mirror of
https://github.com/reanimate/reanimate.git
synced 2026-09-10 23:52:22 +00:00
Set viewbox to 16 by 9. (#11)
* Set viewbox to 16 by 9. * Update examples and fix process termination bug in driver. * Add module for constants. Former-commit-id: 1c77569e771455e674485e2fc58ee57e7df5f3c5
This commit is contained in:
parent
336a011aaa
commit
89905ebe39
24 changed files with 167 additions and 121 deletions
|
|
@ -11,14 +11,15 @@ import Reanimate.LaTeX
|
|||
import Reanimate.Monad
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Signal
|
||||
import Reanimate.Constants
|
||||
|
||||
main :: IO ()
|
||||
main = reanimate bbox
|
||||
|
||||
bbox :: Animation
|
||||
bbox = bg `sim`
|
||||
mapA (translate (-50) 0) bbox1 `sim`
|
||||
mapA (translate 50 0) bbox2
|
||||
mapA (translate (-screenWidth/4) 0) bbox1 `sim`
|
||||
mapA (translate (screenWidth/4) 0) bbox2
|
||||
where
|
||||
bg = mkAnimation 0 $ emit $ mkBackground "black"
|
||||
|
||||
|
|
@ -29,14 +30,15 @@ bbox1 = mkAnimation 5 $ do
|
|||
[ mkBoundingBox $ rotate (360*s) svg
|
||||
, withFillColor "white" $ rotate (360*s) svg ]
|
||||
where
|
||||
svg = scale 3 $ center $ latexAlign "\\sum_{k=1}^\\infty"
|
||||
svg = scale 2 $ center $ latexAlign "\\sum_{k=1}^\\infty"
|
||||
|
||||
bbox2 :: Animation
|
||||
bbox2 = autoReverse $ mkAnimation 2.5 $ do
|
||||
s <- getSignal signalLinear
|
||||
emit $ mkGroup
|
||||
[ mkBoundingBox $ partialSvg s heartShape
|
||||
, withStrokeColor "white" $ withFillOpacity 0 $ partialSvg s heartShape ]
|
||||
, withStrokeColor "white" $ withFillOpacity 0 $
|
||||
partialSvg s heartShape ]
|
||||
|
||||
mkBoundingBox :: Tree -> Tree
|
||||
mkBoundingBox svg = withStrokeColor "red" $ withFillOpacity 0 $
|
||||
|
|
@ -45,7 +47,7 @@ mkBoundingBox svg = withStrokeColor "red" $ withFillOpacity 0 $
|
|||
where
|
||||
(x, y, w, h) = boundingBox svg
|
||||
|
||||
heartShape =
|
||||
heartShape = lowerTransformations $ scaleXY 1 (-1) $ scale 0.1 $
|
||||
center $ rotateAroundCenter 225 $ mkPathString
|
||||
"M0.0,40.0 v-40.0 h40.0\
|
||||
\a20.0 20.0 90.0 0 1 0.0,40.0\
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import Reanimate.Monad
|
|||
import Reanimate.Raster
|
||||
import Reanimate.Signal
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Constants
|
||||
|
||||
-- Cycle the animation if we want to upload it to youtube.
|
||||
youtube :: Animation -> Animation
|
||||
|
|
@ -29,38 +30,48 @@ youtube = id
|
|||
main :: IO ()
|
||||
main = reanimate $ youtube $ pauseAtEnd 2 $ autoReverse $ pauseAtEnd 2 $ mkAnimation 5 $ do
|
||||
s <- getSignal $ signalCurve 2
|
||||
let scaleWidth = 50
|
||||
nubWidth = 2
|
||||
let scaleWidth = screenWidth * 0.5
|
||||
nubWidth = 0.2
|
||||
textYOffset = 0.2
|
||||
emit $ mkGroup
|
||||
[ mkBackground "black"
|
||||
, translate 0 (-80) $ withFillColor "white" $ mkGroup
|
||||
, translate 0 (screenHeight/2*0.85) $ withFillColor "white" $ mkGroup
|
||||
[ translate (scaleWidth*s - scaleWidth/2) 0 $
|
||||
withFillColor "white" $ mkCircle (Num nubWidth)
|
||||
, withStrokeColor "white" $ withStrokeWidth (Num 0.5) $
|
||||
mkLine (Num $ -(scaleWidth-nubWidth)/2,Num 0) (Num $ (scaleWidth-nubWidth)/2, Num 0)
|
||||
, translate (-scaleWidth/2-20) (-5) $ centerX $ latex "Color"
|
||||
, translate (scaleWidth/2+27) (-5) $ centerX $ latex "Greyscale"
|
||||
, withStrokeColor "white" $ withStrokeWidth (Num 0.05) $
|
||||
mkLine (Num $ -(scaleWidth-nubWidth)/2,Num 0)
|
||||
(Num $ (scaleWidth-nubWidth)/2, Num 0)
|
||||
, translate (-scaleWidth/2-1.0) textYOffset $
|
||||
scale 0.5 $ centerX $ latex "Color"
|
||||
, translate (scaleWidth/2+1.5) textYOffset $
|
||||
scale 0.5 $ centerX $ latex "Greyscale"
|
||||
]
|
||||
, translate (-80) (-50) $ mkOutline "viridis" (dimmer s . viridis)
|
||||
, translate (-80) (-20) $ mkOutline "inferno" (dimmer s . inferno)
|
||||
, translate (-80) (10) $ mkOutline "cividis" (dimmer s . cividis)
|
||||
, translate (-80) (40) $ mkOutline "jet" (dimmer s . jet)
|
||||
, translate (-80) (70) $ mkOutline "turbo" (dimmer s . turbo)
|
||||
, translate (-columnX) (rowInit-rowStep*0) $ mkOutline "viridis" (dimmer s . viridis)
|
||||
, translate (-columnX) (rowInit-rowStep*1) $ mkOutline "inferno" (dimmer s . inferno)
|
||||
, translate (-columnX) (rowInit-rowStep*2) $ mkOutline "cividis" (dimmer s . cividis)
|
||||
, translate (-columnX) (rowInit-rowStep*3) $ mkOutline "jet" (dimmer s . jet)
|
||||
, translate (-columnX) (rowInit-rowStep*4) $ mkOutline "turbo" (dimmer s . turbo)
|
||||
|
||||
, translate (80) (-50) $ mkOutline "magma" (dimmer s . magma)
|
||||
, translate (80) (-20) $ mkOutline "plasma" (dimmer s . plasma)
|
||||
, translate (80) (10) $ mkOutline "sinebow" (dimmer s . sinebow)
|
||||
, translate (80) (40) $ mkOutline "hsv" (dimmer s . hsv)
|
||||
, translate (80) (70) $ mkOutline "parula" (dimmer s . parula)
|
||||
, translate (columnX) (rowInit-rowStep*0) $ mkOutline "magma" (dimmer s . magma)
|
||||
, translate (columnX) (rowInit-rowStep*1) $ mkOutline "plasma" (dimmer s . plasma)
|
||||
, translate (columnX) (rowInit-rowStep*2) $ mkOutline "sinebow" (dimmer s . sinebow)
|
||||
, translate (columnX) (rowInit-rowStep*3) $ mkOutline "hsv" (dimmer s . hsv)
|
||||
, translate (columnX) (rowInit-rowStep*4) $ mkOutline "parula" (dimmer s . parula)
|
||||
]
|
||||
where
|
||||
rowInit = 2.2
|
||||
rowStep = 1.2
|
||||
columnX = screenWidth/4
|
||||
|
||||
mkOutline label f =
|
||||
mkGroup
|
||||
[ center $ withFillColor "grey" $ mkRect (Num 151) (Num 11)
|
||||
, scaleToSize 150 10 $ mkColorMap f
|
||||
, translate (-75) (-10) $ centerY $ withFillColor "white" $
|
||||
latex label
|
||||
[ center $ withFillColor "grey" $ mkRect (Num $ scaleWidth+0.05) (Num $ scaleHeight+0.05)
|
||||
, scaleToSize scaleWidth scaleHeight $ mkColorMap f
|
||||
, translate (-scaleWidth/2) (0.5) $ centerY $ withFillColor "white" $
|
||||
scale 0.5 $ latex label
|
||||
]
|
||||
scaleWidth = screenWidth/8*3
|
||||
scaleHeight = screenHeight/20
|
||||
|
||||
mkColorMap :: (Double -> PixelRGB8) -> Tree
|
||||
mkColorMap f = center $ embedImage img
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import Reanimate.LaTeX (latex)
|
|||
import Reanimate.Monad
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Signal
|
||||
import Reanimate.Constants
|
||||
|
||||
waveMultiplier :: Int
|
||||
-- waveMultiplier = 1 -- Sawtooth wave
|
||||
|
|
@ -29,30 +30,30 @@ main = reanimate $
|
|||
fourierAnimation 50 `before`
|
||||
fourierAnimation 100
|
||||
|
||||
sWidth = 0.5
|
||||
sWidth = 0.02
|
||||
|
||||
fourierAnimation :: Int -> Animation
|
||||
fourierAnimation nCircles = repeatAnimation 2 $ mkAnimation 3 $ do
|
||||
emit $ mkBackground "black"
|
||||
phi <- getSignal $ signalFromTo 0 (2*pi) signalLinear
|
||||
mapF (translate (-100) 0) $ do
|
||||
mapF (translate (-screenWidth/4) 0) $ do
|
||||
drawNCircles nCircles phi
|
||||
emit $ withStrokeColor "white" $
|
||||
withStrokeWidth (Num sWidth) $
|
||||
withFillOpacity 0 $
|
||||
translate 80 0 $
|
||||
translate (screenWidth/4) 0 $
|
||||
mkCirclePath nCircles phi
|
||||
emit $ withStrokeWidth (Num sWidth) $
|
||||
withFillColor "white" $
|
||||
translate (-140) (-80) $
|
||||
scale 2 $ latex $ T.pack $ "Circles: " ++ show nCircles
|
||||
translate (-screenWidth/8*3) (screenHeight/8*3) $
|
||||
latex $ T.pack $ "Circles: " ++ show nCircles
|
||||
|
||||
drawNCircles totalCircles phi = do
|
||||
worker circles
|
||||
let x :+ y = sum circles
|
||||
emit $ withStrokeWidth (Num sWidth) $
|
||||
withStrokeColor "white" $
|
||||
mkLine (Num x, Num y) (Num 80, Num y)
|
||||
mkLine (Num x, Num y) (Num (screenWidth/4), Num y)
|
||||
where
|
||||
circles = [ nthCircle n phi | n <- [0..totalCircles-1] ]
|
||||
worker [] = return ()
|
||||
|
|
@ -70,7 +71,7 @@ drawNCircles totalCircles phi = do
|
|||
mkLine (Num 0, Num 0) (Num x, Num y)
|
||||
|
||||
mkCirclePath nCircles phiOffset = mkLinePath $ take 2000 $
|
||||
zip [ 50 * i/granularity | i <- [0..]]
|
||||
zip [ 2 * i/granularity | i <- [0..]]
|
||||
$ drop (round $ (1-phiOffset/(2*pi)) * granularity) $
|
||||
cycle $ [ fourierYValue nCircles phi
|
||||
| x <- reverse [1..granularity]
|
||||
|
|
@ -88,4 +89,4 @@ nthCircle n phi = x :+ y
|
|||
n' = fromIntegral (n*waveMultiplier+1)
|
||||
x = cos (n'*phi) * radius
|
||||
y = sin (n'*phi) * radius
|
||||
radius = 40 * (2 / (n'*pi))
|
||||
radius = 2.5 * (2 / (n'*pi))
|
||||
|
|
|
|||
|
|
@ -15,20 +15,21 @@ import Reanimate.LaTeX
|
|||
import Reanimate.Monad
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Signal
|
||||
import Reanimate.Constants
|
||||
|
||||
main :: IO ()
|
||||
main = reanimate $ pauseAtEnd 2 $
|
||||
fourierAnimation_
|
||||
|
||||
sWidth :: Double
|
||||
sWidth = 0.5
|
||||
sWidth = 0.02
|
||||
|
||||
piFourier :: Fourier
|
||||
piFourier = mkFourier piPoints
|
||||
|
||||
piPoints :: [RPoint]
|
||||
piPoints = lineToPoints 500 $
|
||||
toLineCommands $ extractPath $ scale 30 $ center $ latexAlign "\\pi"
|
||||
toLineCommands $ extractPath $ scale 10 $ center $ latexAlign "\\pi"
|
||||
|
||||
|
||||
fourierAnimation_ :: Animation
|
||||
|
|
@ -40,14 +41,14 @@ fourierAnimation_ = mkAnimation 50 $ do
|
|||
let circles = setFourierLength (fLength*maxLength) piFourier
|
||||
maxLength = sum $ map magnitude $ take 499 $ drop 1 $ fourierCoefficients piFourier
|
||||
|
||||
emit $ withStrokeWidth (Num 1) $ withStrokeColor "green" $
|
||||
emit $ withStrokeColor "green" $
|
||||
mkLinePath $ mkFourierOutline circles
|
||||
drawCircles $ fourierCoefficients $ rotateFourier phi circles
|
||||
|
||||
emit $ withStrokeWidth (Num sWidth) $
|
||||
emit $
|
||||
withFillColor "white" $
|
||||
translate (-140) (-80) $
|
||||
scale 2 $ latex $ T.pack $ "Circles: " ++ show (length $ fourierCoefficients circles)
|
||||
translate (-screenWidth/16*7) (screenHeight/16*7) $
|
||||
latex $ T.pack $ "Circles: " ++ show (length $ fourierCoefficients circles)
|
||||
|
||||
data Fourier = Fourier {fourierCoefficients :: [Complex Double]}
|
||||
|
||||
|
|
@ -112,7 +113,8 @@ drawCircles circles = do
|
|||
worker [] = return ()
|
||||
worker (x :+ y : rest) = do
|
||||
let radius = sqrt(x*x+y*y)
|
||||
emit $ withStrokeWidth (Num 0.2) $
|
||||
emit $
|
||||
withStrokeWidth (Num sWidth) $
|
||||
withStrokeColor "dimgrey" $
|
||||
withFillOpacity 0 $
|
||||
CircleTree $ defaultSvg
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ main = reanimate $ autoReverse $ mkAnimation 5 $ do
|
|||
& filterX .~ pure (Percent (-1))
|
||||
& filterHeight .~ pure (Percent 3)
|
||||
& filterY .~ pure (Percent (-1))
|
||||
emit $ translate 0 (-radius*2) $ withFillColor "red" $ mkGroup
|
||||
emit $ translate 0 (radius*2.2) $ withFillColor "red" $ mkGroup
|
||||
[ translate (s*(-radius)) 0 circ
|
||||
, translate (s*radius) 0 circ
|
||||
]
|
||||
|
|
@ -52,14 +52,14 @@ main = reanimate $ autoReverse $ mkAnimation 5 $ do
|
|||
[ translate (s*(-radius)) 0 circ
|
||||
, translate (s*radius) 0 circ
|
||||
] & filterRef .~ pure (Ref "blur")
|
||||
emit $ translate 0 (radius*2) $ withFillColor "red" $ mkGroup
|
||||
emit $ translate 0 (-radius*2.2) $ withFillColor "red" $ mkGroup
|
||||
[ translate (s*(-radius)) 0 circ
|
||||
, translate (s*radius) 0 circ
|
||||
] & filterRef .~ pure (Ref "goo")
|
||||
where
|
||||
sharpness = 10
|
||||
dev = 5
|
||||
radius = 25
|
||||
dev = 0.2
|
||||
radius = 1
|
||||
circ = mkCircle (Num radius)
|
||||
|
||||
mkFilter :: String -> [FilterElement] -> Filter
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ main = reanimate $ autoReverse $ mkAnimation 2 $ do
|
|||
s <- getSignal signalLinear
|
||||
emit $ mkGroup
|
||||
[ mkBackground "black"
|
||||
, withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) text
|
||||
, withFillColor "white" $ withFillOpacity s text ]
|
||||
, withStrokeColor "white" $ withFillOpacity 0 text
|
||||
, withFillColor "white" $ withFillOpacity s text
|
||||
]
|
||||
where
|
||||
text = scale 4 $ center $ latexAlign
|
||||
text = withStrokeWidth (Num 0.01) $ scale 2 $ center $ latexAlign
|
||||
"\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import Reanimate.Svg
|
|||
main :: IO ()
|
||||
main = reanimate $ mkAnimation 1 $ do
|
||||
emit $ mkBackground "black"
|
||||
emit $ withStrokeWidth (Num 0.1) $
|
||||
emit $
|
||||
withStrokeColor "white" $
|
||||
withSubglyphs [0] (withFillColor "blue") $
|
||||
withSubglyphs [1] (withFillColor "yellow") $
|
||||
|
|
@ -23,4 +23,4 @@ main = reanimate $ mkAnimation 1 $ do
|
|||
withSubglyphs [4] (withFillColor "darkslategrey") $
|
||||
svg
|
||||
where
|
||||
svg = scale 10 $ center $ latex "\\LaTeX"
|
||||
svg = withStrokeWidth (Num 0.01) $ scale 4 $ center $ latex "\\LaTeX"
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ main = reanimate $
|
|||
where
|
||||
bg = mkAnimation 0 $ emit (mkBackground "black")
|
||||
msg = "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
|
||||
glyphs = pathify $ center $ latexAlign msg
|
||||
glyphs = withStrokeWidth (Num 0.01) $ center $ latexAlign msg
|
||||
fillText = mkAnimation 1 $ do
|
||||
s <- getSignal signalLinear
|
||||
emit $ scale 5 $ withFillColor "white" $ withFillOpacity s glyphs
|
||||
emit $ scale 2 $ withFillColor "white" $ withFillOpacity s glyphs
|
||||
drawText = mkAnimation 2 $ do
|
||||
s <- getSignal signalLinear
|
||||
emit $ scale 5 $
|
||||
withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) $
|
||||
emit $ scale 2 $
|
||||
withStrokeColor "white" $ withFillOpacity 0 $
|
||||
partialSvg s glyphs
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ mainScene :: Animation
|
|||
mainScene = sceneAnimation $ mdo
|
||||
play $ drawCircle
|
||||
# setDuration drawCircleT
|
||||
# applyE (constE $ scaleXY (-1) 1)
|
||||
fork $ play $ drawCircle
|
||||
# freezeAtPercentage 1
|
||||
# setDuration rotDur
|
||||
|
|
@ -44,7 +45,6 @@ mainScene = sceneAnimation $ mdo
|
|||
play $ drawCircle
|
||||
# setDuration drawCircleT
|
||||
# reverseAnimation
|
||||
# applyE (constE $ scaleXY (-1) 1)
|
||||
return ()
|
||||
where
|
||||
drawCircleT = 1
|
||||
|
|
@ -54,16 +54,16 @@ mainScene = sceneAnimation $ mdo
|
|||
svg = center $ latex "\\LaTeX"
|
||||
getNth n = snd (splitGlyphs [n] svg)
|
||||
svgs = [
|
||||
scale 5 $
|
||||
translate 0 (-tickLength*1.1) $
|
||||
withStrokeWidth (Num 0.2) $
|
||||
withStrokeWidth (Num 0.01) $
|
||||
scale 2 $
|
||||
translate 0 (tickLength*2) $
|
||||
withStrokeColor "white" $
|
||||
withFillColor "white" $
|
||||
center $ getNth n
|
||||
| n <- [0..4]]
|
||||
|
||||
radius = 25
|
||||
tickLength = 5
|
||||
radius = 1.25
|
||||
tickLength = 0.25
|
||||
|
||||
drawCircle :: Animation
|
||||
drawCircle = mkAnimation 1 $ do
|
||||
|
|
@ -71,19 +71,19 @@ drawCircle = mkAnimation 1 $ do
|
|||
emit $
|
||||
withFillOpacity 0 $
|
||||
withStrokeColor "white" $
|
||||
rotate 90 $
|
||||
rotate (-90) $
|
||||
partialSvg n circPath
|
||||
where
|
||||
circPath = pathify $ mkCircle (Num radius)
|
||||
|
||||
drawTick :: Animation
|
||||
drawTick = drawSVG $ mkLine (Num 0, Num 0) (Num 0, Num $ -tickLength)
|
||||
drawTick = drawSVG $ mkLine (Num 0, Num 0) (Num 0, Num $ tickLength)
|
||||
|
||||
drawSVG :: Tree -> Animation
|
||||
drawSVG t = mkAnimation 1 $ do
|
||||
n <- getSignal signalLinear
|
||||
emit $
|
||||
withStrokeColor "white" $
|
||||
rotate (-n*360) $
|
||||
translate 0 (-radius) $
|
||||
rotate (n*360) $
|
||||
translate 0 radius $
|
||||
t
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ main = reanimate $ mkAnimation 5 $ do
|
|||
s <- getSignal signalLinear
|
||||
emit $ mkGroup
|
||||
[ mkBackground "black"
|
||||
, rotate (s*360) $ center $ scale 0.5 $ embedImage img ]
|
||||
, rotate (s*360) $ center $ scaleToWidth 6 $ embedImage img
|
||||
]
|
||||
where
|
||||
img = generateImage pixelRenderer 255 255
|
||||
pixelRenderer x y = PixelRGB8 (fromIntegral x) (fromIntegral y) 128
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import Reanimate.LaTeX
|
|||
import Reanimate.Monad
|
||||
import Reanimate.Svg
|
||||
import Reanimate.Signal
|
||||
import Reanimate.Constants
|
||||
|
||||
main :: IO ()
|
||||
main = reanimate $ pauseAtEnd 5 $
|
||||
|
|
@ -46,36 +47,39 @@ main = reanimate $ pauseAtEnd 5 $
|
|||
where
|
||||
showFloat s = pack (showFFloat (Just 2) s "")
|
||||
|
||||
convertX x = x*(screenWidth/320)
|
||||
convertY y = y*(screenHeight/180)
|
||||
|
||||
curvesExample :: (Double -> ([(Double, Double -> Double)], Text)) -> Animation
|
||||
curvesExample gen = mkAnimation 2 $ do
|
||||
emit $ mkBackground "black"
|
||||
emit $ withFillColor "white" $
|
||||
translate 0 (-70) $
|
||||
scale 2 $ center $ latex "Signals"
|
||||
translate 0 (screenHeight*0.35) $
|
||||
center $ latex "Signals"
|
||||
s <- getSignal signalLinear
|
||||
let (curveFns, name) = gen s
|
||||
emit $
|
||||
center $
|
||||
mkGroup
|
||||
[ withStrokeColor "white" $ withStrokeWidth (Num 0.5) $
|
||||
[ withStrokeColor "white" $ withStrokeWidth (Num 0.01) $
|
||||
mkGroup
|
||||
[ mkLine (Num 0, Num 0)
|
||||
(Num 200, Num 0)
|
||||
(Num $ convertX 200, Num 0)
|
||||
, mkLine (Num $ 0, Num 0)
|
||||
(Num $ 0, Num $ -50) ]
|
||||
, withStrokeColor "white" $ withStrokeWidth (Num 0.1) $
|
||||
(Num $ 0, Num $ convertY 50) ]
|
||||
, withStrokeColor "white" $ withStrokeWidth (Num 0.01) $
|
||||
mkGroup
|
||||
[ mkLine (Num 0, Num $ -y)
|
||||
(Num 200, Num $ -y)
|
||||
[ mkLine (Num 0, Num $ convertX $ y)
|
||||
(Num $ convertX 200, Num $ convertX y)
|
||||
| y <- [10,20,30,40,50] ]
|
||||
, withFillColor "white" $
|
||||
mkGroup
|
||||
[ translate (-5) 5 $ center $ latex "0"
|
||||
, translate (-5) (-50) $ center $ latex "1"
|
||||
, translate (205) 5 $ center $ latex "1"
|
||||
, translate 100 20 $ center $ latex name ]
|
||||
, withFillOpacity 0 $ withStrokeColor "green" $ withStrokeWidth (Num 0.5) $
|
||||
lowerTransformations $ scaleXY 200 (-50) $ mkSignalLine (signalFromList curveFns)
|
||||
[ translate (convertX $ -5) (convertX $ -5) $ scale 0.5 $ center $ latex "0"
|
||||
, translate (convertX $ -5) (convertX $ 50) $ scale 0.5 $ center $ latex "1"
|
||||
, translate (convertX $ 205) (convertX $ -5) $ scale 0.5 $ center $ latex "1"
|
||||
, translate (convertX $ 100) (convertX $ -30)$ scale 0.6 $ center $ latex name ]
|
||||
, withFillOpacity 0 $ withStrokeColor "green" $ -- withStrokeWidth (Num 0.5) $
|
||||
lowerTransformations $ scaleXY (convertX $ 200) (convertX $ (50)) $ mkSignalLine (signalFromList curveFns)
|
||||
]
|
||||
|
||||
mkSignalLine :: Signal -> Tree
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import qualified Data.Vector.Unboxed as V
|
|||
import Debug.Trace
|
||||
import System.Random
|
||||
import System.Random.Shuffle
|
||||
import Reanimate.Constants
|
||||
|
||||
main :: IO ()
|
||||
main = reanimate $
|
||||
|
|
@ -44,18 +45,22 @@ demonstrateAlgorithm name algo = mkAnimation 10 $ do
|
|||
where
|
||||
num = (sortedDat !! y) V.! x
|
||||
sortedDat = runSort' seed algo width
|
||||
width = 1024
|
||||
-- width = 1024
|
||||
width = 500
|
||||
height = length sortedDat
|
||||
emit $ mkGroup
|
||||
[ mkBackground "black"
|
||||
|
||||
, translate 0 (10) $ center $ scaleToSize 150 150 $ embedImage img
|
||||
, translate 0 (-75) $ withFillColor "white" $ scale 1.5 $ center $
|
||||
, translate 0 (-screenWidth*0.03) $ center $ scaleXY (-1) 1 $
|
||||
scaleToSize 7.5 7.5 $ embedImage img
|
||||
, translate 0 (screenWidth*0.24) $ withFillColor "white" $ scale 1 $ center $
|
||||
latex name
|
||||
, withFillColor "white" $ translate (-85) 10 $ rotate 90 $ center $
|
||||
, withFillColor "white" $
|
||||
translate (-screenWidth*0.26) (-screenHeight*0.05) $
|
||||
rotate (-90) $ scale 0.5 $ center $
|
||||
latex "$Time \\rightarrow$"
|
||||
, withFillColor "white" $ translate (90) 10 $
|
||||
mkCircle (Num $ (1-s)*10)
|
||||
, withFillColor "white" $ translate ((screenWidth*0.30)) 0 $
|
||||
mkCircle (Num $ (1-s)*0.5)
|
||||
]
|
||||
where
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import Reanimate.Monad
|
|||
import Reanimate.Signal
|
||||
import Reanimate.Svg
|
||||
|
||||
|
||||
main :: IO ()
|
||||
main = reanimate $ mkAnimation 10 $ do
|
||||
n <- getSignal $ signalFromTo 1 500 signalLinear
|
||||
|
|
@ -33,7 +32,7 @@ main = reanimate $ mkAnimation 10 $ do
|
|||
where
|
||||
cached = [ dSvg n | n <- [0..]]
|
||||
dSvg n = renderDiagram $ withEnvelope (D.rect 320 180 :: SvgDiagram) $
|
||||
D.scale 5 $ sunflower n
|
||||
D.scale 0.2 $ sunflower n
|
||||
|
||||
mkCoords :: [P2 Double]
|
||||
mkCoords =[coord (fromIntegral i) | i <- [1..]]
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ main :: IO ()
|
|||
main = reanimate $ mkAnimation 5 $ do
|
||||
s <- oscillate $ getSignal $ signalCurve 2
|
||||
emit $ mkBackground "black"
|
||||
emit $ translate (-320/2) (-180/2) $ withStrokeColor "white" $
|
||||
emit $ scale (2/50) $ scaleXY 1 (-1) $
|
||||
translate (-320/2) (-180/2) $ withStrokeColor "white" $
|
||||
renderDiagram $
|
||||
withEnvelope (D.rect 320 180 :: SvgDiagram) $
|
||||
D.scale 50 $ D.translate (V2 (-2) (-0.75)) $ dia s
|
||||
|
|
@ -37,9 +38,9 @@ main = reanimate $ mkAnimation 5 $ do
|
|||
mconcat
|
||||
[ lc green $ rightAngleSquare
|
||||
, tangentLine
|
||||
, baselineText "tangent" # D.translate tangentVector
|
||||
, fc white $ baselineText "tangent" # D.translate tangentVector
|
||||
, normalLine
|
||||
, topLeftText "normal" # D.translate (-normalVector)
|
||||
, fc white $ topLeftText "normal" # D.translate (-normalVector)
|
||||
] # moveTo pt # D.fontSize large
|
||||
<> strokeLocTrail spline
|
||||
where
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ main :: IO ()
|
|||
main = reanimate $ repeatAnimation 5 $ mkAnimation 5 $ do
|
||||
s <- getSignal signalLinear
|
||||
emit $ mkBackground "black"
|
||||
emit $ center $ -- translate (-320/2) (-180/2) $
|
||||
emit $ scale (2/50) $ center $ -- translate (-320/2) (-180/2) $
|
||||
withStrokeColor "white" $
|
||||
renderDiagram $
|
||||
withEnvelope (D.rect 320 180 :: SvgDiagram) $
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ library
|
|||
Reanimate.Scene
|
||||
Reanimate.Povray
|
||||
Reanimate.Effect
|
||||
Reanimate.Constants
|
||||
other-modules: Reanimate.Cache
|
||||
Reanimate.Driver.Check
|
||||
Reanimate.Driver.CLI
|
||||
|
|
|
|||
6
src/Reanimate/Constants.hs
Normal file
6
src/Reanimate/Constants.hs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
module Reanimate.Constants where
|
||||
|
||||
screenWidth, screenHeight :: Num a => a
|
||||
|
||||
screenWidth = 16
|
||||
screenHeight = 9
|
||||
|
|
@ -96,8 +96,7 @@ slaveHandler conn self =
|
|||
case ret of
|
||||
Left err ->
|
||||
sendTextData conn $ T.pack $ "Error" ++ unlines (drop 3 (lines err))
|
||||
Right{} -> do
|
||||
getFrame <- runCmdLazy tmpExecutable ["raw", "+RTS", "-N", "-M1G", "-RTS"]
|
||||
Right{} -> runCmdLazy tmpExecutable execOpts $ \getFrame -> do
|
||||
(frameCount,_) <- expectFrame =<< getFrame
|
||||
sendTextData conn (T.pack $ show frameCount)
|
||||
fix $ \loop -> do
|
||||
|
|
@ -106,6 +105,7 @@ slaveHandler conn self =
|
|||
sendTextData conn frame
|
||||
loop
|
||||
where
|
||||
execOpts = ["raw", "+RTS", "-N", "-M1G", "-RTS"]
|
||||
expectFrame :: Either String Text -> IO (Integer, Text)
|
||||
expectFrame (Left "") = do
|
||||
sendTextData conn (T.pack "Done")
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ xelatex tex = (unsafePerformIO . (cacheMem . cacheDiskSvg) xelatexToSVG)
|
|||
latexAlign :: Text -> Tree
|
||||
latexAlign tex = latex $ T.unlines ["\\begin{align*}", tex, "\\end{align*}"]
|
||||
|
||||
postprocess :: Tree -> Tree
|
||||
postprocess = lowerTransformations . scaleXY 1 (-1) . scale 0.1 . pathify
|
||||
|
||||
latexToSVG :: Text -> IO Tree
|
||||
latexToSVG tex = handle (\(_::SomeException) -> return (failedSvg tex)) $ do
|
||||
|
|
@ -46,7 +48,7 @@ latexToSVG tex = handle (\(_::SomeException) -> return (failedSvg tex)) $ do
|
|||
svg_data <- B.readFile svg_file
|
||||
case parseSvgFile svg_file svg_data of
|
||||
Nothing -> error "Malformed svg"
|
||||
Just svg -> return $ unbox $ replaceUses svg
|
||||
Just svg -> return $ postprocess $ unbox $ replaceUses svg
|
||||
|
||||
xelatexToSVG :: Text -> IO Tree
|
||||
xelatexToSVG tex = handle (\(_::SomeException) -> return (failedSvg tex)) $ do
|
||||
|
|
@ -68,7 +70,7 @@ xelatexToSVG tex = handle (\(_::SomeException) -> return (failedSvg tex)) $ do
|
|||
svg_data <- B.readFile svg_file
|
||||
case parseSvgFile svg_file svg_data of
|
||||
Nothing -> error "Malformed svg"
|
||||
Just svg -> return $ unbox $ replaceUses svg
|
||||
Just svg -> return $ postprocess $ unbox $ replaceUses svg
|
||||
|
||||
failedSvg :: Text -> Tree
|
||||
failedSvg _tex = defaultSvg
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Reanimate.Misc
|
|||
, withTempFile
|
||||
) where
|
||||
|
||||
import Control.Exception (evaluate)
|
||||
import Control.Exception (evaluate, finally)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import System.Directory (createDirectory, findExecutable,
|
||||
|
|
@ -17,7 +17,7 @@ import System.FilePath ((<.>), (</>))
|
|||
import System.IO (hClose, hGetContents, hIsEOF, openTempFile)
|
||||
import System.Process (readProcessWithExitCode,
|
||||
runInteractiveProcess, showCommandForUser,
|
||||
waitForProcess)
|
||||
terminateProcess, waitForProcess)
|
||||
|
||||
requireExecutable :: String -> IO FilePath
|
||||
requireExecutable exec = do
|
||||
|
|
@ -43,27 +43,31 @@ runCmd_ exec args = do
|
|||
"Error code: " ++ show err ++ "\n" ++
|
||||
"stderr: " ++ stderr
|
||||
|
||||
runCmdLazy :: FilePath -> [String] -> IO (IO (Either String T.Text))
|
||||
runCmdLazy exec args = do
|
||||
runCmdLazy :: FilePath -> [String] -> (IO (Either String T.Text) -> IO a) -> IO a
|
||||
runCmdLazy exec args handler = do
|
||||
(inp, out, err, pid) <- runInteractiveProcess exec args Nothing Nothing
|
||||
hClose inp
|
||||
return $ do
|
||||
eof <- hIsEOF out
|
||||
if eof
|
||||
then do
|
||||
stderr <- hGetContents err
|
||||
_ <- evaluate (length stderr)
|
||||
ret <- waitForProcess pid
|
||||
case ret of
|
||||
ExitSuccess -> return (Left "")
|
||||
ExitFailure errMsg -> do
|
||||
return $ Left $
|
||||
"Failed to run: " ++ showCommandForUser exec args ++ "\n" ++
|
||||
"Error code: " ++ show errMsg ++ "\n" ++
|
||||
"stderr: " ++ stderr
|
||||
else do
|
||||
line <- T.hGetLine out
|
||||
return (Right line)
|
||||
let fetch = do
|
||||
eof <- hIsEOF out
|
||||
if eof
|
||||
then do
|
||||
stderr <- hGetContents err
|
||||
_ <- evaluate (length stderr)
|
||||
ret <- waitForProcess pid
|
||||
case ret of
|
||||
ExitSuccess -> return (Left "")
|
||||
ExitFailure errMsg -> do
|
||||
return $ Left $
|
||||
"Failed to run: " ++ showCommandForUser exec args ++ "\n" ++
|
||||
"Error code: " ++ show errMsg ++ "\n" ++
|
||||
"stderr: " ++ stderr
|
||||
else do
|
||||
line <- T.hGetLine out
|
||||
return (Right line)
|
||||
handler fetch `finally` do
|
||||
terminateProcess pid
|
||||
_ <- waitForProcess pid
|
||||
return ()
|
||||
|
||||
withTempDir :: (FilePath -> IO a) -> IO a
|
||||
withTempDir action = do
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ renderSvg :: Maybe Number -> Maybe Number -> Tree -> String
|
|||
renderSvg w h t = ppDocument doc
|
||||
-- renderSvg w h t = ppFastElement (xmlOfDocument doc)
|
||||
where
|
||||
width = 320
|
||||
height = width / (16/9)
|
||||
width = 16
|
||||
height = 9
|
||||
doc = Document
|
||||
{ _viewBox = Just (-width/2, -height/2, width, height)
|
||||
, _width = w
|
||||
, _height = h
|
||||
, _elements = [t]
|
||||
, _elements = [withStrokeWidth (Num 0.05) $ scaleXY 1 (-1) t]
|
||||
, _definitions = M.empty
|
||||
, _description = ""
|
||||
, _documentLocation = ""
|
||||
|
|
|
|||
|
|
@ -46,6 +46,6 @@ mkPovrayImage args script = cacheDiskKey key $ do
|
|||
png <- B.readFile out
|
||||
case decodePng png of
|
||||
Left{} -> error "bad image"
|
||||
Right img -> return $ center $ scaleToSize 320 180 $ embedDynamicImage img
|
||||
Right img -> return $ center $ scaleToSize 16 9 $ embedDynamicImage img
|
||||
where
|
||||
key = T.concat (script:map T.pack args)
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ lowerTransformations = worker Transform.identity
|
|||
GroupTree g -> GroupTree $
|
||||
g & groupChildren %~ map (worker m')
|
||||
& transform .~ Nothing
|
||||
_ -> t
|
||||
_ -> mkGroup [t] & transform .~ Just [ Transform.toTransformation m ]
|
||||
|
||||
lowerIds :: Tree -> Tree
|
||||
lowerIds = mapTree worker
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ module Reanimate.Transform
|
|||
( identity
|
||||
, transformPoint
|
||||
, mkMatrix
|
||||
, toTransformation
|
||||
) where
|
||||
|
||||
-- XXX: Use Linear.Matrix instead of Data.Matrix to drop the 'matrix' dependency.
|
||||
|
|
@ -46,3 +47,8 @@ transformationMatrix transformation =
|
|||
translate x y = fromList [1,0,0,1,x,y]
|
||||
rotate a = fromList [cos r,sin r,-sin r,cos r,0,0]
|
||||
where r = a * pi / 180
|
||||
|
||||
toTransformation :: TMatrix -> Transformation
|
||||
toTransformation m = TransformMatrix a b c d e f
|
||||
where
|
||||
[a,c,e,b,d,f,_,_,_] = M.toList m
|
||||
|
|
|
|||
Loading…
Reference in a new issue