Animating


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


0.03333333333333333
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


0.03333333333333333
0.03333333333333333
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


0.0
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


0.0
1-element Array{Any,1}:
 [0.805213,0.0335703]
Out[5]:

If you used Interact to come up with something cool, do let us know by commenting on this issue. :)


In [ ]: