diff --git a/primer/primer.cabal b/primer/primer.cabal index 590871b8d..33dfec856 100644 --- a/primer/primer.cabal +++ b/primer/primer.cabal @@ -118,6 +118,7 @@ library , exceptions >=0.10.4 && <0.11.0 , extra >=1.7.10 && <1.8.0 , generic-optics >=2.0 && <2.3.0 + , JuicyPixels ^>=3.3.8 , list-t >=1.0 && <1.1.0 , logging-effect ^>=1.4 , mmorph ^>=1.2.0 diff --git a/primer/src/Primer/Primitives.hs b/primer/src/Primer/Primitives.hs index 64ff1b080..63ae54c3e 100644 --- a/primer/src/Primer/Primitives.hs +++ b/primer/src/Primer/Primitives.hs @@ -28,17 +28,24 @@ module Primer.Primitives ( import Foreword hiding (rotate) +import Codec.Picture.ColorQuant (palettizeWithAlpha) +import Codec.Picture.Gif ( + GifDisposalMethod (DisposalAny), + GifEncode (GifEncode), + GifLooping (LoopingForever), + encodeComplexGifImage, + ) import Control.Monad.Fresh (MonadFresh) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.ByteString.Base64 qualified as B64 import Data.Data (Data) import Data.Map qualified as M import Diagrams.Backend.Rasterific ( - GifLooping (LoopingForever), - defaultPaletteOptions, - rasterGif, + Options (RasterificOptions), + Rasterific (Rasterific), ) import Diagrams.Prelude ( + Diagram, V2 (..), circle, deg, @@ -47,6 +54,7 @@ import Diagrams.Prelude ( mkSizeSpec, rect, rectEnvelope, + renderDia, rotate, sRGB24, translate, @@ -336,7 +344,7 @@ primFunDef def args = case def of Animate -> case args of -- Note that `diagramExpr` is an expression of type `Picture` with one free variable, `time`. [PrimCon () (PrimInt duration), Lam () time diagramExpr] - | Just frames <- traverse diagramAtTime [0 .. (duration * 100) `div` frameLength] -> + | Just (frames :: [Diagram Rasterific]) <- traverse diagramAtTime [0 .. (duration * 100) `div` frameLength] -> Right $ prim $ PrimAnimation @@ -347,14 +355,16 @@ primFunDef def args = case def of -- for unrelated reasons (getting the `Bytestring` without dumping it to a file). mempty (decodeUtf8 . B64.encode . toS) - $ rasterGif @Double - (mkSizeSpec $ Just . fromInteger <$> V2 width height) - gifLooping - defaultPaletteOptions + $ encodeComplexGifImage + $ GifEncode (fromInteger width) (fromInteger height) Nothing Nothing gifLooping + $ flip palettizeWithAlpha DisposalAny $ map - ( (,fromInteger frameLength) + ( (fromInteger frameLength,) + . renderDia + Rasterific + (RasterificOptions (mkSizeSpec $ Just . fromInteger <$> V2 width height)) . rectEnvelope - (fromInteger <$> mkP2 (width `div` 2) (height `div` 2)) + (fromInteger <$> mkP2 (-width `div` 2) (-height `div` 2)) (fromInteger <$> V2 width height) ) frames