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 Colors
using Compose
@manipulate for color=["yellow", "cyan", "tomato"], n=3:20, ticks=fps(30.)
t = time()
compose(context(), fill(parse(Colorant, 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(map(!, signal(paused)), 30),
t = foldp(+, 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(parse(Colorant, color)), circle())
end
Out[3]:
Here is a captivating animation made with tiles of varying colors.
In [4]:
using Colors
using Compose
@manipulate for unpaused = true, ticks=fpswhen(signal(unpaused), 30.)
gridstack([compose(context(), rectangle(), fill(ColorTypes.LCHab(70.0, 60.0, 100*time()+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(parse(Colorant, colors[i%4+1])), circle())
for (i, p) in enumerate(points)]
@manipulate for ticks=fps(30.), add=button("Add particle"),
velocities = foldp((x,y) -> push!(x, rand(2)), Any[rand(2)], signal(add))
compose(context(),
dots([map(v -> box(v*time()), (vx, vy)) for (vx, vy) in velocities])...)
end
Out[5]:
If you used Interact to come up with something cool, do let us know by commenting on this issue. :)
In [ ]: