mirror of
https://github.com/reanimate/reanimate.git
synced 2026-09-10 15:42:21 +00:00
Switch back to stylish-haskell and enumerate imports.
This commit is contained in:
parent
96cd95f865
commit
e7bce27d12
39 changed files with 405 additions and 449 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.1 KiB |
BIN
docs/gifs/doc_svgLogo2.gif
Normal file
BIN
docs/gifs/doc_svgLogo2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
14
examples/doc_svgLogo.hs
Executable file → Normal file
14
examples/doc_svgLogo.hs
Executable file → Normal file
|
|
@ -1,16 +1,10 @@
|
|||
#!/usr/bin/env stack
|
||||
-- stack runghc --package reanimate
|
||||
|
||||
module Main (main) where
|
||||
|
||||
import Codec.Picture.Types
|
||||
import Reanimate
|
||||
import Reanimate.Builtin.Documentation
|
||||
import Reanimate.External
|
||||
import Reanimate
|
||||
import Reanimate.Builtin.Documentation
|
||||
import Reanimate.Builtin.Images
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
reanimate $
|
||||
docEnv $
|
||||
staticFrame 1 $
|
||||
withFillOpacity 1 $ svgLogo "cassandra"
|
||||
main = reanimate $ docEnv $ animate $ const svgLogo
|
||||
|
|
|
|||
15
examples/doc_svgLogo2.hs
Executable file
15
examples/doc_svgLogo2.hs
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env stack
|
||||
-- stack runghc --package reanimate
|
||||
|
||||
module Main (main) where
|
||||
|
||||
import Reanimate
|
||||
import Reanimate.Builtin.Documentation
|
||||
import Reanimate.External
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
reanimate $
|
||||
docEnv $
|
||||
staticFrame 1 $
|
||||
withFillOpacity 1 $ svgLogo "cassandra"
|
||||
|
|
@ -53,14 +53,13 @@ module Reanimate.Animation
|
|||
, renderSvg
|
||||
) where
|
||||
|
||||
import Control.Arrow ()
|
||||
import Data.Fixed (mod')
|
||||
import Graphics.SvgTree
|
||||
import Graphics.SvgTree.Printer
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Ease
|
||||
import Reanimate.Svg.Constructors
|
||||
import Text.XML.Light.Output
|
||||
import Graphics.SvgTree.Printer (ppDocument)
|
||||
import Reanimate.Constants (defaultStrokeWidth)
|
||||
import Reanimate.Ease (Signal, reverseS)
|
||||
import Reanimate.Svg.Constructors (mkGroup, scaleXY, withStrokeWidth)
|
||||
import Text.XML.Light.Output (ppElement)
|
||||
|
||||
-- | Duration of an animation or effect. Usually measured in seconds.
|
||||
type Duration = Double
|
||||
|
|
|
|||
|
|
@ -36,17 +36,17 @@ module Reanimate.Blender
|
|||
, blender'
|
||||
) where
|
||||
|
||||
import Data.Hashable
|
||||
import Data.Hashable (Hashable (hash))
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (Tree)
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Cache
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Misc
|
||||
import Reanimate.Parameters
|
||||
import Reanimate.Raster
|
||||
import Reanimate.Svg.Constructors
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Cache (cacheFile, encodeInt)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Misc (requireExecutable, runCmd)
|
||||
import Reanimate.Parameters (pNoExternals)
|
||||
import Reanimate.Raster (mkImage)
|
||||
import Reanimate.Svg.Constructors (mkText)
|
||||
import System.FilePath (replaceExtension, (<.>))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ Portability : POSIX
|
|||
Convenience module for rendering circle plots.
|
||||
|
||||
-}
|
||||
module Reanimate.Builtin.CirclePlot where
|
||||
module Reanimate.Builtin.CirclePlot
|
||||
( circlePlot
|
||||
) where
|
||||
|
||||
import Codec.Picture
|
||||
import Graphics.SvgTree (Tree)
|
||||
import Reanimate.Raster
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Constants
|
||||
import Codec.Picture (PixelRGBA8 (..), generateImage)
|
||||
import Graphics.SvgTree (Tree)
|
||||
import Reanimate.Constants (screenHeight)
|
||||
import Reanimate.Raster (embedImage)
|
||||
import Reanimate.Svg (flipYAxis, scaleToHeight)
|
||||
|
||||
-- | Circle plots are scaled to 'screenHeight'.
|
||||
--
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ GIFs for a consistent look and feel.
|
|||
-}
|
||||
module Reanimate.Builtin.Documentation where
|
||||
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Raster
|
||||
import Reanimate.Constants
|
||||
import Codec.Picture
|
||||
import Codec.Picture (PixelRGB8, PixelRGBA8 (..), generateImage)
|
||||
import Reanimate.Animation (Animation, SVG, mapA, mkAnimation)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Raster (embedImage)
|
||||
import Reanimate.Svg
|
||||
|
||||
-- | Default environment for API documentation GIFs.
|
||||
docEnv :: Animation -> Animation
|
||||
|
|
|
|||
|
|
@ -16,21 +16,21 @@ module Reanimate.Builtin.Images
|
|||
)
|
||||
where
|
||||
|
||||
import Codec.Picture
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (parseSvgFile)
|
||||
import Paths_reanimate
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg
|
||||
import System.IO.Unsafe
|
||||
import Codec.Picture
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (parseSvgFile)
|
||||
import Paths_reanimate
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg
|
||||
import System.IO.Unsafe
|
||||
|
||||
embedImage :: FilePath -> IO SVG
|
||||
embedImage key = do
|
||||
svg_file <- getDataFileName key
|
||||
svg_data <- T.readFile svg_file
|
||||
case parseSvgFile svg_file svg_data of
|
||||
Nothing -> error "Malformed svg"
|
||||
Nothing -> error "Malformed svg"
|
||||
Just svg -> return $ embedDocument svg
|
||||
|
||||
loadJPG :: FilePath -> Image PixelRGBA8
|
||||
|
|
@ -38,7 +38,7 @@ loadJPG key = unsafePerformIO $ do
|
|||
jpg_file <- getDataFileName key
|
||||
dat <- B.readFile jpg_file
|
||||
case decodeJpeg dat of
|
||||
Left err -> error err
|
||||
Left err -> error err
|
||||
Right img -> return $ convertRGBA8 img
|
||||
|
||||
{- HLINT ignore svgLogo -}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ Portability : POSIX
|
|||
-}
|
||||
module Reanimate.Builtin.Slide where
|
||||
|
||||
import Reanimate.Transition
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Effect
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Effect (constE, translateE)
|
||||
import Reanimate.Svg (translate)
|
||||
import Reanimate.Transition (Transition, effectT)
|
||||
|
||||
-- | <<docs/gifs/doc_slideLeftT.gif>>
|
||||
slideLeftT :: Transition
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ module Reanimate.Builtin.TernaryPlot
|
|||
, fromCartesianCoords
|
||||
) where
|
||||
|
||||
import Codec.Picture
|
||||
import Codec.Picture (PixelRGBA8 (..), generateImage)
|
||||
import Graphics.SvgTree (Tree)
|
||||
import Reanimate.Raster
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Raster (embedImage)
|
||||
import Reanimate.Svg (flipYAxis, scaleToWidth, translate)
|
||||
|
||||
-- a+b+c=1
|
||||
-- | Left-most coordinate.
|
||||
|
|
|
|||
|
|
@ -8,24 +8,24 @@ module Reanimate.Cache
|
|||
, encodeInt
|
||||
) where
|
||||
|
||||
import Control.Exception
|
||||
import Control.Exception (evaluate)
|
||||
import Control.Monad (unless)
|
||||
import Data.Bits
|
||||
import Data.Hashable
|
||||
import Data.IORef
|
||||
import Data.Bits (Bits (shiftR))
|
||||
import Data.Hashable (Hashable (hash))
|
||||
import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (Tree, unparse, pattern None)
|
||||
import Graphics.SvgTree (Tree, pattern None, unparse)
|
||||
import Reanimate.Animation (renderTree)
|
||||
import Reanimate.Misc (renameOrCopyFile,getReanimateCacheDirectory)
|
||||
import System.Directory
|
||||
import System.FilePath
|
||||
import System.IO
|
||||
import System.IO.Temp
|
||||
import System.IO.Unsafe
|
||||
import Reanimate.Misc (getReanimateCacheDirectory, renameOrCopyFile)
|
||||
import System.Directory (doesFileExist)
|
||||
import System.FilePath ((<.>), (</>))
|
||||
import System.IO (hClose)
|
||||
import System.IO.Temp (openTempFile, withSystemTempFile)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import Text.XML.Light (Content (..), parseXML)
|
||||
|
||||
-- Memory cache and disk cache
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@ module Reanimate.ColorComponents
|
|||
, fromRGB8
|
||||
) where
|
||||
|
||||
import Codec.Picture
|
||||
import Codec.Picture.Types
|
||||
import Data.Colour
|
||||
import Data.Colour.CIE
|
||||
import Codec.Picture (Pixel (pixelOpacity), PixelRGB8 (..), PixelRGBA8 (..))
|
||||
import Codec.Picture.Types (TransparentPixel (dropTransparency))
|
||||
import Data.Colour (Colour)
|
||||
import Data.Colour.CIE (cieLAB, cieLABView, cieXYZ, cieXYZView)
|
||||
import Data.Colour.CIE.Illuminant (d65)
|
||||
import Data.Colour.RGBSpace
|
||||
import Data.Colour.RGBSpace.HSV
|
||||
import Data.Colour.SRGB
|
||||
import Data.Fixed
|
||||
import Reanimate.Ease
|
||||
import Data.Colour.RGBSpace (RGB (RGB), uncurryRGB)
|
||||
import Data.Colour.RGBSpace.HSV (hsv, hsvView)
|
||||
import Data.Colour.SRGB (sRGB, sRGB24, toSRGB, toSRGBBounded)
|
||||
import Data.Fixed (mod')
|
||||
import Reanimate.Ease (fromToS)
|
||||
|
||||
-- | Constructor and destructor for color's three components.
|
||||
data ColorComponents = ColorComponents
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ module Reanimate.ColorMap
|
|||
, greyscale
|
||||
) where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Data.Vector (Vector)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Vector as V
|
||||
import Codec.Picture
|
||||
import Data.Char
|
||||
import Data.Bits
|
||||
import Codec.Picture (Pixel8, PixelRGB8 (..))
|
||||
import Data.Bits (Bits (shiftL))
|
||||
import Data.Char (digitToInt)
|
||||
import Data.Colour.RGBSpace (RGB (RGB))
|
||||
import qualified Data.Colour.RGBSpace.HSV as HSV
|
||||
import Data.Colour.RGBSpace
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import Data.Vector (Vector)
|
||||
import qualified Data.Vector as V
|
||||
|
||||
-- | Given a number t in the range [0,1], returns the corresponding color from
|
||||
-- the “turbo” color scheme by Anton Mikhailov.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ module Reanimate.Constants
|
|||
, defaultStrokeWidth
|
||||
) where
|
||||
|
||||
import Graphics.SvgTree
|
||||
import Graphics.SvgTree (Dpi)
|
||||
|
||||
-- | Number of units from the left-most point to the right-most point on the screen.
|
||||
screenWidth :: Fractional a => a
|
||||
|
|
|
|||
|
|
@ -12,15 +12,16 @@ module Reanimate.Debug
|
|||
)
|
||||
where
|
||||
|
||||
import Data.IORef
|
||||
import System.IO.Unsafe
|
||||
import Control.Exception
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg
|
||||
import Reanimate.LaTeX
|
||||
import Reanimate.Constants
|
||||
import Text.Printf
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception (evaluate)
|
||||
import Data.IORef (IORef, atomicModifyIORef', modifyIORef', newIORef)
|
||||
import qualified Data.Text as T
|
||||
import Reanimate.Animation (Animation, SVG, duration, parA, pause, seqA, staticFrame)
|
||||
import Reanimate.Constants (defaultStrokeWidth)
|
||||
import Reanimate.LaTeX (latex)
|
||||
import Reanimate.Svg (center, mkGroup, translate, withFillColor, withStrokeColor,
|
||||
withStrokeWidth)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import Text.Printf (printf)
|
||||
|
||||
{-# NOINLINE traceBuffer #-}
|
||||
traceBuffer :: IORef [Animation]
|
||||
|
|
|
|||
|
|
@ -9,12 +9,10 @@ module Reanimate.Driver.CLI
|
|||
, showRaster
|
||||
) where
|
||||
|
||||
import Data.Char
|
||||
import Data.Monoid
|
||||
import Data.Char (toLower)
|
||||
import Options.Applicative
|
||||
import Prelude
|
||||
import Reanimate.Render (FPS, Format (..), Height, Raster (..),
|
||||
Width)
|
||||
import Reanimate.Render (FPS, Format (..), Height, Raster (..), Width)
|
||||
|
||||
newtype Options = Options
|
||||
{ optsCommand :: Command
|
||||
|
|
@ -29,10 +27,10 @@ data Command
|
|||
| Test
|
||||
| Check
|
||||
| View
|
||||
{ viewVerbose :: Bool
|
||||
, viewGHCPath :: Maybe FilePath
|
||||
, viewGHCOpts :: [String]
|
||||
, viewOrigin :: Maybe FilePath
|
||||
{ viewVerbose :: Bool
|
||||
, viewGHCPath :: Maybe FilePath
|
||||
, viewGHCOpts :: [String]
|
||||
, viewOrigin :: Maybe FilePath
|
||||
}
|
||||
| Render
|
||||
{ renderTarget :: Maybe String
|
||||
|
|
@ -54,12 +52,12 @@ data Preset = Youtube | ExampleGif | Quick | MediumQ | HighQ | LowFPS
|
|||
readRaster :: String -> Maybe Raster
|
||||
readRaster raster =
|
||||
case map toLower raster of
|
||||
"none" -> Just RasterNone
|
||||
"auto" -> Just RasterAuto
|
||||
"inkscape" -> Just RasterInkscape
|
||||
"rsvg" -> Just RasterRSvg
|
||||
"imagemagick" -> Just RasterMagick
|
||||
_ -> Nothing
|
||||
"none" -> Just RasterNone
|
||||
"auto" -> Just RasterAuto
|
||||
"inkscape" -> Just RasterInkscape
|
||||
"rsvg" -> Just RasterRSvg
|
||||
"imagemagick" -> Just RasterMagick
|
||||
_ -> Nothing
|
||||
|
||||
showRaster :: Raster -> String
|
||||
showRaster RasterNone = "none"
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ module Reanimate.Driver.Check
|
|||
) where
|
||||
|
||||
import Control.Exception (SomeException, handle)
|
||||
import Control.Monad
|
||||
import Data.Maybe
|
||||
import Data.Version
|
||||
import Reanimate.Misc (runCmd_)
|
||||
import Control.Monad (forM_)
|
||||
import Data.Maybe (fromMaybe, listToMaybe)
|
||||
import Data.Version (Version (Version), parseVersion, showVersion)
|
||||
import Reanimate.Driver.Magick (magickCmd)
|
||||
import Reanimate.Misc (runCmd_)
|
||||
import System.Console.ANSI.Codes
|
||||
import System.Directory (findExecutable)
|
||||
import System.IO
|
||||
import System.IO.Temp
|
||||
import Text.ParserCombinators.ReadP
|
||||
import Text.Printf
|
||||
import System.IO (hClose, hPutStr)
|
||||
import System.IO.Temp (withSystemTempDirectory, withTempFile)
|
||||
import Text.ParserCombinators.ReadP (readP_to_S)
|
||||
import Text.Printf (printf)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Check environment
|
||||
|
|
|
|||
|
|
@ -13,26 +13,27 @@ module Reanimate.External
|
|||
)
|
||||
where
|
||||
|
||||
import Codec.Picture (PixelRGB8 (..))
|
||||
import Control.Monad (unless)
|
||||
import Crypto.Hash.SHA256 (hash)
|
||||
import Data.Aeson (decodeFileStrict)
|
||||
import qualified Data.ByteString as B (readFile)
|
||||
import Data.ByteString.Base64 (encode)
|
||||
import qualified Data.ByteString.Char8 as B8 (unpack)
|
||||
import Data.Char (isSpace, toLower)
|
||||
import Data.List (sort)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as M
|
||||
import Numeric (readHex)
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Misc (getReanimateCacheDirectory, withTempFile)
|
||||
import Reanimate.Raster (mkImage)
|
||||
import System.Directory (doesDirectoryExist, doesFileExist, findExecutable, getDirectoryContents)
|
||||
import System.FilePath (splitExtension, (<.>), (</>))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import System.Process (callProcess)
|
||||
import Codec.Picture (PixelRGB8 (..))
|
||||
import Control.Monad (unless)
|
||||
import Crypto.Hash.SHA256 (hash)
|
||||
import Data.Aeson (decodeFileStrict)
|
||||
import qualified Data.ByteString as B (readFile)
|
||||
import Data.ByteString.Base64 (encode)
|
||||
import qualified Data.ByteString.Char8 as B8 (unpack)
|
||||
import Data.Char (isSpace, toLower)
|
||||
import Data.List (sort)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as M
|
||||
import Numeric (readHex)
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Misc (getReanimateCacheDirectory, withTempFile)
|
||||
import Reanimate.Raster (mkImage)
|
||||
import System.Directory (doesDirectoryExist, doesFileExist, findExecutable,
|
||||
getDirectoryContents)
|
||||
import System.FilePath (splitExtension, (<.>), (</>))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import System.Process (callProcess)
|
||||
|
||||
-- | Resource address
|
||||
type URL = String
|
||||
|
|
@ -83,8 +84,8 @@ downloadFile url action = do
|
|||
mbCurl <- findExecutable "curl"
|
||||
mbWget <- findExecutable "wget"
|
||||
case (mbCurl, mbWget) of
|
||||
(Just curl, _) -> downloadFileCurl curl url action
|
||||
(_, Just wget) -> downloadFileWget wget url action
|
||||
(Just curl, _) -> downloadFileCurl curl url action
|
||||
(_, Just wget) -> downloadFileWget wget url action
|
||||
(Nothing, Nothing) -> error "curl/wget required to download files"
|
||||
|
||||
downloadFileCurl :: FilePath -> URL -> (FilePath -> IO a) -> IO a
|
||||
|
|
@ -151,7 +152,7 @@ simpleIcon = mkImage screenWidth screenHeight . simpleIconPath
|
|||
simpleIconColor :: String -> PixelRGB8
|
||||
simpleIconColor key =
|
||||
case M.lookup key simpleIconColors of
|
||||
Nothing -> error $ "Key not found in simple-icons dataset: " ++ show key
|
||||
Nothing -> error $ "Key not found in simple-icons dataset: " ++ show key
|
||||
Just pixel -> pixel
|
||||
|
||||
-- | Complete list of all Simple Icons.
|
||||
|
|
@ -168,7 +169,7 @@ simpleIconColors = unsafePerformIO $ do
|
|||
]
|
||||
case parsed of
|
||||
Nothing -> error "Invalid json in simpleIcons"
|
||||
Just v -> pure v
|
||||
Just v -> pure v
|
||||
where
|
||||
fromTitle :: String -> String
|
||||
fromTitle = replaceChars . map toLower
|
||||
|
|
@ -194,7 +195,7 @@ simpleIconColors = unsafePerformIO $ do
|
|||
where
|
||||
p offset = case readHex (take 2 $ drop offset hex) of
|
||||
[(num, "")] -> num
|
||||
_ -> error $ "Invalid hex: " ++ (take 2 $ drop offset hex)
|
||||
_ -> error $ "Invalid hex: " ++ (take 2 $ drop offset hex)
|
||||
|
||||
{-# NOINLINE simpleIcons #-}
|
||||
simpleIcons :: [String]
|
||||
|
|
@ -227,7 +228,7 @@ svgLogoPath key = unsafePerformIO $ do
|
|||
-- `svgLogo` "cassandra"
|
||||
-- @
|
||||
--
|
||||
-- <<docs/gifs/doc_svgLogo.gif>>
|
||||
-- <<docs/gifs/doc_svgLogo2.gif>>
|
||||
svgLogo :: String -> SVG
|
||||
svgLogo = mkImage screenWidth screenHeight . svgLogoPath
|
||||
|
||||
|
|
@ -238,4 +239,4 @@ svgLogos = unsafePerformIO $ do
|
|||
files <- getDirectoryContents svgLogosFolder
|
||||
return $
|
||||
sort
|
||||
[key | file <- files, let (key, ext) = splitExtension file, ext == ".svg"]
|
||||
[key | file <- files, let (key, ext) = splitExtension file, ext == ".svg"]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
-- |
|
||||
-- Copyright : Written by David Himmelstrup
|
||||
-- License : Unlicense
|
||||
|
|
@ -35,37 +34,25 @@ module Reanimate.LaTeX
|
|||
)
|
||||
where
|
||||
|
||||
import Control.Lens
|
||||
import qualified Data.ByteString as B
|
||||
import Data.Hashable
|
||||
import Data.Monoid
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import GHC.Generics (Generic)
|
||||
import Graphics.SvgTree
|
||||
( Tree,
|
||||
clipPathRef,
|
||||
clipRule,
|
||||
mapTree,
|
||||
parseSvgFile,
|
||||
strokeColor,
|
||||
pattern ClipPathTree,
|
||||
pattern None,
|
||||
)
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Cache
|
||||
import Reanimate.External
|
||||
import Reanimate.Misc
|
||||
import Reanimate.Parameters
|
||||
import Reanimate.Svg
|
||||
import System.FilePath
|
||||
( replaceExtension,
|
||||
takeFileName,
|
||||
(</>),
|
||||
)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import Control.Lens ((&), (.~))
|
||||
import qualified Data.ByteString as B
|
||||
import Data.Hashable (Hashable)
|
||||
import Data.Monoid (Last (Last))
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import qualified Data.Text.IO as T
|
||||
import GHC.Generics (Generic)
|
||||
import Graphics.SvgTree (Tree, clipPathRef, clipRule, mapTree, parseSvgFile,
|
||||
pattern ClipPathTree, pattern None, strokeColor)
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Cache (cacheDiskSvg, cacheMem)
|
||||
import Reanimate.External (zipArchive)
|
||||
import Reanimate.Misc (requireExecutable, runCmd, withTempDir, withTempFile)
|
||||
import Reanimate.Parameters (pNoExternals)
|
||||
import Reanimate.Svg
|
||||
import System.FilePath (replaceExtension, takeFileName, (</>))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
-- | TeX backends. They have different features and capabilities.
|
||||
data TexEngine = LaTeX | XeLaTeX | LuaLaTeX
|
||||
|
|
@ -73,8 +60,8 @@ data TexEngine = LaTeX | XeLaTeX | LuaLaTeX
|
|||
|
||||
-- | TeX configurations can load packages and set up environments for tex scripts.
|
||||
data TexConfig = TexConfig
|
||||
{ texConfigEngine :: TexEngine,
|
||||
texConfigHeaders :: [T.Text],
|
||||
{ texConfigEngine :: TexEngine,
|
||||
texConfigHeaders :: [T.Text],
|
||||
texConfigPostScript :: [T.Text]
|
||||
}
|
||||
deriving (Generic, Hashable, Read, Show, Eq, Ord)
|
||||
|
|
@ -86,8 +73,8 @@ latexCfg (TexConfig engine headers postscript) =
|
|||
where
|
||||
gen =
|
||||
case engine of
|
||||
LaTeX -> someTexWithHeaders engine "latex" "dvi" []
|
||||
XeLaTeX -> someTexWithHeaders engine "xelatex" "xdv" ["-no-pdf"]
|
||||
LaTeX -> someTexWithHeaders engine "latex" "dvi" []
|
||||
XeLaTeX -> someTexWithHeaders engine "xelatex" "xdv" ["-no-pdf"]
|
||||
LuaLaTeX -> someTexWithHeaders engine "lualatex" "pdf" []
|
||||
|
||||
-- | Invoke latex and import the result as an SVG object. SVG objects are
|
||||
|
|
@ -184,13 +171,13 @@ postprocess =
|
|||
|
||||
enginePostprocess :: TexEngine -> Tree -> Tree
|
||||
enginePostprocess LuaLaTeX svg = translate 0 (svgHeight svg) svg
|
||||
enginePostprocess _ svg = svg
|
||||
enginePostprocess _ svg = svg
|
||||
|
||||
removeClipPaths :: SVG -> SVG
|
||||
removeClipPaths = mapTree worker
|
||||
where
|
||||
worker ClipPathTree {} = None
|
||||
worker t = t & clipRule .~ Last Nothing & clipPathRef .~ Last Nothing
|
||||
worker t = t & clipRule .~ Last Nothing & clipPathRef .~ Last Nothing
|
||||
|
||||
-- executable, arguments, header, tex
|
||||
latexToSVG :: TexEngine -> String -> String -> [String] -> Text -> IO Tree
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ module Reanimate.Memo
|
|||
, memo
|
||||
) where
|
||||
|
||||
import Data.Dynamic
|
||||
import Data.IORef
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe
|
||||
import Data.Typeable
|
||||
import System.IO.Unsafe
|
||||
import System.Mem.StableName
|
||||
import Data.Dynamic (Dynamic, fromDynamic, toDyn)
|
||||
import Data.IORef (IORef, atomicModifyIORef', newIORef)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Typeable (Typeable, cast, typeOf)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import System.Mem.StableName (StableName, eqStableName, hashStableName, makeStableName)
|
||||
|
||||
data DynamicName = forall a. DynamicName !(StableName a) | forall a. (Eq a, Ord a, Typeable a) => DynamicKey a
|
||||
instance Eq DynamicName where
|
||||
|
|
|
|||
|
|
@ -10,46 +10,25 @@ module Reanimate.Misc
|
|||
)
|
||||
where
|
||||
|
||||
import Control.Concurrent
|
||||
import Control.Exception (catch, evaluate, finally, throw)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Foreign.C.Error
|
||||
import GHC.IO.Exception
|
||||
import System.Directory
|
||||
( XdgDirectory (XdgCache),
|
||||
copyFile,
|
||||
createDirectoryIfMissing,
|
||||
findExecutable,
|
||||
getXdgDirectory,
|
||||
removeFile,
|
||||
renameFile,
|
||||
)
|
||||
import System.FilePath ((<.>), (</>))
|
||||
import System.IO
|
||||
( hClose,
|
||||
hGetContents,
|
||||
hIsEOF,
|
||||
hPutStr,
|
||||
stderr,
|
||||
)
|
||||
import System.IO.Temp
|
||||
( withSystemTempDirectory,
|
||||
withSystemTempFile,
|
||||
)
|
||||
import System.Process
|
||||
( readProcessWithExitCode,
|
||||
runInteractiveProcess,
|
||||
showCommandForUser,
|
||||
terminateProcess,
|
||||
waitForProcess,
|
||||
)
|
||||
import Control.Concurrent (forkIO)
|
||||
import Control.Exception (catch, evaluate, finally, throw)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Foreign.C.Error (Errno (Errno), eXDEV)
|
||||
import GHC.IO.Exception (ExitCode (ExitFailure, ExitSuccess), IOException (ioe_errno))
|
||||
import System.Directory (XdgDirectory (XdgCache), copyFile, createDirectoryIfMissing,
|
||||
findExecutable, getXdgDirectory, removeFile, renameFile)
|
||||
import System.FilePath ((<.>), (</>))
|
||||
import System.IO (hClose, hGetContents, hIsEOF, hPutStr, stderr)
|
||||
import System.IO.Temp (withSystemTempDirectory, withSystemTempFile)
|
||||
import System.Process (readProcessWithExitCode, runInteractiveProcess,
|
||||
showCommandForUser, terminateProcess, waitForProcess)
|
||||
|
||||
requireExecutable :: String -> IO FilePath
|
||||
requireExecutable exec = do
|
||||
mbPath <- findExecutable exec
|
||||
case mbPath of
|
||||
Nothing -> error $ "Couldn't find executable: " ++ exec
|
||||
Nothing -> error $ "Couldn't find executable: " ++ exec
|
||||
Just path -> return path
|
||||
|
||||
runCmd :: FilePath -> [String] -> IO ()
|
||||
|
|
@ -96,7 +75,7 @@ runCmdLazy exec args handler = do
|
|||
_ <- evaluate (length errOutput)
|
||||
ret <- waitForProcess pid
|
||||
case ret of
|
||||
ExitSuccess -> return (Left "")
|
||||
ExitSuccess -> return (Left "")
|
||||
ExitFailure {} -> return (Left errOutput)
|
||||
else {-ExitFailure errMsg -> do
|
||||
return $ Left $
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ module Reanimate.Parameters
|
|||
, setRootDirectory
|
||||
) where
|
||||
|
||||
import System.IO.Unsafe
|
||||
import Data.IORef
|
||||
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
-- | Width of animation in pixels.
|
||||
type Width = Int
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ import qualified Data.Geometry.Point as Geo
|
|||
import qualified Data.Geometry.Polygon as Geo
|
||||
import Data.List (nub, partition, sortOn)
|
||||
import qualified Data.PlaneGraph as Geo
|
||||
import Data.Proxy
|
||||
import Data.Proxy (Proxy (Proxy))
|
||||
import qualified Data.Vector as V
|
||||
import Geom2D.CubicBezier.Linear (ClosedPath (..),
|
||||
CubicBezier (..),
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ module Reanimate.Povray
|
|||
, povrayExtreme'
|
||||
) where
|
||||
|
||||
import Data.Hashable
|
||||
import Data.Hashable (Hashable (hash))
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (Tree)
|
||||
import Reanimate.Cache
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Misc
|
||||
import Reanimate.Parameters
|
||||
import Reanimate.Raster
|
||||
import Reanimate.Svg.Constructors
|
||||
import Reanimate.Cache (cacheFile, encodeInt)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Misc (requireExecutable, runCmd)
|
||||
import Reanimate.Parameters (pNoExternals)
|
||||
import Reanimate.Raster (mkImage)
|
||||
import Reanimate.Svg.Constructors (mkText)
|
||||
import System.FilePath (replaceExtension, (<.>))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,36 +26,35 @@ module Reanimate.Raster
|
|||
)
|
||||
where
|
||||
|
||||
import Codec.Picture
|
||||
import Control.Lens ( (&)
|
||||
, (.~)
|
||||
)
|
||||
import Control.Monad
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Base64.Lazy as Base64
|
||||
import qualified Data.ByteString.Lazy.Char8 as LBS
|
||||
import Data.Hashable
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree ( Number(..)
|
||||
, defaultSvg
|
||||
, parseSvgFile
|
||||
)
|
||||
import qualified Graphics.SvgTree as Svg
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Cache
|
||||
import Reanimate.Driver.Magick
|
||||
import Reanimate.Misc
|
||||
import Reanimate.Render
|
||||
import Reanimate.Parameters
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Svg.Constructors
|
||||
import Reanimate.Svg.Unuse
|
||||
import System.Directory
|
||||
import System.FilePath
|
||||
import System.IO
|
||||
import System.IO.Temp
|
||||
import System.IO.Unsafe
|
||||
import Codec.Picture (DynamicImage, Image (imageHeight, imageWidth),
|
||||
PngSavable (encodePng), decodePng, dynamicMap,
|
||||
encodeDynamicPng, writePng)
|
||||
import Control.Lens ((&), (.~))
|
||||
import Control.Monad (unless)
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Base64.Lazy as Base64
|
||||
import qualified Data.ByteString.Lazy.Char8 as LBS
|
||||
import Data.Hashable (Hashable (hash))
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Graphics.SvgTree (Number (..), defaultSvg, parseSvgFile)
|
||||
import qualified Graphics.SvgTree as Svg
|
||||
import Reanimate.Animation (SVG, renderSvg)
|
||||
import Reanimate.Cache (cacheFile, encodeInt)
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Driver.Magick (magickCmd)
|
||||
import Reanimate.Misc (getReanimateCacheDirectory, renameOrCopyFile,
|
||||
requireExecutable, runCmd)
|
||||
import Reanimate.Parameters (Height, Raster (RasterNone), Width, pHeight,
|
||||
pNoExternals, pRaster, pRootDirectory, pWidth)
|
||||
import Reanimate.Render (applyRaster, requireRaster)
|
||||
import Reanimate.Svg.Constructors (flipYAxis, mkText, scaleXY)
|
||||
import Reanimate.Svg.Unuse (replaceUses, unbox, unboxFit)
|
||||
import System.Directory (copyFile, doesFileExist, removeFile)
|
||||
import System.FilePath (replaceExtension, takeExtension, (<.>), (</>))
|
||||
import System.IO (hClose)
|
||||
import System.IO.Temp (withSystemTempFile)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
-- | Load an external image. Width and height must be specified,
|
||||
-- ignoring the image's aspect ratio. The center of the image is
|
||||
|
|
|
|||
|
|
@ -26,22 +26,22 @@ module Reanimate.Render
|
|||
import Control.Concurrent
|
||||
import Control.Exception
|
||||
import Control.Monad (forM_, forever, unless, void, when)
|
||||
import Data.Either
|
||||
import Data.Function
|
||||
import Data.Either (isRight)
|
||||
import Data.Function (fix)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Time
|
||||
import Graphics.SvgTree (Number (..))
|
||||
import Numeric
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Driver.Check
|
||||
import Reanimate.Driver.Magick
|
||||
import Numeric (showFFloat)
|
||||
import Reanimate.Animation (Animation, duration, frameAt, renderSvg)
|
||||
import Reanimate.Driver.Check (hasInkscape, hasMagick, hasRSvg)
|
||||
import Reanimate.Driver.Magick (magickCmd)
|
||||
import Reanimate.Misc
|
||||
import Reanimate.Parameters
|
||||
import System.Console.ANSI.Codes
|
||||
import System.Exit
|
||||
import System.FileLock (withTryFileLock, SharedExclusive(..), unlockFile)
|
||||
import System.Directory
|
||||
import System.Console.ANSI.Codes (clearFromCursorToLineEndCode)
|
||||
import System.Directory (doesFileExist, removeFile)
|
||||
import System.Exit (ExitCode (ExitFailure), exitWith)
|
||||
import System.FileLock (SharedExclusive (..), unlockFile, withTryFileLock)
|
||||
import System.FilePath (replaceExtension, (<.>), (</>))
|
||||
import System.IO
|
||||
import Text.Printf (printf)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
module Reanimate.Scene.Core where
|
||||
|
||||
import Control.Monad.Fix (MonadFix (..))
|
||||
import Control.Monad.ST
|
||||
import Data.List
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg.Constructors
|
||||
import Control.Monad.Fix (MonadFix (..))
|
||||
import Control.Monad.ST (ST, runST)
|
||||
import Data.List (sortOn)
|
||||
import Reanimate.Animation (Animation, Duration, SVG, Time, mkAnimation)
|
||||
import Reanimate.Svg.Constructors (mkGroup)
|
||||
|
||||
-- | The ZIndex property specifies the stack order of sprites and animations. Elements
|
||||
-- with a higher ZIndex will be drawn on top of elements with a lower index.
|
||||
|
|
|
|||
|
|
@ -1,32 +1,26 @@
|
|||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
module Reanimate.Scene.Object where
|
||||
|
||||
import Linear.V2
|
||||
import Linear.Vector
|
||||
import Control.Lens
|
||||
import Control.Monad (forM_, void)
|
||||
import Control.Monad.State (State, execState)
|
||||
import Data.Monoid ( Last(getLast) )
|
||||
import Graphics.SvgTree
|
||||
( Number (..),
|
||||
Tree,
|
||||
strokeWidth,
|
||||
toUserUnit,
|
||||
pattern None,
|
||||
)
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Constants (defaultDPI, defaultStrokeWidth)
|
||||
import Reanimate.Ease (Signal, curveS, fromToS)
|
||||
import Reanimate.Effect ( applyE, fadeLineOutE, overEnding )
|
||||
import Reanimate.Math.Balloon ( balloon )
|
||||
import Reanimate.Morph.Common (morph)
|
||||
import Reanimate.Morph.Linear (linear)
|
||||
import Reanimate.Svg
|
||||
import Control.Lens
|
||||
import Control.Monad (forM_, void)
|
||||
import Control.Monad.State (State, execState)
|
||||
import Data.Monoid (Last (getLast))
|
||||
import Graphics.SvgTree (Number (..), Tree, pattern None, strokeWidth, toUserUnit)
|
||||
import Linear.V2 (R1 (_x), R2 (_y), V2 (..))
|
||||
import Linear.Vector (Additive (lerp), (^*))
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Constants (defaultDPI, defaultStrokeWidth)
|
||||
import Reanimate.Ease (Signal, curveS, fromToS)
|
||||
import Reanimate.Effect (applyE, fadeLineOutE, overEnding)
|
||||
import Reanimate.Math.Balloon (balloon)
|
||||
import Reanimate.Morph.Common (morph)
|
||||
import Reanimate.Morph.Linear (linear)
|
||||
import Reanimate.Svg
|
||||
|
||||
import Reanimate.Scene.Core
|
||||
import Reanimate.Scene.Sprite
|
||||
import Reanimate.Scene.Var
|
||||
import Reanimate.Scene.Core (Scene, fork, scene, wait)
|
||||
import Reanimate.Scene.Sprite (Sprite, newSprite, newSpriteA', play, spriteModify, unVar)
|
||||
import Reanimate.Scene.Var (Var, modifyVar, newVar, readVar, tweenVar)
|
||||
|
||||
-------------------------------------------------------
|
||||
-- Objects
|
||||
|
|
@ -43,23 +37,23 @@ instance Renderable Tree where
|
|||
-- change over time.
|
||||
data Object s a = Object
|
||||
{ objectSprite :: Sprite s,
|
||||
objectData :: Var s (ObjectData a)
|
||||
objectData :: Var s (ObjectData a)
|
||||
}
|
||||
|
||||
-- | Container for object properties.
|
||||
data ObjectData a = ObjectData
|
||||
{ _oTranslate :: V2 Double,
|
||||
_oValueRef :: a,
|
||||
_oSVG :: SVG,
|
||||
_oContext :: SVG -> SVG,
|
||||
{ _oTranslate :: V2 Double,
|
||||
_oValueRef :: a,
|
||||
_oSVG :: SVG,
|
||||
_oContext :: SVG -> SVG,
|
||||
-- | Top, right, bottom, left
|
||||
_oMargin :: (Double, Double, Double, Double),
|
||||
_oBB :: (Double, Double, Double, Double),
|
||||
_oOpacity :: Double,
|
||||
_oShown :: Bool,
|
||||
_oZIndex :: Int,
|
||||
_oEasing :: Signal,
|
||||
_oScale :: Double,
|
||||
_oMargin :: (Double, Double, Double, Double),
|
||||
_oBB :: (Double, Double, Double, Double),
|
||||
_oOpacity :: Double,
|
||||
_oShown :: Bool,
|
||||
_oZIndex :: Int,
|
||||
_oEasing :: Signal,
|
||||
_oScale :: Double,
|
||||
_oScaleOrigin :: V2 Double
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +502,7 @@ oDraw = oStagger $ \svg -> scene $
|
|||
let sWidth =
|
||||
case toUserUnit defaultDPI <$> getLast (attr ^. strokeWidth) of
|
||||
Just (Num d) -> max defaultStrokeWidth d
|
||||
_ -> defaultStrokeWidth
|
||||
_ -> defaultStrokeWidth
|
||||
-- wait 1
|
||||
play $
|
||||
mapA ctx $
|
||||
|
|
|
|||
|
|
@ -1,39 +1,21 @@
|
|||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
|
||||
module Reanimate.Scene.Sprite where
|
||||
|
||||
import Control.Monad (void)
|
||||
import Control.Monad.ST (ST)
|
||||
import Data.Bifunctor (Bifunctor (first))
|
||||
import Data.STRef (STRef, modifySTRef, newSTRef, readSTRef)
|
||||
import Graphics.SvgTree
|
||||
( pattern None,
|
||||
)
|
||||
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,
|
||||
wait,
|
||||
)
|
||||
import Reanimate.Scene.Var (unpackVar, Var (..), newVar, readVar)
|
||||
import Reanimate.Transition (Transition, overlapT)
|
||||
import Control.Monad (void)
|
||||
import Control.Monad.ST (ST)
|
||||
import Data.Bifunctor (Bifunctor (first))
|
||||
import Data.STRef (STRef, modifySTRef, newSTRef, readSTRef)
|
||||
import Graphics.SvgTree (pattern None)
|
||||
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,
|
||||
wait)
|
||||
import Reanimate.Scene.Var (Var (..), newVar, readVar, unpackVar)
|
||||
import Reanimate.Transition (Transition, overlapT)
|
||||
|
||||
-- | Create and render a variable. The rendering will be born at the current timestamp
|
||||
-- and will persist until the end of the scene.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
module Reanimate.Scene.Var where
|
||||
|
||||
import Control.Monad.ST (ST)
|
||||
import qualified Data.Map as M
|
||||
import Data.STRef
|
||||
import Reanimate.Animation (Duration, Time)
|
||||
import Reanimate.Scene.Core (Scene, liftST, queryNow, wait)
|
||||
import Control.Monad.ST (ST)
|
||||
import qualified Data.Map as M
|
||||
import Data.STRef (STRef, modifySTRef, newSTRef, readSTRef)
|
||||
import Reanimate.Animation (Duration, Time)
|
||||
import Reanimate.Scene.Core (Scene, liftST, queryNow, wait)
|
||||
|
||||
-- | Time dependent variable.
|
||||
newtype Var s a = Var (STRef s (VarData a))
|
||||
|
|
@ -18,9 +18,9 @@ newtype Var s a = Var (STRef s (VarData a))
|
|||
-- it shouldn't be Nothing again.
|
||||
-- 3. isNothing (evarLastTime var) => M.null (evarTimeline var)
|
||||
data VarData a = VarData
|
||||
{ evarDefault :: a,
|
||||
evarTimeline :: Timeline a,
|
||||
evarLastTime :: Maybe Time,
|
||||
{ evarDefault :: a,
|
||||
evarTimeline :: Timeline a,
|
||||
evarLastTime :: Maybe Time,
|
||||
evarLastValue :: a
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ modifyVarData now fn var =
|
|||
let before = keepBefore now var
|
||||
after = keepFrom now var
|
||||
timeline = flip M.map (evarTimeline after) $ \case
|
||||
StaticValue s -> StaticValue $ fn s
|
||||
StaticValue s -> StaticValue $ fn s
|
||||
TweenValue dur f -> TweenValue dur $ \a t -> fn (f a t)
|
||||
in after {evarTimeline = timeline, evarLastValue = fn $ evarLastValue after} `elseVar` before
|
||||
|
||||
|
|
@ -165,5 +165,5 @@ keepBefore nd var@VarData {..} =
|
|||
_ -> timeline'
|
||||
lastTime = case lastModifier of
|
||||
Just (t, TweenValue dur _) -> Just $ min nd (t + dur)
|
||||
_ -> min nd <$> evarLastTime
|
||||
_ -> min nd <$> evarLastTime
|
||||
in VarData evarDefault timeline'' lastTime (maybe evarDefault (readVarData var) lastTime)
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ module Reanimate.Svg
|
|||
, module Reanimate.Svg.Unuse
|
||||
) where
|
||||
|
||||
import Control.Lens ((%~), (&), (.~), (^.), (?~))
|
||||
import Control.Lens ((%~), (&), (.~), (?~), (^.))
|
||||
import Control.Monad.State
|
||||
import Graphics.SvgTree
|
||||
import Linear.V2 hiding (angle)
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Animation (SVG)
|
||||
import Linear.V2 (V2 (V2))
|
||||
import Reanimate.Animation (SVG)
|
||||
import Reanimate.Constants (defaultDPI)
|
||||
import Reanimate.Svg.BoundingBox (boundingBox, svgHeight, svgWidth)
|
||||
import Reanimate.Svg.Constructors
|
||||
import Reanimate.Svg.LineCommand
|
||||
import Reanimate.Svg.BoundingBox
|
||||
import Reanimate.Svg.Unuse
|
||||
import qualified Reanimate.Transform as Transform
|
||||
import Reanimate.Svg.Unuse (embedDocument, replaceUses, unbox, unboxFit)
|
||||
import qualified Reanimate.Transform as Transform
|
||||
|
||||
-- | Remove transformations (such as translations, rotations, scaling)
|
||||
-- and apply them directly to the SVG nodes. Note, this function
|
||||
|
|
@ -343,9 +343,9 @@ mapSvgLines fn = mapSvgPaths (lineToPath . fn . toLineCommands)
|
|||
mapSvgPoints :: (RPoint -> RPoint) -> SVG -> SVG
|
||||
mapSvgPoints fn = mapSvgLines (map worker)
|
||||
where
|
||||
worker (LineMove p) = LineMove (fn p)
|
||||
worker (LineMove p) = LineMove (fn p)
|
||||
worker (LineBezier ps) = LineBezier (map fn ps)
|
||||
worker (LineEnd p) = LineEnd (fn p)
|
||||
worker (LineEnd p) = LineEnd (fn p)
|
||||
|
||||
-- | Convert coordinate system from degrees to radians.
|
||||
svgPointsToRadians :: SVG -> SVG
|
||||
|
|
|
|||
|
|
@ -11,18 +11,18 @@ module Reanimate.Svg.BoundingBox
|
|||
, svgWidth
|
||||
) where
|
||||
|
||||
import Control.Arrow ((***))
|
||||
import Control.Lens ((^.))
|
||||
import Data.List
|
||||
import Data.Maybe (mapMaybe)
|
||||
import qualified Data.Vector.Unboxed as V
|
||||
import Control.Arrow ((***))
|
||||
import Control.Lens ((^.))
|
||||
import Data.List (foldl')
|
||||
import Data.Maybe (mapMaybe)
|
||||
import qualified Data.Vector.Unboxed as V
|
||||
import qualified Geom2D.CubicBezier.Linear as Bezier
|
||||
import Graphics.SvgTree
|
||||
import Linear.V2 hiding (angle)
|
||||
import Linear.Vector
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Svg.LineCommand
|
||||
import qualified Reanimate.Transform as Transform
|
||||
import Linear.V2 (V2 (V2))
|
||||
import Linear.Vector (Additive (zero))
|
||||
import Reanimate.Constants (defaultDPI)
|
||||
import Reanimate.Svg.LineCommand (LineCommand (..), toLineCommands)
|
||||
import qualified Reanimate.Transform as Transform
|
||||
|
||||
-- | Return bounding box of SVG tree.
|
||||
-- The four numbers returned are (minimal X-coordinate, minimal Y-coordinate, width, height)
|
||||
|
|
@ -114,7 +114,7 @@ svgBoundingPoints t = map (Transform.transformPoint m) $
|
|||
rnum = circ ^. circleRadius
|
||||
in case mapMaybe unpackNumber [xnum, ynum, rnum] of
|
||||
[x, y, r] -> [ V2 (x + r * cos angle) (y + r * sin angle) | angle <- [0, pi/10 .. 2 * pi]]
|
||||
_ -> []
|
||||
_ -> []
|
||||
|
||||
ellipseBoundingPoints e =
|
||||
let (xnum,ynum) = e ^. ellipseCenter
|
||||
|
|
|
|||
|
|
@ -63,11 +63,11 @@ import Data.Attoparsec.Text (parseOnly)
|
|||
import qualified Data.Map as Map
|
||||
import qualified Data.Text as T
|
||||
import Graphics.SvgTree
|
||||
import Graphics.SvgTree.NamedColors
|
||||
import Graphics.SvgTree.PathParser
|
||||
import Linear.V2 hiding (angle)
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Svg.BoundingBox
|
||||
import Graphics.SvgTree.NamedColors (svgNamedColors)
|
||||
import Graphics.SvgTree.PathParser (pathParser)
|
||||
import Linear.V2 (V2 (V2))
|
||||
import Reanimate.Constants (screenHeight, screenWidth)
|
||||
import Reanimate.Svg.BoundingBox (boundingBox)
|
||||
|
||||
-- | Apply list of transformations to given image.
|
||||
withTransformations :: [Transformation] -> Tree -> Tree
|
||||
|
|
|
|||
|
|
@ -15,17 +15,20 @@ module Reanimate.Svg.LineCommand
|
|||
)
|
||||
where
|
||||
|
||||
import Control.Lens ((%~), (&), (.~))
|
||||
import Control.Monad.Fix
|
||||
import Control.Monad.State
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import qualified Data.Vector.Unboxed as V
|
||||
import Control.Lens ((%~), (&), (.~))
|
||||
import Control.Monad.Fix (MonadFix (mfix))
|
||||
import Control.Monad.State (MonadState (get, put), State, evalState, forM, gets,
|
||||
modify)
|
||||
import Data.Functor (($>))
|
||||
import Data.Maybe (mapMaybe)
|
||||
import qualified Data.Vector.Unboxed as V
|
||||
import qualified Geom2D.CubicBezier.Linear as Bezier
|
||||
import Graphics.SvgTree
|
||||
import Linear.Metric
|
||||
import Linear.V2 hiding (angle)
|
||||
import Linear.Vector
|
||||
import Graphics.SvgTree (Coord, Origin (OriginAbsolute, OriginRelative),
|
||||
PathCommand (..), RPoint, Tree, mapTree, pathDefinition,
|
||||
pattern PathTree)
|
||||
import Linear.Metric (Metric (distance))
|
||||
import Linear.V2 (R1 (_x), R2 (_y), V2 (V2))
|
||||
import Linear.Vector (Additive (lerp, zero))
|
||||
|
||||
-- | Line command monad used for keeping track of the current location.
|
||||
type CmdM a = State RPoint a
|
||||
|
|
@ -42,13 +45,13 @@ data LineCommand
|
|||
lineToPath :: [LineCommand] -> [PathCommand]
|
||||
lineToPath = map worker
|
||||
where
|
||||
worker (LineMove p) = MoveTo OriginAbsolute [p]
|
||||
worker (LineMove p) = MoveTo OriginAbsolute [p]
|
||||
-- worker (LineDraw p) = LineTo OriginAbsolute [p]
|
||||
worker (LineBezier [a, b, c]) = CurveTo OriginAbsolute [(a, b, c)]
|
||||
worker (LineBezier [a, b]) = QuadraticBezier OriginAbsolute [(a, b)]
|
||||
worker (LineBezier [a]) = LineTo OriginAbsolute [a]
|
||||
worker LineBezier {} = error "Reanimate.Svg.lineToPath: invalid bezier curve"
|
||||
worker LineEnd {} = EndPath
|
||||
worker (LineBezier [a, b]) = QuadraticBezier OriginAbsolute [(a, b)]
|
||||
worker (LineBezier [a]) = LineTo OriginAbsolute [a]
|
||||
worker LineBezier {} = error "Reanimate.Svg.lineToPath: invalid bezier curve"
|
||||
worker LineEnd {} = EndPath
|
||||
|
||||
-- | Using @n@ control points, approximate the path of the curves.
|
||||
lineToPoints :: Int -> [LineCommand] -> [RPoint]
|
||||
|
|
@ -56,9 +59,9 @@ lineToPoints nPoints cmds =
|
|||
mapMaybe lineEnd lineSegments
|
||||
where
|
||||
lineSegments = [partialLine (fromIntegral n / fromIntegral nPoints) cmds | n <- [0 .. nPoints -1]]
|
||||
lineEnd [] = Nothing
|
||||
lineEnd [] = Nothing
|
||||
lineEnd [LineBezier pts] = Just (last pts)
|
||||
lineEnd (_ : xs) = lineEnd xs
|
||||
lineEnd (_ : xs) = lineEnd xs
|
||||
|
||||
partialLine :: Double -> [LineCommand] -> [LineCommand]
|
||||
partialLine alpha cmds = evalState (worker 0 cmds) zero
|
||||
|
|
@ -78,9 +81,9 @@ adjustLineLength :: Double -> RPoint -> LineCommand -> LineCommand
|
|||
adjustLineLength alpha from cmd =
|
||||
case cmd of
|
||||
LineBezier points -> LineBezier $ drop 1 $ partialBezierPoints (from : points) 0 alpha
|
||||
LineMove p -> LineMove p
|
||||
LineMove p -> LineMove p
|
||||
-- LineDraw t -> LineDraw (lerp alpha t from)
|
||||
LineEnd p -> LineBezier [lerp alpha p from]
|
||||
LineEnd p -> LineBezier [lerp alpha p from]
|
||||
|
||||
-- | Estimated length of all segments in a line.
|
||||
lineLength :: LineCommand -> CmdM Double
|
||||
|
|
@ -101,10 +104,10 @@ lineLength cmd =
|
|||
rpointsToBezier :: [RPoint] -> Bezier.CubicBezier Double
|
||||
rpointsToBezier lst =
|
||||
case lst of
|
||||
[a, b] -> Bezier.CubicBezier a a b b
|
||||
[a, b, c] -> Bezier.quadToCubic (Bezier.QuadBezier a b c)
|
||||
[a, b] -> Bezier.CubicBezier a a b b
|
||||
[a, b, c] -> Bezier.quadToCubic (Bezier.QuadBezier a b c)
|
||||
[a, b, c, d] -> Bezier.CubicBezier a b c d
|
||||
_ -> error $ "rpointsToBezier: Invalid list of points: " ++ show lst
|
||||
_ -> error $ "rpointsToBezier: Invalid list of points: " ++ show lst
|
||||
|
||||
-- | Convert from path commands to line commands.
|
||||
toLineCommands :: [PathCommand] -> [LineCommand]
|
||||
|
|
@ -116,12 +119,12 @@ toLineCommands ps = evalState (worker zero Nothing ps) zero
|
|||
let startPos' =
|
||||
case lcmds of
|
||||
[LineMove pos] -> pos
|
||||
_ -> startPos
|
||||
_ -> startPos
|
||||
(lcmds ++) <$> worker startPos' (cmdToControlPoint $ last lcmds) cmds
|
||||
|
||||
cmdToControlPoint :: LineCommand -> Maybe RPoint
|
||||
cmdToControlPoint (LineBezier points) = Just (last (init points))
|
||||
cmdToControlPoint _ = Nothing
|
||||
cmdToControlPoint _ = Nothing
|
||||
|
||||
mkStraightLine :: RPoint -> LineCommand
|
||||
mkStraightLine p = LineBezier [p]
|
||||
|
|
@ -180,7 +183,7 @@ toLineCommand startPos mbPrevControlPt cmd =
|
|||
adjustPosition OriginRelative p = modify (+ p)
|
||||
adjustPosition OriginAbsolute p = put p
|
||||
makeAbsolute OriginAbsolute _from p = p
|
||||
makeAbsolute OriginRelative from p = from + p
|
||||
makeAbsolute OriginRelative from p = from + p
|
||||
|
||||
calculateVectorAngle :: Double -> Double -> Double -> Double -> Double
|
||||
calculateVectorAngle ux uy vx vy
|
||||
|
|
|
|||
|
|
@ -14,18 +14,19 @@ module Reanimate.Svg.Unuse
|
|||
|
||||
import Control.Lens ((%~), (&), (.~), (?~), (^.))
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Graphics.SvgTree
|
||||
import Reanimate.Constants
|
||||
import Reanimate.Svg.Constructors
|
||||
import Reanimate.Constants (defaultDPI, screenHeight, screenWidth)
|
||||
import Reanimate.Svg.Constructors (flipYAxis, mkGroup, scaleXY, translate,
|
||||
withFillOpacity, withStrokeWidth)
|
||||
|
||||
-- | Replace all @<use>@ nodes with their definition.
|
||||
replaceUses :: Document -> Document
|
||||
replaceUses doc = doc & documentElements %~ map (mapTree replace)
|
||||
where
|
||||
replaceDefinition PathTree{} = None
|
||||
replaceDefinition PathTree{} = None
|
||||
replaceDefinition SymbolTree{} = None
|
||||
replaceDefinition t = t
|
||||
replaceDefinition t = t
|
||||
|
||||
replace t@DefinitionTree{} = mapTree replaceDefinition t
|
||||
replace (UseTree _ Just{}) = error "replaceUses: subtree in use?"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{-# LANGUAGE BangPatterns #-}
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
{-|
|
||||
2D transformation matrices capable of translating, scaling,
|
||||
rotating, and skewing.
|
||||
|
|
@ -11,12 +11,12 @@ module Reanimate.Transform
|
|||
) where
|
||||
|
||||
-- XXX: Use Linear.Matrix instead of Data.Matrix to drop the 'matrix' dependency.
|
||||
import Data.List
|
||||
import Data.Matrix (Matrix)
|
||||
import qualified Data.Matrix as M
|
||||
import Data.Maybe
|
||||
import Graphics.SvgTree
|
||||
import Linear.V2
|
||||
import Data.List (foldl')
|
||||
import Data.Matrix (Matrix)
|
||||
import qualified Data.Matrix as M
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Graphics.SvgTree (Coord, RPoint, Transformation (..))
|
||||
import Linear.V2 (V2 (V2))
|
||||
|
||||
-- | Identity matrix.
|
||||
--
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ module Reanimate.Transition
|
|||
, fadeT
|
||||
) where
|
||||
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Ease
|
||||
import Reanimate.Effect
|
||||
import Reanimate.Animation (Animation, dropA, duration, lastA, parA, pause, seqA, signalA,
|
||||
takeA)
|
||||
import Reanimate.Ease (Signal)
|
||||
import Reanimate.Effect (Effect, applyE, fadeInE, fadeOutE)
|
||||
|
||||
-- | A transition transforms one animation into another.
|
||||
type Transition = Animation -> Animation -> Animation
|
||||
|
|
@ -66,7 +67,7 @@ effectT eA eB a b = applyE eA a `parA` applyE eB b
|
|||
--
|
||||
-- <<docs/gifs/doc_chainT.gif>>
|
||||
chainT :: Transition -> [Animation] -> Animation
|
||||
chainT _ [] = pause 0
|
||||
chainT _ [] = pause 0
|
||||
chainT t (x:xs) = foldl t x xs
|
||||
|
||||
-- | Fade out left-hand-side animation while fading in right-hand-side animation.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
{-|
|
||||
Reanimate can automatically synchronize animations to your voice if you have
|
||||
a transcript and an audio recording. This works with the help of Gentle
|
||||
|
|
@ -20,27 +20,27 @@ module Reanimate.Voice
|
|||
)
|
||||
where
|
||||
|
||||
import Control.Monad (forM_)
|
||||
import Data.Aeson
|
||||
import Data.Char
|
||||
import System.IO.Unsafe ( unsafePerformIO )
|
||||
import System.Directory
|
||||
import System.FilePath
|
||||
import System.Process
|
||||
import System.Exit
|
||||
import Control.Monad
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import qualified Data.Map as Map
|
||||
import Data.Map ( Map )
|
||||
import Data.Text ( Text )
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Reanimate.Misc
|
||||
import Reanimate.LaTeX
|
||||
import Reanimate.Scene
|
||||
import Reanimate.Animation
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Constants
|
||||
import Data.Char (isAlphaNum, isSpace)
|
||||
import Data.List (sortOn)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe (listToMaybe)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Reanimate.Animation (SVG, staticFrame)
|
||||
import Reanimate.Constants (defaultStrokeWidth, screenHeight, screenWidth)
|
||||
import Reanimate.LaTeX (latex, latexChunks)
|
||||
import Reanimate.Misc (withTempFile)
|
||||
import Reanimate.Scene (Scene, play, waitUntil)
|
||||
import Reanimate.Svg (mkGroup, scale, translate, withStrokeColor, withStrokeWidth)
|
||||
import System.Directory (doesFileExist)
|
||||
import System.Exit (ExitCode (ExitFailure, ExitSuccess))
|
||||
import System.FilePath (replaceExtension)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import System.Process (rawSystem, showCommandForUser)
|
||||
|
||||
-- | Aligned transcript. Contains the transcript text as well as
|
||||
-- timing data for each word.
|
||||
|
|
|
|||
Loading…
Reference in a new issue