In [1]:
using Interact, Reactive
It is possible to create interactive animations using Reactive's timing functions.
Functions like fps
, fpswhen
, every
etc, let us create periodically updating signals. This, combined with the other functions in Reactive provide for declarative ways to define animations. Let us now take the n-gon compose example from interactive diagrams notebook and animate it.
In [2]:
using Color
using Compose
@manipulate for color=["yellow", "cyan", "tomato"], n=3:20, t_dt=timestamp(fps(30.))
t, dt = t_dt # current time, time since last frame
compose(context(), fill(color),
polygon([((1+sin(θ+t))/2, (1+cos(θ+t))/2) for θ in 0:2π/n:2π]))
end
Out[2]:
It's often advisable to give your animations a pause checkbox. Here is a bouncing ball that you can pause and resume
In [3]:
using Compose
@manipulate for
paused=false,
dt = fpswhen(lift(!, paused), 30), # stop updating time when paused.
t = foldl(+, 0., dt), # add up the time deltas to get time
gravity = 0:0.01:5, # some sort of gravity
color = ["tomato", "cyan"] # color the ball
compose(context(0.5, 1-abs(sin(t*gravity)), 0.1, 0.1), fill(color), circle())
end
Out[3]:
Here is a captivating animation made with tiles of varying colors.
In [4]:
using Color
using Compose
@manipulate for unpaused = true, x=timestamp(fpswhen(unpaused, 30.))
gridstack([compose(context(), rectangle(), fill(LCHab(70.0, 60.0, 100*x[1]+i*j)))
for i in 1:8, j in 1:8])
end
Out[4]:
And finally, particles in a box.
In [5]:
using Compose
box(x) = let i = floor(x)
i%2==0 ? x-i : 1+i-x
end
colors = ["orange", "cyan", "gray", "tomato"]
dots(points) = [(context(p[1], p[2], .05, .05), fill(colors[i%4+1]), circle())
for (i, p) in enumerate(points)]
@manipulate for t=timestamp(fps(30.)), add=button("Add particle"),
velocities = foldl((x,y) -> push!(x, rand(2)), Any[rand(2)], add)
compose(context(),
dots([map(v -> box(v*t[1]), (vx, vy)) for (vx, vy) in velocities])...)
end
Out[5]:
If you used Interact to come up with something you think people will be wow-ed by, do let us know by commenting on this issue. :)