Hylograph.Simulation.Core.Tick
- Package
- purescript-hylograph-simulation-core
- Repository
- afcondon/purescript-hylograph-simulation-core
Tick-Driven Transitions
Primitives for animating transitions using simulation ticks rather than CSS. This is the simulation-aware analog to d3-transition.
Key insight: Force simulations already have a tick loop. We can use that same loop to drive enter/exit/update animations, giving us:
- Predictable, debuggable behavior
- No CSS timing coordination
- Pure PureScript interpolation
Usage:
import Hylograph.Simulation.Core.Tick as T
-- In your state
type State = { entering :: Map String Progress, exiting :: Array (Transitioning Node) }
-- In tick handler
onTick state = do
let { active: stillEntering } = T.tickProgressMap 0.025 state.entering
let { active: stillExiting } = T.tickTransitions 0.025 state.exiting
-- render with interpolated values
-- In render
radius = case enterProgress of
Just p -> T.lerp 20.0 5.0 (T.easeOut p)
Nothing -> 5.0
#Transitioning Source
type Transitioning a = { item :: a, progress :: Progress }An item in transition, carrying its state and progress
#tickProgressMap Source
tickProgressMap :: forall k. Ord k => TickDelta -> Map k Progress -> { active :: Map k Progress, completed :: Array k }Advance all progress values in a Map, partitioning into active and completed
let { active, completed } = tickProgressMap 0.025 enteringNodes
-- active: nodes still animating
-- completed: keys that just finished (for cleanup, callbacks, etc.)
#tickTransitions Source
tickTransitions :: forall a. TickDelta -> Array (Transitioning a) -> { active :: Array (Transitioning a), completed :: Array a }Advance all transitions, partitioning into active and completed
let { active, completed } = tickTransitions 0.025 exitingNodes
-- active: items still animating out
-- completed: items that finished (now safe to remove from DOM)
#startTransitions Source
startTransitions :: forall a. Array a -> Array (Transitioning a)Wrap items as transitions starting at progress 0.0
#startTransitionsFrom Source
startTransitionsFrom :: forall a. Progress -> Array a -> Array (Transitioning a)Wrap items as transitions starting at a specific progress
#lerpClamped Source
lerpClamped :: Number -> Number -> Progress -> NumberLinear interpolation with progress clamped to [0, 1]
#easeInQuad Source
easeInQuad :: EasingQuadratic ease in: t²
#easeOutQuad Source
easeOutQuad :: EasingQuadratic ease out: 1 - (1-t)²
#easeInOutQuad Source
easeInOutQuad :: EasingQuadratic ease in-out
#easeInCubic Source
easeInCubic :: EasingCubic ease in: t³
#easeOutCubic Source
easeOutCubic :: EasingCubic ease out: 1 - (1-t)³
#easeInOutCubic Source
easeInOutCubic :: EasingCubic ease in-out
#withEasing Source
withEasing :: forall a. Easing -> (Progress -> a) -> Progress -> aApply easing to an interpolation function
-- Ease-out shrink from 20 to 5
radius = withEasing easeOut (lerp 20.0 5.0) progress
#ticksForDuration Source
ticksForDuration :: Int -> TickDeltaCalculate tick delta for a desired duration at assumed 60fps
ticksForDuration 1000 -- 0.0167 (1 second at 60fps)
ticksForDuration 500 -- 0.0333 (0.5 seconds)