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:
David Himmelstrup 2019-09-18 19:20:14 +08:00 committed by GitHub
commit 89905ebe39
24 changed files with 167 additions and 121 deletions

View file

@ -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\

View file

@ -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

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -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}"

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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..]]

View file

@ -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

View file

@ -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) $

View file

@ -57,6 +57,7 @@ library
Reanimate.Scene
Reanimate.Povray
Reanimate.Effect
Reanimate.Constants
other-modules: Reanimate.Cache
Reanimate.Driver.Check
Reanimate.Driver.CLI

View file

@ -0,0 +1,6 @@
module Reanimate.Constants where
screenWidth, screenHeight :: Num a => a
screenWidth = 16
screenHeight = 9

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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 = ""

View file

@ -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)

View file

@ -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

View file

@ -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