Animation & Screen
Frames as Sequences
An animation is a sequence of scenes — one map per frame. No timeline, no keyframes, no mutation:
(require '[eido.animate :as anim])
(def frames
(anim/frames 60
(fn [t] ;; t goes from 0.0 to 1.0
{:image/size [400 400]
:image/background [:color/rgb 30 30 40]
:image/nodes
[{:node/type :shape/circle
:circle/center [200 200]
:circle/radius (* 150 t)
:style/fill [:color/hsl (* 360 t) 0.8 0.5]}]})))
60 frames = 60 maps in a vector. Each frame is an independent scene — no shared mutable state between frames.
Easing and Helpers
The animation helpers shape how values change over time:
;; Sine pulse — 0→1→0 over the cycle
(anim/pulse t)
;; Linear fade — 1→0
(anim/fade-linear t)
;; Quadratic fade — softer tail
(anim/fade-out t)
;; Quadratic ease-in
(anim/fade-in t)Combine these with your own math. Since t is just a number, any function works.
GIF Export
;; Animated GIF — loops by default
(eido/render frames {:output "anim.gif" :fps 30})
;; Non-looping GIF
(eido/render frames {:output "anim.gif" :fps 30 :loop false})
;; Higher resolution
(eido/render frames {:output "anim.gif" :fps 30 :scale 2})Animated SVG
;; Animated SVG using SMIL
(eido/render frames {:output "anim.svg" :fps 30})
;; Or get the SVG string directly
(eido/render frames {:format :svg :fps 30})Animated SVGs are resolution-independent and work in modern browsers.
PNG Sequence
For video production, render a numbered PNG sequence and encode with ffmpeg:
;; Write frame-0000.png through frame-0059.png
(eido/render frames {:output "frames/" :fps 30})
;; Then encode:
;; ffmpeg -framerate 30 -i frames/frame-%04d.png -c:v libx264 -pix_fmt yuv420p out.mp4Seamless Loops
Use 4D noise for seamless looping — sample a circle in the noise space:
(require '[eido.gen.noise :as noise])
;; Seamless 1-second loop at 30fps
(anim/frames 30
(fn [t]
(let [angle (* 2 Math/PI t)
nx (Math/cos angle)
ny (Math/sin angle)]
;; perlin4d produces values that loop seamlessly
;; as (nx, ny) trace a circle
(make-scene (noise/perlin4d x y nx ny)))))perlin4d is specifically designed for this — the cos/sin trick traces a circle in the 3rd and 4th dimensions, producing a seamless loop in the first two.