From 6e2d77976670554ba379b0e739fe85a9b36b9552 Mon Sep 17 00:00:00 2001 From: Lemmih Date: Tue, 8 Sep 2020 10:29:05 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=201c7fa?= =?UTF-8?q?10f863c7726b5db0b3721b0f78b92421aeb=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- haddock.txt | 4 +- hpc_badge.json | 2 +- hpc_index.html | 12 +- hpc_index_alt.html | 12 +- hpc_index_exp.html | 14 +- hpc_index_fun.html | 14 +- playground/snippets.js | 2 +- .../Reanimate.Scene.Core.hs.html | 186 ++++++++ .../Reanimate.Scene.Sprite.hs.html | 439 ++++++++++++++++++ .../Reanimate.Scene.Var.hs.html | 193 ++++++++ 10 files changed, 860 insertions(+), 18 deletions(-) create mode 100644 reanimate-0.4.3.0-inplace/Reanimate.Scene.Core.hs.html create mode 100644 reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite.hs.html create mode 100644 reanimate-0.4.3.0-inplace/Reanimate.Scene.Var.hs.html diff --git a/haddock.txt b/haddock.txt index d57c03f..a893429 100644 --- a/haddock.txt +++ b/haddock.txt @@ -1,4 +1,4 @@ - 100% (155 /155) in 'Reanimate' + 100% (154 /154) in 'Reanimate' 100% ( 55 / 55) in 'Reanimate.Svg.Constructors' 100% ( 41 / 41) in 'Reanimate.Animation' 100% ( 40 / 40) in 'Reanimate.GeoProjection' @@ -36,4 +36,4 @@ 100% ( 3 / 3) in 'Reanimate.Math.Balloon' 100% ( 3 / 3) in 'Reanimate.Blender' 100% ( 2 / 2) in 'Reanimate.Builtin.CirclePlot' - 90% (113 /126) in 'Reanimate.Scene' + 89% (111 /125) in 'Reanimate.Scene' diff --git a/hpc_badge.json b/hpc_badge.json index 2b5e58c..57494ef 100644 --- a/hpc_badge.json +++ b/hpc_badge.json @@ -1 +1 @@ - { "schemaVersion": 1, "label": "api tests", "message": "30%", "color": "success" } + { "schemaVersion": 1, "label": "api tests", "message": "35%", "color": "success" } diff --git a/hpc_index.html b/hpc_index.html index 1594cf1..17a5de6 100644 --- a/hpc_index.html +++ b/hpc_index.html @@ -100,8 +100,14 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Render 5%1/19
0%0/53
4%39/852
-  module reanimate-0.4.3.0-inplace/Reanimate.Scene -27%40/146
55%15/27
31%543/1700
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Core +63%12/19
- 0/0 72%172/237
+ +  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite +85%23/27
57%11/19
78%314/400
+ +  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Var +89%17/19
60%14/23
68%220/319
  module reanimate-0.4.3.0-inplace/Reanimate.Svg 38%5/13
18%15/80
41%323/777
@@ -125,5 +131,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black } 100%6/6
50%1/2
95%43/45
  Program Coverage Total -30%249/820
16%134/829
29%4680/15725
+35%261/739
17%144/844
32%4843/14981
diff --git a/hpc_index_alt.html b/hpc_index_alt.html index 6ab2658..e678a18 100644 --- a/hpc_index_alt.html +++ b/hpc_index_alt.html @@ -16,14 +16,17 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.ColorMap 100%14/14
60%3/5
99%1176/1180
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Var +89%17/19
60%14/23
68%220/319
+   module reanimate-0.4.3.0-inplace/Reanimate.Svg.LineCommand 80%12/15
58%43/74
70%659/937
  module reanimate-0.4.3.0-inplace/Reanimate.Animation 90%28/31
57%8/14
87%298/341
-  module reanimate-0.4.3.0-inplace/Reanimate.Scene -27%40/146
55%15/27
31%543/1700
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite +85%23/27
57%11/19
78%314/400
  module reanimate-0.4.3.0-inplace/Reanimate.ColorComponents 75%9/12
50%1/2
81%135/166
@@ -123,7 +126,10 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Parameters 15%3/20
- 0/0 14%7/49
+ +  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Core +63%12/19
- 0/0 72%172/237
  Program Coverage Total -30%249/820
16%134/829
29%4680/15725
+35%261/739
17%144/844
32%4843/14981
diff --git a/hpc_index_exp.html b/hpc_index_exp.html index 15dbe24..0d136d3 100644 --- a/hpc_index_exp.html +++ b/hpc_index_exp.html @@ -28,9 +28,18 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.ColorComponents 75%9/12
50%1/2
81%135/166
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite +85%23/27
57%11/19
78%314/400
+ +  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Core +63%12/19
- 0/0 72%172/237
+   module reanimate-0.4.3.0-inplace/Reanimate.Svg.LineCommand 80%12/15
58%43/74
70%659/937
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Var +89%17/19
60%14/23
68%220/319
+   module reanimate-0.4.3.0-inplace/Reanimate.Svg.Constructors 67%33/49
37%3/8
65%368/563
@@ -49,9 +58,6 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Svg 38%5/13
18%15/80
41%323/777
-  module reanimate-0.4.3.0-inplace/Reanimate.Scene -27%40/146
55%15/27
31%543/1700
-   module reanimate-0.4.3.0-inplace/Geom2D.CubicBezier.Linear 19%20/101
5%2/36
27%97/347
@@ -125,5 +131,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black } 0%0/1
0%0/4
0%0/61
  Program Coverage Total -30%249/820
