packages feed

reanimate 1.1.5.0 → 1.1.6.0

raw patch · 9 files changed

+112/−48 lines, 9 filesdep −hgeometrydep −hgeometry-combinatorialbinary-addedPVP ok

version bump matches the API change (PVP)

Dependencies removed: hgeometry, hgeometry-combinatorial

API changes (from Hackage documentation)

+ Reanimate: newSpritePart :: Frame s SVG -> Scene s (Sprite s)
+ Reanimate: renderSprite :: Sprite s -> Frame s SVG
+ Reanimate.Scene: newObjectPart :: Renderable a => a -> Scene s (Object s a)
+ Reanimate.Scene: newSpritePart :: Frame s SVG -> Scene s (Sprite s)
+ Reanimate.Scene: renderObject :: Object s a -> Frame s SVG
+ Reanimate.Scene: renderSprite :: Sprite s -> Frame s SVG

Files

ChangeLog.md view
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and the project adheres to the [Haskell Package Versioning Policy (PVP)](https://pvp.haskell.org)+## 1.1.6.0 -- 2022-06-02++ * Drop hgeometry dependency.  ## 1.1.4.0 -- 2021-03-11 
+ docs/gifs/doc_renderObject.gif view

binary file changed (absent → 53349 bytes)

reanimate.cabal view
@@ -3,7 +3,7 @@ --  see http://haskell.org/cabal/users-guide/  name:                reanimate-version:             1.1.5.0+version:             1.1.6.0 -- synopsis: -- description: license:             PublicDomain@@ -37,13 +37,6 @@     Type:      git     Location:  git://github.com/lemmih/reanimate.git -flag no-hgeometry-  description:-    Disable all features that depend on hgeometry. Should only-    be used when developing new hgeometry algorithms.-  default: False-  manual: True- library   hs-source-dirs:     src   if os(windows)@@ -113,12 +106,7 @@                       Detach                       POVRay   autogen-modules:    Paths_reanimate-  if flag(no-hgeometry)-    cpp-options: -DNO_HGEOMETRY-  else-    build-depends:-      hgeometry               >=0.11.0.0,-      hgeometry-combinatorial >=0.11.0.0+  cpp-options: -DNO_HGEOMETRY   build-depends:     base                 >=4.10 && <5,     JuicyPixels          >=3.3.3,@@ -178,6 +166,7 @@     Helpers   hs-source-dirs: test   ghc-options: -w+  cpp-options: -DNO_HGEOMETRY   build-depends:     base,     directory,
src/Reanimate.hs view
@@ -105,12 +105,14 @@   , spriteDuration    -- :: Frame s Duration   , signalS           -- :: Sprite s -> Duration -> Signal -> Scene s ()   , newSprite         -- :: Frame s SVG -> Scene s (Sprite s)+  , newSpritePart     -- :: Frame s SVG -> Scene s (Sprite s)   , newSprite_        -- :: Frame s SVG -> Scene s ()   , newSpriteA        -- :: Animation -> Scene s (Sprite s)   , newSpriteA'       -- :: Sync -> Animation -> Scene s (Sprite s)   , newSpriteSVG      -- :: SVG -> Scene s (Sprite s)   , newSpriteSVG_     -- :: SVG -> Scene s ()   , destroySprite     -- :: Sprite s -> Scene s ()+  , renderSprite      -- :: Sprite s -> Frame s SVG   , applyVar          -- :: Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()   , spriteModify      -- :: Sprite s -> Frame s ((SVG,ZIndex) -> (SVG, ZIndex)) -> Scene s ()   , spriteMap         -- :: Sprite s -> (SVG -> SVG) -> Scene s ()
src/Reanimate/PolyShape.hs view
@@ -41,7 +41,7 @@   , plGroupTouching   ) where -import           Control.Lens                                         ((&), (.~), (^.))+import           Control.Lens                                         ((&), (.~)) import           Data.List                                            (nub, partition, sortOn) import qualified Data.Vector                                          as V import           Geom2D.CubicBezier.Linear                            (ClosedPath (..),@@ -67,6 +67,7 @@ import           Reanimate.Svg  #if !defined(NO_HGEOMETRY)+import           Control.Lens                                         ((^.)) import           Algorithms.Geometry.PolygonTriangulation.Triangulate (triangulate')  import           Data.Ext
src/Reanimate/Scene.hs view
@@ -39,12 +39,14 @@     spriteT, -- :: Frame s Time     spriteDuration, -- :: Frame s Duration     newSprite, -- :: Frame s SVG -> Scene s (Sprite s)+    newSpritePart, -- :: Frame s SVG -> Scene s (Sprite s)     newSprite_, -- :: Frame s SVG -> Scene s ()     newSpriteA, -- :: Animation -> Scene s (Sprite s)     newSpriteA', -- :: Sync -> Animation -> Scene s (Sprite s)     newSpriteSVG, -- :: SVG -> Scene s (Sprite s)     newSpriteSVG_, -- :: SVG -> Scene s ()     destroySprite, -- :: Sprite s -> Scene s ()+    renderSprite, -- :: Sprite s -> Frame s SVG     applyVar, -- :: Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()     spriteModify, -- :: Sprite s -> Frame s ((SVG,ZIndex) -> (SVG, ZIndex)) -> Scene s ()     spriteMap, -- :: Sprite s -> (SVG -> SVG) -> Scene s ()@@ -60,6 +62,8 @@     signalO,     oNew,     newObject,+    newObjectPart,+    renderObject,     oModify,     oModifyS,     oRead,
src/Reanimate/Scene/Object.hs view
@@ -18,7 +18,7 @@ import           Reanimate.Svg  import           Reanimate.Scene.Core   (Scene, fork, scene, wait)-import           Reanimate.Scene.Sprite (Sprite, newSprite, newSpriteA', play, spriteModify, unVar, signalS)+import           Reanimate.Scene.Sprite (Frame, Sprite, addPartToScene, newSpritePart, newSpriteA', play, spriteModify, unVar, signalS, renderSprite) import           Reanimate.Scene.Var    (Var, modifyVar, newVar, readVar, tweenVar)  -------------------------------------------------------@@ -290,6 +290,15 @@ -- | Create new object. newObject :: Renderable a => a -> Scene s (Object s a) newObject val = do+  obj <- newObjectPart val+  addPartToScene $ objectSprite obj+  return obj++-- | Create new object, but not showing as part of the scene, Such+--   objects can be used hierachically within the definitions of+--   sprites, via the function renderObject.+newObjectPart :: Renderable a => a -> Scene s (Object s a)+newObjectPart val = do   ref <-     newVar       ObjectData@@ -306,7 +315,7 @@           _oScale = 1,           _oScaleOrigin = V2 0 0         }-  sprite <- newSprite $ do+  sprite <- newSpritePart $ do     ~obj@ObjectData {..} <- unVar ref     pure $       if _oShown@@ -326,6 +335,32 @@       }   where     svg = toSVG val++-- | Create a frame context from an object for use within a sprite definition.+--+--   Example:+--+-- @+-- do opacityVar <- 'newVar' 1+--    textObj1 <- 'newObjectPart' $ 'scale' 3 $ 'center' $ 'latex' "Fade"+--    'oModify' textObj1 $ 'oContext' .~ 'withFillColor' "red"+--    textObj2 <- 'newObjectPart' $ 'scale' 3 $ 'center' $ 'latex' "Overlap"+--    'oModify' textObj2 $ 'oContext' .~ 'withFillColor' "blue"+--    sprite <- 'newSprite' $ do+--      opacity <- 'unVar' opacityVar+--      text1 <- 'renderObject' textObj1+--      text2 <- 'renderObject' textObj2+--      'return' $ 'withGroupOpacity' opacity $ 'mkGroup' [text1, text2]+--    'fork' $ 'oShowWith' textObj1 $ 'setDuration' 1 . 'oDraw'+--    'wait' 0.2+--    'fork' $ 'oShowWith' textObj2 $ 'setDuration' 1 . 'oDraw'+--    'wait' 0.2+--    'tweenVar' opacityVar 1 $ 'const' $ 'fromToS' 1 0+-- @+--+-- <<docs/gifs/doc_renderObject.gif>>+renderObject :: Object s a -> Frame s SVG+renderObject obj = renderSprite $ objectSprite obj  oScaleApply :: ObjectData a -> (SVG -> SVG) oScaleApply ObjectData {..} =
src/Reanimate/Scene/Sprite.hs view
@@ -12,7 +12,7 @@ import           Reanimate.Animation  (Animation, Duration, SVG, Sync (SyncStretch), Time, dropA,                                        duration, getAnimationFrame) import           Reanimate.Effect     (Effect, delayE)-import           Reanimate.Scene.Core (Scene (M), ZIndex, addGen, fork, liftST, queryNow, scene,+import           Reanimate.Scene.Core (Gen, Scene (M), ZIndex, addGen, fork, liftST, queryNow, scene,                                        wait) import           Reanimate.Scene.Var  (Var (..), newVar, readVar, unpackVar) import           Reanimate.Transition (Transition, overlapT)@@ -58,22 +58,22 @@  -- | Sprites are animations with a given time of birth as well as a time of death. --   They can be controlled using variables, tweening, and effects.-data Sprite s = Sprite Time (STRef s (Time -> Time)) (STRef s (Duration, ST s (Duration -> Time -> SVG -> (SVG, ZIndex))))+data Sprite s = Sprite Time (STRef s (Time -> Time)) (STRef s (Duration, ST s (Duration -> Duration -> Time -> SVG -> (SVG, ZIndex)))) (Gen s)  -- | Sprite frame generator. Generates frames over time in a stateful environment.-newtype Frame s a = Frame {unFrame :: ST s (Time -> Duration -> Time -> a)}+newtype Frame s a = Frame {unFrame :: ST s (Duration -> Time -> Duration -> Time -> a)}  instance Functor (Frame s) where   fmap fn (Frame gen) = Frame $ do     m <- gen-    return (\real_t d t -> fn $ m real_t d t)+    return (\scene_d real_t d t -> fn $ m scene_d real_t d t)  instance Applicative (Frame s) where-  pure v = Frame $ return (\_ _ _ -> v)+  pure v = Frame $ return (\_ _ _ _ -> v)   Frame f <*> Frame g = Frame $ do     m1 <- f     m2 <- g-    return $ \real_t d t -> m1 real_t d t (m2 real_t d t)+    return $ \scene_d real_t d t -> m1 scene_d real_t d t (m2 scene_d real_t d t)  -- | Dereference a variable as a Sprite frame. --@@ -90,15 +90,15 @@ unVar :: Var s a -> Frame s a unVar var = Frame $ do   fn <- unpackVar var-  return $ \real_t _d _t -> fn real_t+  return $ \_scene_d real_t _d _t -> fn real_t  -- | Dereference seconds since sprite birth. spriteT :: Frame s Time-spriteT = Frame $ return (\_real_t _d t -> t)+spriteT = Frame $ return (\_scene_d _real_t _d t -> t)  -- | Dereference duration of the current sprite. spriteDuration :: Frame s Duration-spriteDuration = Frame $ return (\_real_t d _t -> d)+spriteDuration = Frame $ return (\_scene_d _real_t d _t -> d)  -- | Create new sprite defined by a frame generator. Unless otherwise specified using --   'destroySprite', the sprite will die at the end of the scene.@@ -113,17 +113,26 @@ --   <<docs/gifs/doc_newSprite.gif>> newSprite :: Frame s SVG -> Scene s (Sprite s) newSprite render = do+  s <- newSpritePart render+  addPartToScene s+  return s++-- | Create a new sprite defined by a frame generator, but not showing+--   as part of the scene. Such sprites can be used hierarchically within+--   the definitions of other sprites, via the function renderSprite.+newSpritePart :: Frame s SVG -> Scene s (Sprite s)+newSpritePart render = do   now <- queryNow   tmod <- liftST $ newSTRef id-  ref <- liftST $ newSTRef (-1, return $ \_d _t svg -> (svg, 0))-  addGen $ do+  ref <- liftST $ newSTRef (-1, return $ \_ad _d _t svg -> (svg, 0))+  return $ Sprite now tmod ref $ do     fn <- unFrame render     time_fn <- readSTRef tmod     (spriteDur, spriteEffectGen) <- readSTRef ref     spriteEffect <- spriteEffectGen-    return $ \d absT_ ->+    return $ \absD absT_ ->       let absT = time_fn absT_-          relD = (if spriteDur < 0 then d else spriteDur) - now+          relD = (if spriteDur < 0 then absD else spriteDur) - now           relT = absT - now           -- Sprite is live [now;duration[           -- If we're at the end of a scene, sprites@@ -131,12 +140,14 @@           -- This behavior is difficult to get right. See the 'bug_*' examples for           -- automated tests.           inTimeSlice = relT >= 0 && relT < relD-          isLastFrame = d == absT && relT == relD-       in if inTimeSlice || isLastFrame-            then spriteEffect relD relT (fn absT relD relT)+          isLastFrame = absD == absT && relT == relD+      in if inTimeSlice || isLastFrame+            then spriteEffect absD relD relT (fn absD absT relD relT)             else (None, 0)-  return $ Sprite now tmod ref +addPartToScene :: Sprite s -> Scene s ()+addPartToScene (Sprite _ _ _ gen) = addGen gen+ -- | Create new sprite defined by a frame generator. The sprite will die at --   the end of the scene. newSprite_ :: Frame s SVG -> Scene s ()@@ -197,6 +208,15 @@ newSpriteSVG_ :: SVG -> Scene s () newSpriteSVG_ = void . newSpriteSVG +-- | Create a frame context from the source sprite for use within another. Use of this+--   function allows several sprites to be combined into a single one, with the+--   method of combination controled by variables.+renderSprite :: Sprite s -> Frame s SVG+renderSprite (Sprite _ _ _ gen) =+  Frame $ do+            genFn <- gen+            return (\absD absT _ _ -> fst $ genFn absD absT)+ -- | Change the rendering of a sprite using data from a variable. If data from several variables --   is needed, use a frame generator instead. --@@ -228,7 +248,7 @@ -- --   <<docs/gifs/doc_destroySprite.gif>> destroySprite :: Sprite s -> Scene s ()-destroySprite (Sprite _ _tmod ref) = do+destroySprite (Sprite _ _tmod ref _) = do   now <- queryNow   liftST $     modifySTRef ref $ \(ttl, render) ->@@ -236,19 +256,19 @@  -- | Low-level frame modifier. spriteModify :: Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()-spriteModify (Sprite born _tmod ref) modFn = liftST $+spriteModify (Sprite born _tmod ref _) modFn = liftST $   modifySTRef ref $ \(ttl, renderGen) ->     ( ttl,       do         render <- renderGen         modRender <- unFrame modFn-        return $ \relD relT ->-          let absT = relT + born in modRender absT relD relT . render relD relT+        return $ \absD relD relT ->+          let absT = relT + born in modRender absD absT relD relT . render absD relD relT     )  -- | Apply easing function before rendering sprite. signalS :: Sprite s -> Duration -> Signal -> Scene s ()-signalS (Sprite _born tmod _ref) dur signal = do+signalS (Sprite _born tmod _ref _) dur signal = do   now <- queryNow   let modify_t t         | t < now     = t@@ -271,7 +291,7 @@ -- --   <<docs/gifs/doc_spriteMap.gif>> spriteMap :: Sprite s -> (SVG -> SVG) -> Scene s ()-spriteMap sprite@(Sprite born _ _) fn = do+spriteMap sprite@(Sprite born _ _ _) fn = do   now <- queryNow   let tDelta = now - born   spriteModify sprite $ do@@ -289,7 +309,7 @@ -- --   <<docs/gifs/doc_spriteTween.gif>> spriteTween :: Sprite s -> Duration -> (Double -> SVG -> SVG) -> Scene s ()-spriteTween sprite@(Sprite born _ _) dur fn = do+spriteTween sprite@(Sprite born _ _ _) dur fn = do   now <- queryNow   let tDelta = now - born   spriteModify sprite $ do@@ -331,15 +351,15 @@ -- --   <<docs/gifs/doc_spriteE.gif>> spriteE :: Sprite s -> Effect -> Scene s ()-spriteE (Sprite born _tmod ref) effect = do+spriteE (Sprite born _tmod ref _) effect = do   now <- queryNow   liftST $     modifySTRef ref $ \(ttl, renderGen) ->       ( ttl,         do           render <- renderGen-          return $ \d t svg ->-            let (svg', z) = render d t svg+          return $ \ad d t svg ->+            let (svg', z) = render ad d t svg              in (delayE (max 0 $ now - born) effect d t svg', z)       ) @@ -357,15 +377,15 @@ -- --   <<docs/gifs/doc_spriteZ.gif>> spriteZ :: Sprite s -> ZIndex -> Scene s ()-spriteZ (Sprite born _tmod ref) zindex = do+spriteZ (Sprite born _tmod ref _) zindex = do   now <- queryNow   liftST $     modifySTRef ref $ \(ttl, renderGen) ->       ( ttl,         do           render <- renderGen-          return $ \d t svg ->-            let (svg', z) = render d t svg in (svg', if t < now - born then z else zindex)+          return $ \ad d t svg ->+            let (svg', z) = render ad d t svg in (svg', if t < now - born then z else zindex)       )  -- | Destroy all local sprites at the end of a scene.
test/Properties.hs view
@@ -1,13 +1,17 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances    #-} {-# OPTIONS_GHC -w      #-} {-# LANGUAGE TemplateHaskell      #-} module Properties where +import           Test.Tasty++#if !defined(NO_HGEOMETRY)+ import qualified Data.Vector            as V import           Linear.V2 import           Linear.Vector import           Test.QuickCheck-import           Test.Tasty import           Test.Tasty.QuickCheck  import           Reanimate.Math.Common@@ -18,6 +22,8 @@  import Debug.Trace ++ prop_pGenerate (PolyParam a) (PolyParam b) (PolyParam c) (PolyParam d) =   pIsSimple $ pGenerate [a,b,c,d] @@ -87,3 +93,7 @@ return [] all_props :: TestTree all_props = testProperties "properties" $allProperties+#else+all_props :: TestTree+all_props = testGroup "properties" []+#endif