Moving Circles
div#app
IO loops can also be used to animate elements.
let n = 10,
dt = 0.05,
ds = 0.05,
f = Math.sqrt(3) * Math.PI,
IO = dom.IO;
// samples : Int -> [Num]
let samples = k => [...Array(n)]
.map((_, i) => 2 * i * Math.PI / n)
.map(t => t + k * dt);
//--- View ---
// circle : Num -> Node
let circle = dom('circle').place('circle')
.attr('r', 4)
.attr('transform', m => `translate(${m.x}, ${m.y})`)
.style('transition', `transform ${ds}s`)
.pull(t => ({
x: (30 + 12 * Math.cos(f * t)) * Math.cos(t),
y: (30 + 12 * Math.cos(f * t))* Math.sin(t)
}));
// circles : [Num] -> [Node]
let circles = dom.map(circle);
// svg : Int -> Node
let svg = dom('svg').put('#app')
.attr('width', 150)
.attr('height', 150)
.attr('viewBox', "-50 -50 100 100")
.branch(circles)
.pull(samples);
//--- Update ---
// tick : Int -> IO(Int)
let tick = k => {
return IO()
.return(k)
.push(samples)
.bind(IO.map.set(circles))
.return(k + 1);
}
// loop : Int -> IO(Num)
let loop = k => tick(k).sleep(ds).bind(loop);
//--- Main ---
// io : IO(Int)
let io = IO.put(svg)(0).bind(loop);