16%134/829
29%4680/15725
+35%261/739
17%144/844
32%4843/14981
diff --git a/hpc_index_fun.html b/hpc_index_fun.html index 9fc1f98..6cbab36 100644 --- a/hpc_index_fun.html +++ b/hpc_index_fun.html @@ -22,9 +22,15 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Animation 90%28/31
57%8/14
87%298/341
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Var +89%17/19
60%14/23
68%220/319
+   module reanimate-0.4.3.0-inplace/Reanimate.Ease 87%7/8
100%4/4
96%85/88
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite +85%23/27
57%11/19
78%314/400
+   module reanimate-0.4.3.0-inplace/Reanimate.Transform 83%5/6
33%4/12
45%76/166
@@ -37,6 +43,9 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Svg.Constructors 67%33/49
37%3/8
65%368/563
+  module reanimate-0.4.3.0-inplace/Reanimate.Scene.Core +63%12/19
- 0/0 72%172/237
+   module reanimate-0.4.3.0-inplace/Reanimate.Builtin.Images 57%4/7
25%1/4
48%24/49
@@ -64,9 +73,6 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black }   module reanimate-0.4.3.0-inplace/Reanimate.Svg.Unuse 33%1/3
0%0/14
22%28/127
-  module reanimate-0.4.3.0-inplace/Reanimate.Scene -27%40/146
55%15/27
31%543/1700
-   module reanimate-0.4.3.0-inplace/Reanimate.PolyShape 22%8/35
27%13/48
18%127/691
@@ -125,5 +131,5 @@ table.dashboard { border-collapse: collapse ; border: solid 1px black } 0%0/1
0%0/4
0%0/61
  Program Coverage Total -30%249/820
