dzen-dhall-1.0.0: src/DzenDhall/Animation/Slider.hs
module DzenDhall.Animation.Slider where
import DzenDhall.Config
import DzenDhall.AST
import DzenDhall.Data
import DzenDhall.Extra
import Data.Vector (Vector, (!), null, length)
import Lens.Micro
-- | There are three stages of the animation in a cycle:
--
-- 1. Fading in
-- 2. Delay
-- 3. Fading out
run
:: Slider
-> Int
-- ^ Frame number
-> Vector AST
-- ^ Vector of possible ASTs (only one of them will be selected)
-> AST
run _ _ asts
| Data.Vector.null asts = mempty
-- Short-circuit if `fadeFrameCount`s are all set to zero.
run slider frame asts
| slider ^. fadeIn . fadeFrameCount == 0 &&
slider ^. fadeOut . fadeFrameCount == 0 =
let astIx = (frame `div` positive (slider ^. sliderDelay))
`mod` Data.Vector.length asts
in asts ! astIx
run slider frame asts =
-- Calculate total frame counts for each 3 stages:
let inFrameCount = positive $ slider ^. fadeIn . fadeFrameCount
delayFrameCount = slider ^. sliderDelay
outFrameCount = positive $ slider ^. fadeOut . fadeFrameCount
-- Find how many frames total in a cycle
totalFrames = positive $
inFrameCount + delayFrameCount + outFrameCount
-- Find currenlty selected AST index
astIx = (frame `div` totalFrames) `mod` Data.Vector.length asts
-- Select visible AST
ast = asts ! astIx
-- Find in which frame we are, starting from the beginning of the
-- animation cycle.
frameNumber = frame `mod` totalFrames
-- Calculate frame number in a cycle from which stage 3 starts
outStartFrame = inFrameCount + delayFrameCount
-- Find out, on which of the three stages we are:
--
-- For 1st & 3rd stages, calculate frame number relative to the first
-- frame of each stage.
yShift =
if | frameNumber <= inFrameCount
-- For the first stage, `relativeFrameNumber` is just `frameNumber` -
-- - we are starting from 0.
-> renderFade (slider ^.fadeIn) frameNumber inFrameCount
| frameNumber < outStartFrame
-> 0
| otherwise
-- For the third stage, `relativeFrameNumber` equals to how many frames
-- are remaining
-> renderFade (slider ^. fadeOut) (totalFrames - frameNumber) outFrameCount
in
ASTProp (P (XY (0, yShift))) ast
renderFade
:: Fade
-> Int
-- ^ Number of the current frame
-> Int
-- ^ Total frame count in a stage
-> Int
renderFade fade relativeFrameNumber frameCount =
let height = fade ^. fadePixelHeight
dk = direction (fade ^. fadeDirection)
in
dk * (height - height * relativeFrameNumber `div` frameCount)
direction :: VerticalDirection -> Int
direction VUp = -1
direction _ = 1