mirror of
https://github.com/reanimate/reanimate.git
synced 2026-09-10 23:52:22 +00:00
Improve povray examples.
Former-commit-id: b1101fe5b3a7b9bec0b6b92f303d42be8114d128
This commit is contained in:
parent
e87e69c5b9
commit
8333d3d4f1
6 changed files with 370 additions and 39 deletions
|
|
@ -241,3 +241,18 @@ This file is auto-generated by docs/render_all.sh. DO NOT EDIT.
|
||||||
|
|
||||||
<br/><hr><br/>
|
<br/><hr><br/>
|
||||||
|
|
||||||
|
## tut_glue_povray
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>View tut_glue_povray.hs</summary>
|
||||||
|
<pre><code class="haskell">
|
||||||
|
{!examples/tut_glue_povray.hs!}
|
||||||
|
</code></pre>
|
||||||
|
</details>
|
||||||
|
<br/>
|
||||||
|
<video width="640" height="360" autoplay loop>
|
||||||
|
<source src="https://github.com/Lemmih/reanimate/raw/master/docs/rendered/tut_glue_povray.mp4">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
<br/><hr><br/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ ROOT=`stack path --project-root`
|
||||||
EXAMPLES='boundingbox colormaps goo latex_basic latex_color latex_draw
|
EXAMPLES='boundingbox colormaps goo latex_basic latex_color latex_draw
|
||||||
latex_wheel raster sphere blender_default_cube
|
latex_wheel raster sphere blender_default_cube
|
||||||
tut_glue_svg tut_glue_animate tut_glue_keyframe tut_glue_fourier
|
tut_glue_svg tut_glue_animate tut_glue_keyframe tut_glue_fourier
|
||||||
tut_glue_physics tut_glue_latex'
|
tut_glue_physics tut_glue_latex tut_glue_povray
|
||||||
|
tut_glue_povray_ortho'
|
||||||
|
|
||||||
WIDTH=640
|
WIDTH=640
|
||||||
HEIGHT=$((WIDTH*9/16))
|
HEIGHT=$((WIDTH*9/16))
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ The following examples shows how something as seemingly complicated as fourier s
|
||||||
<source src="https://github.com/Lemmih/reanimate/raw/master/docs/rendered/tut_glue_fourier.mp4">
|
<source src="https://github.com/Lemmih/reanimate/raw/master/docs/rendered/tut_glue_fourier.mp4">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
Scripting in Haskell also gives access to the extensive body of code libraries. There are Haskell libraries for syntax highlighting, font manipulation, and much, much more. In the spirit of being a batteries-included framework, Reanimate ships with a built-in 2D physics library, called Chipmunk2D. The example below demonstrates how SVG shapes can be generated with LaTeX and then nearly effortlessly used in a physics simulation.
|
Scripting in Haskell also gives access to the extensive body of code libraries. There are Haskell libraries for syntax highlighting, font manipulation, and much, much more. In the spirit of being a batteries-included framework, Reanimate ships with a built-in 2D physics library, called Chipmunk2D. The example below demonstrates how SVG shapes can be used nearly effortlessly in a physics simulation.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Toggle source code.</summary>
|
<summary>Toggle source code.</summary>
|
||||||
|
|
@ -120,7 +120,34 @@ The resulting SVGs can be manipulated just like any other. The below examples il
|
||||||
|
|
||||||
## Pillar III: povray
|
## Pillar III: povray
|
||||||
|
|
||||||
TODO: Draw text and animate shapes, zoom out so it looks like a piece of paper (still animated), draw circle, fade in rotating sphere.
|
TODO: Draw text and animate shapes, zoom out so it looks like a piece of paper (still animated).
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Toggle source code.</summary>
|
||||||
|
<pre><code class="haskell">
|
||||||
|
{!examples/tut_glue_povray.hs!}
|
||||||
|
</code></pre>
|
||||||
|
</details>
|
||||||
|
<br/>
|
||||||
|
<video width="640" height="360" autoplay loop>
|
||||||
|
<source src="../rendered/tut_glue_povray.mp4">
|
||||||
|
<source src="https://github.com/Lemmih/reanimate/raw/master/docs/rendered/tut_glue_povray.mp4">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
TODO: Talk about orthographic projection. Draw circle, fade in rotating sphere.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Toggle source code.</summary>
|
||||||
|
<pre><code class="haskell">
|
||||||
|
{!examples/tut_glue_povray_ortho.hs!}
|
||||||
|
</code></pre>
|
||||||
|
</details>
|
||||||
|
<br/>
|
||||||
|
<video width="640" height="360" autoplay loop>
|
||||||
|
<source src="../rendered/tut_glue_povray_ortho.mp4">
|
||||||
|
<source src="https://github.com/Lemmih/reanimate/raw/master/docs/rendered/tut_glue_povray_ortho.mp4">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
|
||||||
## Pillar IV: Blender
|
## Pillar IV: Blender
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,12 @@ import System.Random
|
||||||
import System.Random.Shuffle
|
import System.Random.Shuffle
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = reanimate $ parA bg $ sceneAnimation $ do
|
main = reanimate $ parA bg latexExample
|
||||||
|
where
|
||||||
|
bg = animate $ const $ mkBackgroundPixel (PixelRGBA8 252 252 252 0xFF)
|
||||||
|
|
||||||
|
latexExample :: Animation
|
||||||
|
latexExample = sceneAnimation $ do
|
||||||
-- Draw equation
|
-- Draw equation
|
||||||
play $ drawAnimation strokedSvg
|
play $ drawAnimation strokedSvg
|
||||||
sprites <- forM glyphs $ \(fn, _, elt) ->
|
sprites <- forM glyphs $ \(fn, _, elt) ->
|
||||||
|
|
@ -41,7 +46,6 @@ main = reanimate $ parA bg $ sceneAnimation $ do
|
||||||
withStrokeColor "black" svg
|
withStrokeColor "black" svg
|
||||||
svg = lowerTransformations $ simplify $ scale 2 $ center $
|
svg = lowerTransformations $ simplify $ scale 2 $ center $
|
||||||
latexAlign "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
latexAlign "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
||||||
bg = animate $ const $ mkBackgroundPixel (PixelRGBA8 252 252 252 0xFF)
|
|
||||||
shuffleList lst = shuffle' lst (length lst) (mkStdGen 0xdeadbeef)
|
shuffleList lst = shuffle' lst (length lst) (mkStdGen 0xdeadbeef)
|
||||||
|
|
||||||
highlightE :: Effect
|
highlightE :: Effect
|
||||||
|
|
|
||||||
|
|
@ -5,80 +5,83 @@
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
import Reanimate
|
import Reanimate
|
||||||
|
import Reanimate.Scene
|
||||||
|
import Reanimate.Animation
|
||||||
import Reanimate.Povray
|
import Reanimate.Povray
|
||||||
import Reanimate.Raster
|
import Reanimate.Raster
|
||||||
|
import Reanimate.Effect
|
||||||
import Data.String.Here
|
import Data.String.Here
|
||||||
|
import Graphics.SvgTree hiding (Text)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import Codec.Picture
|
||||||
|
import System.Random
|
||||||
|
import System.Random.Shuffle
|
||||||
|
import Control.Lens ((^.))
|
||||||
|
import Data.Monoid
|
||||||
|
import Control.Monad
|
||||||
|
import Codec.Picture.Types
|
||||||
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = reanimate $ mkAnimation 10 $ \t ->
|
main = reanimate $ parA bg $ sceneAnimation $ do
|
||||||
let s = fromToS 0 4 t in
|
zPos <- newVar 0
|
||||||
let rot = fromToS 0 (360) t in
|
xRot <- newVar 0
|
||||||
mkGroup
|
zRot <- newVar 0
|
||||||
[ mkBackground "black"
|
s <- newSprite $ do
|
||||||
, povraySlow [] (script (svgAsPngFile (texture $ oscillateS t)) s rot)
|
transZ <- freezeVar zPos
|
||||||
-- , texture $ oscillateS t
|
getX <- freezeVar xRot
|
||||||
]
|
getZ <- freezeVar zRot
|
||||||
|
return $ \real_t dur t ->
|
||||||
|
povraySlow [] $
|
||||||
|
script (svgAsPngFile (texture (t/dur))) (transZ real_t) (getX real_t) (getZ real_t)
|
||||||
|
wait 2
|
||||||
|
tweenVar zPos 9 (\t v -> fromToS v 8 (t/9))
|
||||||
|
tweenVar xRot 9 (\t v -> fromToS v 360 $ curveS 2 (t/9))
|
||||||
|
tweenVar zRot 9 (\t v -> fromToS v 360 $ curveS 2 (t/9))
|
||||||
|
wait 10
|
||||||
|
tweenVar zPos 2 (\t v -> fromToS v 0 $ curveS 3 (t/2))
|
||||||
|
wait 2
|
||||||
where
|
where
|
||||||
|
bg = animate $ const $ mkBackgroundPixel $ PixelRGBA8 252 252 252 0xFF
|
||||||
|
|
||||||
texture :: Double -> SVG
|
texture :: Double -> SVG
|
||||||
texture t = mkGroup
|
texture t = mkGroup
|
||||||
[ checker 10 10
|
[ checker 10 10
|
||||||
, translate (screenWidth/2) 0 $
|
, frameAt (t*duration latexExample) latexExample ]
|
||||||
translate (-screenWidth*t) 0 $
|
|
||||||
withFillColor "red" $ mkCircle 3 ]
|
|
||||||
|
|
||||||
script :: FilePath -> Double -> Double -> Text
|
script :: FilePath -> Double -> Double -> Double -> Text
|
||||||
script png s rot = [iTrim|
|
script png transZ rotX rotZ = [iTrim|
|
||||||
//EXAMPLE OF SPHERE
|
|
||||||
|
|
||||||
//Files with predefined colors and textures
|
|
||||||
#include "colors.inc"
|
#include "colors.inc"
|
||||||
#include "glass.inc"
|
|
||||||
#include "golds.inc"
|
|
||||||
#include "metals.inc"
|
|
||||||
#include "stones.inc"
|
|
||||||
#include "woods.inc"
|
|
||||||
|
|
||||||
#include "shapes3.inc"
|
|
||||||
|
|
||||||
//Place the camera
|
//Place the camera
|
||||||
camera {
|
camera {
|
||||||
perspective
|
perspective
|
||||||
//location <0,0,-9-${s*2}>
|
|
||||||
location <0,0,-9>
|
location <0,0,-9>
|
||||||
look_at <0,0,0>
|
look_at <0,0,0>
|
||||||
up y
|
up y
|
||||||
right x*16/9
|
right x*16/9
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Ambient light to "brighten up" darker pictures
|
//Ambient light to "brighten up" darker pictures
|
||||||
global_settings { ambient_light White*3 }
|
global_settings { ambient_light White*3 }
|
||||||
|
|
||||||
//Set a background color
|
//Set a background color
|
||||||
//background { color White }
|
|
||||||
//background { color rgbt <0.1, 0, 0, 0> } // red
|
|
||||||
background { color rgbt <0, 0, 0, 1> } // transparent
|
background { color rgbt <0, 0, 0, 1> } // transparent
|
||||||
|
|
||||||
polygon {
|
polygon {
|
||||||
4,
|
4,
|
||||||
//<-9, -4.5>, <-9, 4.5>, <9, 4.5>, <9, -4.5>
|
|
||||||
<0, 0>, <0, 1>, <1, 1>, <1, 0>
|
<0, 0>, <0, 1>, <1, 1>, <1, 0>
|
||||||
texture {
|
texture {
|
||||||
//pigment{ color rgb <0,1,0> }
|
|
||||||
pigment{
|
pigment{
|
||||||
image_map{ png ${png} }
|
image_map{ png ${png} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
translate <-1/2,-1/2>
|
translate <-1/2,-1/2>
|
||||||
scale <16,9>
|
scale <16,9>
|
||||||
rotate <0,${rot},${rot}>
|
rotate <0,${rotX},${rotZ}>
|
||||||
translate <0,0,${s*2}>
|
translate <0,0,${transZ}>
|
||||||
}
|
}
|
||||||
|
|]
|
||||||
|]
|
|
||||||
|
|
||||||
checker :: Int -> Int -> SVG
|
checker :: Int -> Int -> SVG
|
||||||
checker w h =
|
checker w h =
|
||||||
|
|
@ -105,3 +108,81 @@ checker w h =
|
||||||
stepY = screenHeight/fromIntegral h
|
stepY = screenHeight/fromIntegral h
|
||||||
offsetX = screenWidth/2
|
offsetX = screenWidth/2
|
||||||
offsetY = screenHeight/2
|
offsetY = screenHeight/2
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
-- COPIED FROM tut_glue_latex.hs --
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
latexExample :: Animation
|
||||||
|
latexExample = sceneAnimation $ do
|
||||||
|
-- Draw equation
|
||||||
|
play $ drawAnimation strokedSvg
|
||||||
|
sprites <- forM glyphs $ \(fn, _, elt) ->
|
||||||
|
newSpriteA $ animate $ const $ fn elt
|
||||||
|
-- Yoink each glyph
|
||||||
|
forM_ (reverse sprites) $ \sprite -> do
|
||||||
|
spriteE sprite (overBeginning 1 $ aroundCenterE $ highlightE)
|
||||||
|
wait 0.5
|
||||||
|
-- Flash glyphs randomly with color
|
||||||
|
forM_ (shuffleList (sprites++sprites)) $ \sprite -> do
|
||||||
|
spriteE sprite (overBeginning 0.5 $ aroundCenterE $ flashE)
|
||||||
|
wait 0.1
|
||||||
|
wait 0.5
|
||||||
|
mapM_ destroySprite sprites
|
||||||
|
-- Undraw equations
|
||||||
|
play $ drawAnimation' (Just 0xdeadbeef) 1 0.1 strokedSvg
|
||||||
|
# reverseA
|
||||||
|
where
|
||||||
|
glyphs = svgGlyphs svg
|
||||||
|
strokedSvg =
|
||||||
|
withStrokeWidth (defaultStrokeWidth*0.5) $
|
||||||
|
withStrokeColor "black" svg
|
||||||
|
svg = lowerTransformations $ simplify $ scale 2 $ center $
|
||||||
|
latexAlign "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
||||||
|
shuffleList lst = shuffle' lst (length lst) (mkStdGen 0xdeadbeef)
|
||||||
|
|
||||||
|
highlightE :: Effect
|
||||||
|
highlightE d t =
|
||||||
|
scale (1 + bellS 2 (t/d)*0.5) . rotate (wiggleS (t/d) * 20)
|
||||||
|
|
||||||
|
flashE :: Effect
|
||||||
|
flashE d t =
|
||||||
|
withStrokeColor "black" .
|
||||||
|
withStrokeWidth (defaultStrokeWidth*0.5*bellS 2 (t/d)) .
|
||||||
|
withFillColorPixel (promotePixel $ turbo (t/d))
|
||||||
|
|
||||||
|
-- s-curve, sin, s-curve
|
||||||
|
wiggleS :: Signal
|
||||||
|
wiggleS t
|
||||||
|
| t < 0.25 = curveS 2 (t*4)
|
||||||
|
| t < 0.75 = sin ((t-0.25)*2*pi+pi/2)
|
||||||
|
| otherwise = curveS 2 ((t-0.75)*4)-1
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
drawAnimation :: SVG -> Animation
|
||||||
|
drawAnimation = drawAnimation' Nothing 0.5 0.3
|
||||||
|
|
||||||
|
drawAnimation' :: Maybe Int -> Double -> Double -> SVG -> Animation
|
||||||
|
drawAnimation' mbSeed fillDur step svg = sceneAnimation $ do
|
||||||
|
forM_ (zip [0..] $ shuf $ svgGlyphs svg) $ \(n, (fn, attr, tree)) -> do
|
||||||
|
let sWidth =
|
||||||
|
case toUserUnit defaultDPI <$> getLast (attr ^. strokeWidth) of
|
||||||
|
Just (Num d) -> d
|
||||||
|
_ -> defaultStrokeWidth
|
||||||
|
fork $ do
|
||||||
|
wait (n*step)
|
||||||
|
play $ mapA fn $ (animate (\t -> withFillOpacity 0 $ partialSvg t tree)
|
||||||
|
# applyE (overEnding fillDur $ fadeLineOutE sWidth))
|
||||||
|
fork $ do
|
||||||
|
wait (n*step+(1-fillDur))
|
||||||
|
newSprite $ do
|
||||||
|
return $ \_real_t _d t ->
|
||||||
|
withStrokeWidth 0 $ fn $ withFillOpacity (min 1 $ t/fillDur) tree
|
||||||
|
where
|
||||||
|
shuf lst =
|
||||||
|
case mbSeed of
|
||||||
|
Nothing -> lst
|
||||||
|
Just seed -> shuffle' lst (length lst) (mkStdGen seed)
|
||||||
|
|
|
||||||
203
examples/tut_glue_povray_ortho.hs
Executable file
203
examples/tut_glue_povray_ortho.hs
Executable file
|
|
@ -0,0 +1,203 @@
|
||||||
|
#!/usr/bin/env stack
|
||||||
|
-- stack runghc --package reanimate
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
import Reanimate
|
||||||
|
import Reanimate.Scene
|
||||||
|
import Reanimate.Animation
|
||||||
|
import Reanimate.Povray
|
||||||
|
import Reanimate.Raster
|
||||||
|
import Data.String.Here
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Codec.Picture
|
||||||
|
import Reanimate.Effect
|
||||||
|
import Reanimate.Scene
|
||||||
|
import System.Random
|
||||||
|
import System.Random.Shuffle
|
||||||
|
import Graphics.SvgTree hiding (Text)
|
||||||
|
import Control.Lens ((^.))
|
||||||
|
import Control.Monad
|
||||||
|
import Codec.Picture.Types
|
||||||
|
import Data.Monoid
|
||||||
|
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = reanimate $ parA bg $ sceneAnimation $ do
|
||||||
|
xRot <- newVar (-30)
|
||||||
|
yRot <- newVar 180
|
||||||
|
zRot <- newVar 0
|
||||||
|
s <- newSprite $ do
|
||||||
|
getX <- freezeVar xRot
|
||||||
|
getY <- freezeVar yRot
|
||||||
|
getZ <- freezeVar zRot
|
||||||
|
return $ \real_t dur t ->
|
||||||
|
povraySlow [] $
|
||||||
|
script (svgAsPngFile (texture (t/dur))) (getX real_t) (getY real_t) (getZ real_t)
|
||||||
|
wait 2
|
||||||
|
let tDuration = 20
|
||||||
|
tweenVar yRot tDuration (\t v -> fromToS v (v+180) $ curveS 2 (t/tDuration))
|
||||||
|
tweenVar xRot (tDuration/2) (\t v -> fromToS v (v+60) $ curveS 2 (t/(tDuration/2)))
|
||||||
|
fork $ do
|
||||||
|
wait (tDuration/2)
|
||||||
|
tweenVar xRot (tDuration/2) (\t v -> fromToS v (v-60) $ curveS 2 (t/(tDuration/2)))
|
||||||
|
--tweenVar zRot 9 (\t v -> fromToS v 360 $ curveS 2 (t/9))
|
||||||
|
wait tDuration
|
||||||
|
wait 2
|
||||||
|
--tweenVar zPos 2 (\t v -> fromToS v 0 $ curveS 3 (t/2))
|
||||||
|
--wait 2
|
||||||
|
where
|
||||||
|
bg = animate $ const $ mkBackgroundPixel $ PixelRGBA8 252 252 252 0xFF
|
||||||
|
|
||||||
|
texture :: Double -> SVG
|
||||||
|
texture t = mkGroup
|
||||||
|
[ checker 10 10
|
||||||
|
, frameAt (t*duration latexExample) latexExample
|
||||||
|
]
|
||||||
|
|
||||||
|
script :: FilePath -> Double -> Double -> Double -> Text
|
||||||
|
script png rotX rotY rotZ = [iTrim|
|
||||||
|
//Files with predefined colors and textures
|
||||||
|
#include "colors.inc"
|
||||||
|
|
||||||
|
#include "shapes3.inc"
|
||||||
|
|
||||||
|
//Place the camera
|
||||||
|
camera {
|
||||||
|
orthographic
|
||||||
|
location <0,0,-10>
|
||||||
|
look_at <0,0,0>
|
||||||
|
up <0,9,0>
|
||||||
|
right <16,0,0>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Ambient light to "brighten up" darker pictures
|
||||||
|
global_settings { ambient_light White*3 }
|
||||||
|
|
||||||
|
//Set a background color
|
||||||
|
//background { color White }
|
||||||
|
//background { color rgbt <0.1, 0, 0, 0> } // red
|
||||||
|
background { color rgbt <0, 0, 0, 1> } // transparent
|
||||||
|
|
||||||
|
//Sphere with specified center point and radius
|
||||||
|
sphere {
|
||||||
|
<0,0,0>, 4
|
||||||
|
texture {
|
||||||
|
uv_mapping pigment{
|
||||||
|
image_map{ png ${png} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rotate <0,${rotY},${rotZ}>
|
||||||
|
rotate <${rotX},0,0>
|
||||||
|
}
|
||||||
|
|
||||||
|
|]
|
||||||
|
|
||||||
|
checker :: Int -> Int -> SVG
|
||||||
|
checker w h =
|
||||||
|
withFillColor "white" $
|
||||||
|
withStrokeColor "white" $
|
||||||
|
withStrokeWidth 0.1 $
|
||||||
|
mkGroup
|
||||||
|
[ withStrokeWidth 0 $
|
||||||
|
withFillOpacity 0.7 $ mkBackground "blue"
|
||||||
|
, mkGroup
|
||||||
|
[ translate (stepX*x-offsetX + stepX/2) 0 $
|
||||||
|
mkLine (0, -screenHeight/2*0.9) (0, screenHeight/2*0.9)
|
||||||
|
| x <- map fromIntegral [0..w-1]
|
||||||
|
]
|
||||||
|
,
|
||||||
|
mkGroup
|
||||||
|
[ translate 0 (stepY*y-offsetY) $
|
||||||
|
mkLine (-screenWidth/2, 0) (screenWidth/2, 0)
|
||||||
|
| y <- map fromIntegral [0..h]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
where
|
||||||
|
stepX = screenWidth/fromIntegral w
|
||||||
|
stepY = screenHeight/fromIntegral h
|
||||||
|
offsetX = screenWidth/2
|
||||||
|
offsetY = screenHeight/2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
-- COPIED FROM tut_glue_latex.hs --
|
||||||
|
|
||||||
|
|
||||||
|
latexExample :: Animation
|
||||||
|
latexExample = sceneAnimation $ do
|
||||||
|
-- Draw equation
|
||||||
|
play $ drawAnimation strokedSvg
|
||||||
|
sprites <- forM glyphs $ \(fn, _, elt) ->
|
||||||
|
newSpriteA $ animate $ const $ fn elt
|
||||||
|
-- Yoink each glyph
|
||||||
|
forM_ (reverse sprites) $ \sprite -> do
|
||||||
|
spriteE sprite (overBeginning 1 $ aroundCenterE $ highlightE)
|
||||||
|
wait 0.5
|
||||||
|
-- Flash glyphs randomly with color
|
||||||
|
forM_ (shuffleList (sprites++sprites)) $ \sprite -> do
|
||||||
|
spriteE sprite (overBeginning 0.5 $ aroundCenterE $ flashE)
|
||||||
|
wait 0.1
|
||||||
|
wait 0.5
|
||||||
|
mapM_ destroySprite sprites
|
||||||
|
-- Undraw equations
|
||||||
|
play $ drawAnimation' (Just 0xdeadbeef) 1 0.1 strokedSvg
|
||||||
|
# reverseA
|
||||||
|
where
|
||||||
|
glyphs = svgGlyphs svg
|
||||||
|
strokedSvg =
|
||||||
|
withStrokeWidth (defaultStrokeWidth*0.5) $
|
||||||
|
withStrokeColor "black" svg
|
||||||
|
svg = lowerTransformations $ simplify $ scale 2 $ center $
|
||||||
|
latexAlign "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
||||||
|
bg = animate $ const $ mkBackgroundPixel (PixelRGBA8 252 252 252 0xFF)
|
||||||
|
shuffleList lst = shuffle' lst (length lst) (mkStdGen 0xdeadbeef)
|
||||||
|
|
||||||
|
highlightE :: Effect
|
||||||
|
highlightE d t =
|
||||||
|
scale (1 + bellS 2 (t/d)*0.5) . rotate (wiggleS (t/d) * 20)
|
||||||
|
|
||||||
|
flashE :: Effect
|
||||||
|
flashE d t =
|
||||||
|
withStrokeColor "black" .
|
||||||
|
withStrokeWidth (defaultStrokeWidth*0.5*bellS 2 (t/d)) .
|
||||||
|
withFillColorPixel (promotePixel $ turbo (t/d))
|
||||||
|
|
||||||
|
-- s-curve, sin, s-curve
|
||||||
|
wiggleS :: Signal
|
||||||
|
wiggleS t
|
||||||
|
| t < 0.25 = curveS 2 (t*4)
|
||||||
|
| t < 0.75 = sin ((t-0.25)*2*pi+pi/2)
|
||||||
|
| otherwise = curveS 2 ((t-0.75)*4)-1
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
drawAnimation :: SVG -> Animation
|
||||||
|
drawAnimation = drawAnimation' Nothing 0.5 0.3
|
||||||
|
|
||||||
|
drawAnimation' :: Maybe Int -> Double -> Double -> SVG -> Animation
|
||||||
|
drawAnimation' mbSeed fillDur step svg = sceneAnimation $ do
|
||||||
|
forM_ (zip [0..] $ shuf $ svgGlyphs svg) $ \(n, (fn, attr, tree)) -> do
|
||||||
|
let sWidth =
|
||||||
|
case toUserUnit defaultDPI <$> getLast (attr ^. strokeWidth) of
|
||||||
|
Just (Num d) -> d
|
||||||
|
_ -> defaultStrokeWidth
|
||||||
|
fork $ do
|
||||||
|
wait (n*step)
|
||||||
|
play $ mapA fn $ (animate (\t -> withFillOpacity 0 $ partialSvg t tree)
|
||||||
|
# applyE (overEnding fillDur $ fadeLineOutE sWidth))
|
||||||
|
fork $ do
|
||||||
|
wait (n*step+(1-fillDur))
|
||||||
|
newSprite $ do
|
||||||
|
return $ \_real_t _d t ->
|
||||||
|
withStrokeWidth 0 $ fn $ withFillOpacity (min 1 $ t/fillDur) tree
|
||||||
|
where
|
||||||
|
shuf lst =
|
||||||
|
case mbSeed of
|
||||||
|
Nothing -> lst
|
||||||
|
Just seed -> shuffle' lst (length lst) (mkStdGen seed)
|
||||||
|
|
||||||
Loading…
Reference in a new issue