16%134/829
29%4680/15725
+35%261/739
17%144/844
32%4843/14981
diff --git a/playground/snippets.js b/playground/snippets.js index 26d1b89..7cdf8e6 100644 --- a/playground/snippets.js +++ b/playground/snippets.js @@ -9,4 +9,4 @@ const snippets = [{"title": "Hello World","url": "https://reanimate.clozecards.c ,{"title": "Object Positions","url": "https://reanimate.clozecards.com/Mf4zcImo+I7/195.svg","code": "env =\n addStatic (mkBackground \"white\") .\n mapA (withStrokeColor \"black\")\n\nanimation :: Animation\nanimation = env $\n sceneAnimation $ do\n -- Configure objects\n txt <- newText \"Center\"\n top <- newText \"Top\"\n oModifyS top $ \n oTopY .= screenTop\n topR <- newText \"Top right\"\n oModifyS topR $ do\n oTopY .= screenTop\n oRightX .= screenRight\n botR <- newText \"Bottom right\"\n oModifyS botR $ do\n oTranslate .= (0, screenBottom+0.5)\n oRightX .= screenRight\n botL <- newText \"Bottom left\"\n oModifyS botL $ do\n oTranslate .= (0, screenBottom+0.5)\n oLeftX .= screenLeft\n topL <- newText \"Top left\"\n oModifyS topL $ do\n oTopY .= screenTop\n oLeftX .= screenLeft\n -- Show objects\n oShow txt\n wait 1\n switchTo txt top\n switchTo top topR\n switchTo topR botR\n switchTo botR botL\n switchTo botL topL\n switchTo topL txt\n\nswitchTo src dst = do\n fork $ oHideWith src oFadeOut\n oShowWith dst oFadeIn\n wait 1\n\nnewText txt =\n newObject $ scale 1.5 $ centerX $ latex txt\n"} ,{"title": "Camera","url": "https://reanimate.clozecards.com/Hcx00P+aeph/150.svg","code": "animation :: Animation\nanimation = docEnv $ mapA (withFillOpacity 1) $ sceneAnimation $ do\n cam <- newObject Camera\n\n txt <- newObject $ center $ latex \"Fixed (non-cam)\"\n oModifyS txt $ do\n oTopY .= screenTop \n oZIndex .= 2\n\n circle <- newObject $ withFillColor \"blue\" $ mkCircle 1\n cameraAttach cam circle\n circleRight <- oRead circle oRightX\n\n box <- newObject $ withFillColor \"green\" $ mkRect 2 2\n cameraAttach cam box\n oModify box $ oLeftX .~ circleRight\n boxCenter <- oRead box oCenterXY\n\n small <- newObject $ center $ latex \"This text is very small\"\n cameraAttach cam small\n oModifyS small $ do\n oCenterXY .= boxCenter\n oScale .= 0.1\n \n oShow txt\n oShow small\n oShow circle\n oShow box\n\n wait 1\n\n cameraFocus cam boxCenter\n waitOn $ do\n fork $ cameraPan cam 3 boxCenter\n fork $ cameraZoom cam 3 15\n \n wait 2\n cameraZoom cam 3 1\n cameraPan cam 1 (0,0)\n"} ]; -const playgroundVersion = "2020-09-08 (f2070)"; +const playgroundVersion = "2020-09-08 (1c7fa)"; diff --git a/reanimate-0.4.3.0-inplace/Reanimate.Scene.Core.hs.html b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Core.hs.html new file mode 100644 index 0000000..aa5adac --- /dev/null +++ b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Core.hs.html @@ -0,0 +1,186 @@ + + + + + + +
+never executed always true always false
+
+
+    1 {-# LANGUAGE RankNTypes #-}
+    2 
+    3 module Reanimate.Scene.Core where
+    4 
+    5 import Control.Monad.Fix (MonadFix (..))
+    6 import Control.Monad.ST
+    7 import Data.List
+    8 import Reanimate.Animation
+    9 import Reanimate.Svg.Constructors
+   10 
+   11 -- | The ZIndex property specifies the stack order of sprites and animations. Elements
+   12 --   with a higher ZIndex will be drawn on top of elements with a lower index.
+   13 type ZIndex = Int
+   14 
+   15 -- (seq duration, par duration)
+   16 -- [(Time, Animation, ZIndex)]
+   17 -- Map Time [(Animation, ZIndex)]
+   18 type Gen s = ST s (Duration -> Time -> (SVG, ZIndex))
+   19 
+   20 -- | A 'Scene' represents a sequence of animations and variables
+   21 --   that change over time.
+   22 newtype Scene s a = M {unM :: Time -> ST s (a, Duration, Duration, [Gen s])}
+   23 
+   24 instance Functor (Scene s) where
+   25   fmap f action = M $ \t -> do
+   26     (a, d1, d2, gens) <- unM action t
+   27     return (f a, d1, d2, gens)
+   28 
+   29 instance Applicative (Scene s) where
+   30   pure a = M $ \_ -> return (a, 0, 0, [])
+   31   f <*> g = M $ \t -> do
+   32     (f', s1, p1, gen1) <- unM f t
+   33     (g', s2, p2, gen2) <- unM g (t + s1)
+   34     return (f' g', s1 + s2, max p1 (s1 + p2), gen1 ++ gen2)
+   35 
+   36 instance Monad (Scene s) where
+   37   return = pure
+   38   f >>= g = M $ \t -> do
+   39     (a, s1, p1, gen1) <- unM f t
+   40     (b, s2, p2, gen2) <- unM (g a) (t + s1)
+   41     return (b, s1 + s2, max p1 (s1 + p2), gen1 ++ gen2)
+   42 
+   43 instance MonadFix (Scene s) where
+   44   mfix fn = M $ \t -> mfix (\v -> let (a, _s, _p, _gens) = v in unM (fn a) t)
+   45 
+   46 liftST :: ST s a -> Scene s a
+   47 liftST action = M $ \_ -> action >>= \a -> return (a, 0, 0, [])
+   48 
+   49 -- | Evaluate the value of a scene.
+   50 evalScene :: (forall s. Scene s a) -> a
+   51 evalScene action = runST $ do
+   52   (val, _, _, _) <- unM action 0
+   53   return val
+   54 
+   55 -- | Render a 'Scene' to an 'Animation'.
+   56 scene :: (forall s. Scene s a) -> Animation
+   57 scene = sceneAnimation
+   58 
+   59 -- | Render a 'Scene' to an 'Animation'.
+   60 sceneAnimation :: (forall s. Scene s a) -> Animation
+   61 sceneAnimation action =
+   62   runST
+   63     ( do
+   64         (_, s, p, gens) <- unM action 0
+   65         let dur = max s p
+   66         genFns <- sequence gens
+   67         return $
+   68           mkAnimation
+   69             dur
+   70             ( \t ->
+   71                 mkGroup $
+   72                   map fst $
+   73                     sortOn
+   74                       snd
+   75                       [spriteRender dur (t * dur) | spriteRender <- genFns]
+   76             )
+   77     )
+   78 
+   79 -- | Execute actions in a scene without advancing the clock. Note that scenes do not end before
+   80 --   all forked actions have completed.
+   81 --
+   82 --   Example:
+   83 --
+   84 -- @
+   85 -- do 'fork' $ 'play' 'Reanimate.Builtin.Documentation.drawBox'
+   86 --    'play' 'Reanimate.Builtin.Documentation.drawCircle'
+   87 -- @
+   88 --
+   89 --   <<docs/gifs/doc_fork.gif>>
+   90 fork :: Scene s a -> Scene s a
+   91 fork (M action) = M $ \t -> do
+   92   (a, s, p, gens) <- action t
+   93   return (a, 0, max s p, gens)
+   94 
+   95 -- | Query the current clock timestamp.
+   96 --
+   97 --   Example:
+   98 --
+   99 -- @
+  100 -- do now \<- 'play' 'Reanimate.Builtin.Documentation.drawCircle' *\> 'queryNow'
+  101 --    'play' $ 'staticFrame' 1 $ 'scale' 2 $ 'withStrokeWidth' 0.05 $
+  102 --      'mkText' $ "Now=" <> T.pack (show now)
+  103 -- @
+  104 --
+  105 --   <<docs/gifs/doc_queryNow.gif>>
+  106 queryNow :: Scene s Time
+  107 queryNow = M $ \t -> return (t, 0, 0, [])
+  108 
+  109 -- | Advance the clock by a given number of seconds.
+  110 --
+  111 --   Example:
+  112 --
+  113 -- @
+  114 -- do 'fork' $ 'play' 'Reanimate.Builtin.Documentation.drawBox'
+  115 --    'wait' 1
+  116 --    'play' 'Reanimate.Builtin.Documentation.drawCircle'
+  117 -- @
+  118 --
+  119 --   <<docs/gifs/doc_wait.gif>>
+  120 wait :: Duration -> Scene s ()
+  121 wait d = M $ \_ -> return ((), d, 0, [])
+  122 
+  123 -- | Wait until the clock is equal to the given timestamp.
+  124 waitUntil :: Time -> Scene s ()
+  125 waitUntil tNew = do
+  126   now <- queryNow
+  127   wait (max 0 (tNew - now))
+  128 
+  129 -- | Wait until all forked and sequential animations have finished.
+  130 --
+  131 --   Example:
+  132 --
+  133 -- @
+  134 -- do 'waitOn' $ 'fork' $ 'play' 'Reanimate.Builtin.Documentation.drawBox'
+  135 --    'play' 'Reanimate.Builtin.Documentation.drawCircle'
+  136 -- @
+  137 --
+  138 --   <<docs/gifs/doc_waitOn.gif>>
+  139 waitOn :: Scene s a -> Scene s a
+  140 waitOn (M action) = M $ \t -> do
+  141   (a, s, p, gens) <- action t
+  142   return (a, max s p, 0, gens)
+  143 
+  144 -- | Change the ZIndex of a scene.
+  145 adjustZ :: (ZIndex -> ZIndex) -> Scene s a -> Scene s a
+  146 adjustZ fn (M action) = M $ \t -> do
+  147   (a, s, p, gens) <- action t
+  148   return (a, s, p, map genFn gens)
+  149   where
+  150     genFn gen = do
+  151       frameGen <- gen
+  152       return $ \d t -> let (svg, z) = frameGen d t in (svg, fn z)
+  153 
+  154 -- | Query the duration of a scene.
+  155 withSceneDuration :: Scene s () -> Scene s Duration
+  156 withSceneDuration s = do
+  157   t1 <- queryNow
+  158   s
+  159   t2 <- queryNow
+  160   return (t2 - t1)
+  161 
+  162 addGen :: Gen s -> Scene s ()
+  163 addGen gen = M $ \_ -> return ((), 0, 0, [gen])
+
+
+ + diff --git a/reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite.hs.html b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite.hs.html new file mode 100644 index 0000000..a064050 --- /dev/null +++ b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Sprite.hs.html @@ -0,0 +1,439 @@ + + + + + + +
+never executed always true always false
+
+
+    1 {-# LANGUAGE ApplicativeDo #-}
+    2 {-# LANGUAGE PatternSynonyms #-}
+    3 {-# LANGUAGE RankNTypes #-}
+    4 
+    5 module Reanimate.Scene.Sprite where
+    6 
+    7 import Control.Monad (void)
+    8 import Control.Monad.ST (ST)
+    9 import Data.Bifunctor (Bifunctor (first))
+   10 import Data.STRef (STRef, modifySTRef, newSTRef, readSTRef)
+   11 import Graphics.SvgTree
+   12   ( pattern None,
+   13   )
+   14 import Reanimate.Animation
+   15   ( Animation,
+   16     Duration,
+   17     SVG,
+   18     Sync (SyncStretch),
+   19     Time,
+   20     dropA,
+   21     duration,
+   22     getAnimationFrame,
+   23   )
+   24 import Reanimate.Effect (Effect, delayE)
+   25 import Reanimate.Scene.Core
+   26   ( Scene (M),
+   27     ZIndex,
+   28     addGen,
+   29     fork,
+   30     liftST,
+   31     queryNow,
+   32     sceneAnimation,
+   33     wait,
+   34   )
+   35 import Reanimate.Scene.Var (unpackVar, Var (..), newVar, readVar)
+   36 import Reanimate.Transition (Transition, overlapT)
+   37 
+   38 -- | Create and render a variable. The rendering will be born at the current timestamp
+   39 --   and will persist until the end of the scene.
+   40 --
+   41 --   Example:
+   42 --
+   43 -- @
+   44 -- do var \<- 'simpleVar' 'mkCircle' 0
+   45 --    'tweenVar' var 2 $ \\val -> 'fromToS' val ('Reanimate.Constants.screenHeight'/2)
+   46 -- @
+   47 --
+   48 --   <<docs/gifs/doc_simpleVar.gif>>
+   49 simpleVar :: (a -> SVG) -> a -> Scene s (Var s a)
+   50 simpleVar render def = do
+   51   v <- newVar def
+   52   _ <- newSprite $ render <$> unVar v
+   53   return v
+   54 
+   55 -- | Helper function for filtering variables.
+   56 findVar :: (a -> Bool) -> [Var s a] -> Scene s (Var s a)
+   57 findVar _cond [] = error "Variable not found."
+   58 findVar cond (v : vs) = do
+   59   val <- readVar v
+   60   if cond val then return v else findVar cond vs
+   61 
+   62 -- | Play an animation once and then remove it. This advances the clock by the duration of the
+   63 --   animation.
+   64 --
+   65 --   Example:
+   66 --
+   67 -- @
+   68 -- do 'play' 'Reanimate.Builtin.Documentation.drawBox'
+   69 --    'play' 'Reanimate.Builtin.Documentation.drawCircle'
+   70 -- @
+   71 --
+   72 --   <<docs/gifs/doc_play.gif>>
+   73 play :: Animation -> Scene s ()
+   74 play ani = newSpriteA ani >>= destroySprite
+   75 
+   76 -- | Sprites are animations with a given time of birth as well as a time of death.
+   77 --   They can be controlled using variables, tweening, and effects.
+   78 data Sprite s = Sprite Time (STRef s (Duration, ST s (Duration -> Time -> SVG -> (SVG, ZIndex))))
+   79 
+   80 -- | Sprite frame generator. Generates frames over time in a stateful environment.
+   81 newtype Frame s a = Frame {unFrame :: ST s (Time -> Duration -> Time -> a)}
+   82 
+   83 instance Functor (Frame s) where
+   84   fmap fn (Frame gen) = Frame $ do
+   85     m <- gen
+   86     return (\real_t d t -> fn $ m real_t d t)
+   87 
+   88 instance Applicative (Frame s) where
+   89   pure v = Frame $ return (\_ _ _ -> v)
+   90   Frame f <*> Frame g = Frame $ do
+   91     m1 <- f
+   92     m2 <- g
+   93     return $ \real_t d t -> m1 real_t d t (m2 real_t d t)
+   94 
+   95 -- | Dereference a variable as a Sprite frame.
+   96 --
+   97 --   Example:
+   98 --
+   99 -- @
+  100 -- do v \<- 'newVar' 0
+  101 --    'newSprite' $ 'mkCircle' \<$\> 'unVar' v
+  102 --    'tweenVar' v 1 $ \\val -> 'fromToS' val 3
+  103 --    'tweenVar' v 1 $ \\val -> 'fromToS' val 0
+  104 -- @
+  105 --
+  106 --   <<docs/gifs/doc_unVar.gif>>
+  107 unVar :: Var s a -> Frame s a
+  108 unVar var = Frame $ do
+  109   fn <- unpackVar var
+  110   return $ \real_t _d _t -> fn real_t
+  111 
+  112 -- | Dereference seconds since sprite birth.
+  113 spriteT :: Frame s Time
+  114 spriteT = Frame $ return (\_real_t _d t -> t)
+  115 
+  116 -- | Dereference duration of the current sprite.
+  117 spriteDuration :: Frame s Duration
+  118 spriteDuration = Frame $ return (\_real_t d _t -> d)
+  119 
+  120 -- | Create new sprite defined by a frame generator. Unless otherwise specified using
+  121 --   'destroySprite', the sprite will die at the end of the scene.
+  122 --
+  123 --   Example:
+  124 --
+  125 -- @
+  126 -- do 'newSprite' $ 'mkCircle' \<$\> 'spriteT' -- Circle sprite where radius=time.
+  127 --    'wait' 2
+  128 -- @
+  129 --
+  130 --   <<docs/gifs/doc_newSprite.gif>>
+  131 newSprite :: Frame s SVG -> Scene s (Sprite s)
+  132 newSprite render = do
+  133   now <- queryNow
+  134   ref <- liftST $ newSTRef (-1, return $ \_d _t svg -> (svg, 0))
+  135   addGen $ do
+  136     fn <- unFrame render
+  137     (spriteDur, spriteEffectGen) <- readSTRef ref
+  138     spriteEffect <- spriteEffectGen
+  139     return $ \d absT ->
+  140       let relD = (if spriteDur < 0 then d else spriteDur) - now
+  141           relT = absT - now
+  142           -- Sprite is live [now;duration[
+  143           -- If we're at the end of a scene, sprites
+  144           -- are live: [now;duration]
+  145           -- This behavior is difficult to get right. See the 'bug_*' examples for
+  146           -- automated tests.
+  147           inTimeSlice = relT >= 0 && relT < relD
+  148           isLastFrame = d == absT && relT == relD
+  149        in if inTimeSlice || isLastFrame
+  150             then spriteEffect relD relT (fn absT relD relT)
+  151             else (None, 0)
+  152   return $ Sprite now ref
+  153 
+  154 -- | Create new sprite defined by a frame generator. The sprite will die at
+  155 --   the end of the scene.
+  156 newSprite_ :: Frame s SVG -> Scene s ()
+  157 newSprite_ = void . newSprite
+  158 
+  159 -- | Create a new sprite from an animation. This advances the clock by the
+  160 --   duration of the animation. Unless otherwise specified using
+  161 --   'destroySprite', the sprite will die at the end of the scene.
+  162 --
+  163 --   Note: If the scene doesn't end immediately after the duration of the
+  164 --   animation, the animation will be stretched to match the lifetime of the
+  165 --   sprite. See 'newSpriteA'' and 'play'.
+  166 --
+  167 --   Example:
+  168 --
+  169 -- @
+  170 -- do 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawCircle'
+  171 --    'play' 'Reanimate.Builtin.Documentation.drawBox'
+  172 --    'play' $ 'reverseA' 'Reanimate.Builtin.Documentation.drawBox'
+  173 -- @
+  174 --
+  175 --   <<docs/gifs/doc_newSpriteA.gif>>
+  176 newSpriteA :: Animation -> Scene s (Sprite s)
+  177 newSpriteA = newSpriteA' SyncStretch
+  178 
+  179 -- | Create a new sprite from an animation and specify the synchronization policy. This advances
+  180 --   the clock by the duration of the animation.
+  181 --
+  182 --   Example:
+  183 --
+  184 -- @
+  185 -- do 'fork' $ 'newSpriteA'' 'SyncFreeze' 'Reanimate.Builtin.Documentation.drawCircle'
+  186 --    'play' 'Reanimate.Builtin.Documentation.drawBox'
+  187 --    'play' $ 'reverseA' 'Reanimate.Builtin.Documentation.drawBox'
+  188 -- @
+  189 --
+  190 --   <<docs/gifs/doc_newSpriteA'.gif>>
+  191 newSpriteA' :: Sync -> Animation -> Scene s (Sprite s)
+  192 newSpriteA' sync animation =
+  193   newSprite (getAnimationFrame sync animation <$> spriteT <*> spriteDuration)
+  194     <* wait (duration animation)
+  195 
+  196 -- | Create a sprite from a static SVG image.
+  197 --
+  198 --   Example:
+  199 --
+  200 -- @
+  201 -- do 'newSpriteSVG' $ 'mkBackground' "lightblue"
+  202 --    'play' 'Reanimate.Builtin.Documentation.drawCircle'
+  203 -- @
+  204 --
+  205 --   <<docs/gifs/doc_newSpriteSVG.gif>>
+  206 newSpriteSVG :: SVG -> Scene s (Sprite s)
+  207 newSpriteSVG = newSprite . pure
+  208 
+  209 -- | Create a permanent sprite from a static SVG image. Same as `newSpriteSVG`
+  210 --   but the sprite isn't returned and thus cannot be destroyed.
+  211 newSpriteSVG_ :: SVG -> Scene s ()
+  212 newSpriteSVG_ = void . newSpriteSVG
+  213 
+  214 -- | Change the rendering of a sprite using data from a variable. If data from several variables
+  215 --   is needed, use a frame generator instead.
+  216 --
+  217 --   Example:
+  218 --
+  219 -- @
+  220 -- do s \<- 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawBox'
+  221 --    v \<- 'newVar' 0
+  222 --    'applyVar' v s 'rotate'
+  223 --    'tweenVar' v 2 $ \\val -> 'fromToS' val 90
+  224 -- @
+  225 --
+  226 --   <<docs/gifs/doc_applyVar.gif>>
+  227 applyVar :: Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()
+  228 applyVar var sprite fn = spriteModify sprite $ do
+  229   varFn <- unVar var
+  230   return $ first $ fn varFn
+  231 
+  232 -- | Destroy a sprite, preventing it from being rendered in the future of the scene.
+  233 --   If 'destroySprite' is invoked multiple times, the earliest time-of-death is used.
+  234 --
+  235 --   Example:
+  236 --
+  237 -- @
+  238 -- do s <- 'newSpriteSVG' $ 'withFillOpacity' 1 $ 'mkCircle' 1
+  239 --    'fork' $ 'wait' 1 \>\> 'destroySprite' s
+  240 --    'play' 'Reanimate.Builtin.Documentation.drawBox'
+  241 -- @
+  242 --
+  243 --   <<docs/gifs/doc_destroySprite.gif>>
+  244 destroySprite :: Sprite s -> Scene s ()
+  245 destroySprite (Sprite _ ref) = do
+  246   now <- queryNow
+  247   liftST $
+  248     modifySTRef ref $ \(ttl, render) ->
+  249       (if ttl < 0 then now else min ttl now, render)
+  250 
+  251 -- | Low-level frame modifier.
+  252 spriteModify :: Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
+  253 spriteModify (Sprite born ref) modFn = liftST $
+  254   modifySTRef ref $ \(ttl, renderGen) ->
+  255     ( ttl,
+  256       do
+  257         render <- renderGen
+  258         modRender <- unFrame modFn
+  259         return $ \relD relT ->
+  260           let absT = relT + born in modRender absT relD relT . render relD relT
+  261     )
+  262 
+  263 -- | Map the SVG output of a sprite.
+  264 --
+  265 --   Example:
+  266 --
+  267 -- @
+  268 -- do s \<- 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawCircle'
+  269 --    'wait' 1
+  270 --    'spriteMap' s 'flipYAxis'
+  271 -- @
+  272 --
+  273 --   <<docs/gifs/doc_spriteMap.gif>>
+  274 spriteMap :: Sprite s -> (SVG -> SVG) -> Scene s ()
+  275 spriteMap sprite@(Sprite born _) fn = do
+  276   now <- queryNow
+  277   let tDelta = now - born
+  278   spriteModify sprite $ do
+  279     t <- spriteT
+  280     return $ \(svg, zindex) -> (if (t - tDelta) < 0 then svg else fn svg, zindex)
+  281 
+  282 -- | Modify the output of a sprite between @now@ and @now+duration@.
+  283 --
+  284 --   Example:
+  285 --
+  286 -- @
+  287 -- do s \<- 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawCircle'
+  288 --    'spriteTween' s 1 $ \\val -> 'translate' ('Reanimate.Constants.screenWidth'*0.3*val) 0
+  289 -- @
+  290 --
+  291 --   <<docs/gifs/doc_spriteTween.gif>>
+  292 spriteTween :: Sprite s -> Duration -> (Double -> SVG -> SVG) -> Scene s ()
+  293 spriteTween sprite@(Sprite born _) dur fn = do
+  294   now <- queryNow
+  295   let tDelta = now - born
+  296   spriteModify sprite $ do
+  297     t <- spriteT
+  298     return $ first $ \svg -> fn (clamp 0 1 $ (t - tDelta) / dur) svg
+  299   wait dur
+  300   where
+  301     clamp a b v
+  302       | v < a = a
+  303       | v > b = b
+  304       | otherwise = v
+  305 
+  306 -- | Create a new variable and apply it to a sprite.
+  307 --
+  308 --   Example:
+  309 --
+  310 -- @
+  311 -- do s \<- 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawBox'
+  312 --    v \<- 'spriteVar' s 0 'rotate'
+  313 --    'tweenVar' v 2 $ \\val -> 'fromToS' val 90
+  314 -- @
+  315 --
+  316 --   <<docs/gifs/doc_spriteVar.gif>>
+  317 spriteVar :: Sprite s -> a -> (a -> SVG -> SVG) -> Scene s (Var s a)
+  318 spriteVar sprite def fn = do
+  319   v <- newVar def
+  320   applyVar v sprite fn
+  321   return v
+  322 
+  323 -- | Apply an effect to a sprite.
+  324 --
+  325 --   Example:
+  326 --
+  327 -- @
+  328 -- do s <- 'fork' $ 'newSpriteA' 'Reanimate.Builtin.Documentation.drawCircle'
+  329 --    'spriteE' s $ 'overBeginning' 1 'fadeInE'
+  330 --    'spriteE' s $ 'overEnding' 0.5 'fadeOutE'
+  331 -- @
+  332 --
+  333 --   <<docs/gifs/doc_spriteE.gif>>
+  334 spriteE :: Sprite s -> Effect -> Scene s ()
+  335 spriteE (Sprite born ref) effect = do
+  336   now <- queryNow
+  337   liftST $
+  338     modifySTRef ref $ \(ttl, renderGen) ->
+  339       ( ttl,
+  340         do
+  341           render <- renderGen
+  342           return $ \d t svg ->
+  343             let (svg', z) = render d t svg
+  344              in (delayE (max 0 $ now - born) effect d t svg', z)
+  345       )
+  346 
+  347 -- | Set new ZIndex of a sprite.
+  348 --
+  349 --   Example:
+  350 --
+  351 -- @
+  352 -- do s1 \<- 'newSpriteSVG' $ 'withFillOpacity' 1 $ 'withFillColor' "blue" $ 'mkCircle' 3
+  353 --    'newSpriteSVG' $ 'withFillOpacity' 1 $ 'withFillColor' "red" $ 'mkRect' 8 3
+  354 --    'wait' 1
+  355 --    'spriteZ' s1 1
+  356 --    'wait' 1
+  357 -- @
+  358 --
+  359 --   <<docs/gifs/doc_spriteZ.gif>>
+  360 spriteZ :: Sprite s -> ZIndex -> Scene s ()
+  361 spriteZ (Sprite born ref) zindex = do
+  362   now <- queryNow
+  363   liftST $
+  364     modifySTRef ref $ \(ttl, renderGen) ->
+  365       ( ttl,
+  366         do
+  367           render <- renderGen
+  368           return $ \d t svg ->
+  369             let (svg', z) = render d t svg in (svg', if t < now - born then z else zindex)
+  370       )
+  371 
+  372 -- | Destroy all local sprites at the end of a scene.
+  373 --
+  374 --   Example:
+  375 --
+  376 -- @
+  377 -- do -- the rect lives through the entire 3s animation
+  378 --    'newSpriteSVG_' $ 'translate' (-3) 0 $ 'mkRect' 4 4
+  379 --    'wait' 1
+  380 --    'spriteScope' $ do
+  381 --      -- the circle only lives for 1 second.
+  382 --      local \<- 'newSpriteSVG' $ 'translate' 3 0 $ 'mkCircle' 2
+  383 --      'spriteE' local $ 'overBeginning' 0.3 'fadeInE'
+  384 --      'spriteE' local $ 'overEnding' 0.3 'fadeOutE'
+  385 --      'wait' 1
+  386 --    'wait' 1
+  387 -- @
+  388 --
+  389 --   <<docs/gifs/doc_spriteScope.gif>>
+  390 spriteScope :: Scene s a -> Scene s a
+  391 spriteScope (M action) = M $ \t -> do
+  392   (a, s, p, gens) <- action t
+  393   return (a, s, p, map (genFn (t + max s p)) gens)
+  394   where
+  395     genFn maxT gen = do
+  396       frameGen <- gen
+  397       return $ \_ t ->
+  398         if t < maxT
+  399           then frameGen maxT t
+  400           else (None, 0)
+  401 
+  402 asAnimation :: (forall s'. Scene s' a) -> Scene s Animation
+  403 asAnimation s = do
+  404   now <- queryNow
+  405   return $ dropA now (sceneAnimation (wait now >> s))
+  406 
+  407 -- | Apply a transformation with a given overlap. This makes sure
+  408 --   to keep timestamps intact such that events can still be timed
+  409 --   by transcripts.
+  410 transitionO :: Transition -> Double -> (forall s'. Scene s' a) -> (forall s'. Scene s' b) -> Scene s ()
+  411 transitionO t o a b = do
+  412   aA <- asAnimation a
+  413   bA <- fork $ do
+  414     wait (duration aA - o)
+  415     asAnimation b
+  416   play $ overlapT o t aA bA
+
+
+ + diff --git a/reanimate-0.4.3.0-inplace/Reanimate.Scene.Var.hs.html b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Var.hs.html new file mode 100644 index 0000000..926a43f --- /dev/null +++ b/reanimate-0.4.3.0-inplace/Reanimate.Scene.Var.hs.html @@ -0,0 +1,193 @@ + + + + + + +
+never executed always true always false
+
+
+    1 {-# LANGUAGE LambdaCase #-}
+    2 {-# LANGUAGE RecordWildCards #-}
+    3 
+    4 module Reanimate.Scene.Var where
+    5 
+    6 import Control.Monad.ST (ST)
+    7 import qualified Data.Map as M
+    8 import Data.Maybe (fromMaybe)
+    9 import Data.STRef
+   10 import Reanimate.Animation (Duration, Time)
+   11 import Reanimate.Scene.Core (Scene, liftST, queryNow, wait)
+   12 
+   13 -- | Time dependent variable.
+   14 newtype Var s a = Var (STRef s (VarData a))
+   15 
+   16 -- Note: We must ensure that upon transforming an VarData,
+   17 --       1. evarDefault old == evarDefault new
+   18 --       2. isNothing (evarLastTime old) || isJust (evarLastTime new) i.e. once evarLastValue has a Just value,
+   19 --          it shouldn't be Nothing again.
+   20 --       3. isNothing (evarLastTime var) => M.null (evarTimeline var)
+   21 data VarData a = VarData
+   22   { evarDefault :: a,
+   23     evarTimeline :: Timeline a,
+   24     evarLastTime :: Maybe Time,
+   25     evarLastValue :: a
+   26   }
+   27 
+   28 data Modifier a = StaticValue a | TweenValue Duration (a -> Time -> a)
+   29 
+   30 type Timeline a = M.Map Time (Modifier a)
+   31 
+   32 -- | Create a new variable with a default value.
+   33 --   Variables always have a defined value even if they are read at a timestamp that is
+   34 --   earlier than when the variable was created. For example:
+   35 --
+   36 -- @
+   37 -- do v \<- 'fork' ('wait' 10 \>\> 'newVar' 0) -- Create a variable at timestamp '10'.
+   38 --    'readVar' v                       -- Read the variable at timestamp '0'.
+   39 --                                    -- The value of the variable will be '0'.
+   40 -- @
+   41 newVar :: a -> Scene s (Var s a)
+   42 newVar def = Var <$> liftST (newSTRef $ VarData def M.empty Nothing def)
+   43 
+   44 -- | Read the value of a variable at the current timestamp.
+   45 readVar :: Var s a -> Scene s a
+   46 readVar (Var ref) = readVarData <$> liftST (readSTRef ref) <*> queryNow
+   47 
+   48 unpackVar :: Var s a -> ST s (Time -> a)
+   49 unpackVar (Var ref) = readVarData <$> readSTRef ref
+   50 
+   51 -- | Write the value of a variable at the current timestamp.
+   52 --
+   53 --   Example:
+   54 --
+   55 -- @
+   56 -- do v \<- 'newVar' 0
+   57 --    'newSprite' $ 'mkCircle' \<$\> 'unVar' v
+   58 --    'writeVar' v 1; 'wait' 1
+   59 --    'writeVar' v 2; 'wait' 1
+   60 --    'writeVar' v 3; 'wait' 1
+   61 -- @
+   62 --
+   63 --   <<docs/gifs/doc_writeVar.gif>>
+   64 writeVar :: Var s a -> a -> Scene s ()
+   65 writeVar (Var ref) val = do
+   66   now <- queryNow
+   67   liftST $ modifySTRef ref $ writeVarData now val
+   68 
+   69 -- | Modify the value of a variable at the current timestamp and all future timestamps.
+   70 modifyVar :: Var s a -> (a -> a) -> Scene s ()
+   71 modifyVar (Var ref) fn = do
+   72   now <- queryNow
+   73   liftST $ modifySTRef ref $ modifyVarData now fn
+   74 
+   75 -- | Modify a variable between @now@ and @now+duration@.
+   76 tweenVar :: Var s a -> Duration -> (a -> Time -> a) -> Scene s ()
+   77 tweenVar _ dur _ | dur < 0 = error "Reanimate.tweenVar: durations must be non-negative"
+   78 tweenVar (Var ref) dur fn = do
+   79   now <- queryNow
+   80   liftST $ modifySTRef ref $ tweenVarData now dur fn
+   81   wait dur
+   82 
+   83 readVarData :: VarData a -> Time -> a
+   84 readVarData (VarData def _ Nothing _) _ = def
+   85 readVarData (VarData def timeline (Just lastTime) lastValue) now
+   86   | now < lastTime = lookupTimeline timeline def now
+   87   | otherwise = lastValue
+   88 
+   89 lookupTimeline :: Timeline a -> a -> Time -> a
+   90 lookupTimeline timeline def now = case M.lookupLE now timeline of
+   91   Just (_, StaticValue sVal) -> sVal
+   92   Just (t, TweenValue dur f)
+   93     | t + dur > now -> f def now
+   94   _ -> def
+   95 
+   96 writeVarData :: Time -> a -> VarData a -> VarData a
+   97 writeVarData now x var =
+   98   let before = keepBefore now var
+   99       after = VarData (evarDefault var) M.empty (Just now) x
+  100    in after `elseVar` before
+  101 
+  102 modifyVarData :: Time -> (a -> a) -> VarData a -> VarData a
+  103 modifyVarData now fn var =
+  104   let before = keepBefore now var
+  105       after = keepFrom now var
+  106       timeline = flip M.map (evarTimeline after) $ \case
+  107         StaticValue s -> StaticValue $ fn s
+  108         TweenValue dur f -> TweenValue dur $ \a t -> fn (f a t)
+  109    in after {evarTimeline = timeline, evarLastValue = fn $ evarLastValue after} `elseVar` before
+  110 
+  111 -- Note: The function passed here takes time on the scale 0 to 1
+  112 --       while the function in `TweenValue` takes time on an absolute scale.
+  113 tweenVarData :: Time -> Duration -> (a -> Time -> a) -> VarData a -> VarData a
+  114 tweenVarData st dur fn var@VarData {..} =
+  115   let nd = st + dur
+  116       before = keepBefore st var
+  117       during = keepInRange (Just st) (Just nd) var
+  118       tweenFn a t =
+  119         let idx = (t - st) / dur
+  120             idx' = if isNaN idx then 1 else idx
+  121          in fn (readVarData (during {evarDefault = a}) t) idx'
+  122       valueTweenEnd = tweenFn evarDefault nd -- we'll never use the def here, replace with error?
+  123       after = VarData evarDefault (M.singleton st $ TweenValue dur tweenFn) (Just nd) valueTweenEnd
+  124    in after `elseVar` before
+  125 
+  126 -- Returns the union of two vars such that we use the second var if first var doesn't have a value.
+  127 -- Assumes both vars have same default value.
+  128 elseVar :: VarData a -> VarData a -> VarData a
+  129 elseVar var1 var2
+  130   | Just t <- evarLastTime var1 =
+  131     let afterTimeline = evarTimeline var1
+  132         joinAt = fromMaybe t . fmap fst $ M.lookupMin afterTimeline
+  133         beforeTimeline = case keepBefore joinAt var2 of
+  134           x
+  135             | Just lastTime <- evarLastTime x, lastTime < joinAt -> M.insert lastTime (StaticValue $ evarLastValue x) $ evarTimeline x
+  136             | otherwise -> evarTimeline x
+  137      in var1 {evarTimeline = M.union afterTimeline beforeTimeline}
+  138   | otherwise = var2
+  139 
+  140 -- Restrict a var to a given time interval.
+  141 keepInRange :: Maybe Time -> Maybe Time -> VarData a -> VarData a
+  142 keepInRange st nd = fromMaybe id (keepFrom <$> st) . fromMaybe id (keepBefore <$> nd)
+  143 
+  144 -- Restrict a var to start at given timestamp.
+  145 keepFrom :: Time -> VarData a -> VarData a
+  146 keepFrom st VarData {..} =
+  147   let timeline' = M.dropWhileAntitone (< st) evarTimeline
+  148       -- if there is no modifier in timeline starting at st,
+  149       -- we must get the modifier that starts before and truncate it to start at st.
+  150       timeline'' = case M.lookupLE st evarTimeline of
+  151         Just (t, val@(StaticValue _))
+  152           | t < st -> M.insert st val timeline'
+  153         Just (t, TweenValue dur fn)
+  154           | t < st, t + dur > st -> M.insert st (TweenValue (t + dur - st) fn) timeline'
+  155         _ -> timeline'
+  156    in VarData evarDefault timeline'' (max evarLastTime $ Just st) evarLastValue
+  157 
+  158 -- Restrict a var to end(clamp) at given timestamp.
+  159 keepBefore :: Time -> VarData a -> VarData a
+  160 keepBefore nd var@VarData {..} =
+  161   let timeline' = M.takeWhileAntitone (< nd) evarTimeline
+  162       lastModifier = M.lookupMax timeline'
+  163       timeline'' = case lastModifier of
+  164         Just (t, TweenValue dur fn)
+  165           | t + dur > nd -> M.insert t (TweenValue (nd - t) fn) timeline'
+  166         _ -> timeline'
+  167       lastTime = case lastModifier of
+  168         Just (t, TweenValue dur _) -> Just $ min nd (t + dur)
+  169         _ -> min nd <$> evarLastTime
+  170    in VarData evarDefault timeline'' lastTime (fromMaybe evarDefault $ fmap (readVarData var) lastTime)
+
+
+ +