Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Add animation example
Browse files Browse the repository at this point in the history
  • Loading branch information
LilithHafner committed Aug 5, 2022
1 parent ea4e6ab commit 3fe1be5
Showing 1 changed file with 84 additions and 2 deletions.
86 changes: 84 additions & 2 deletions docs/src/manual/canvas.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Drawing on Canvas
# Drawing on Canvas & Animation

Generic drawing is done on a `Canvas`. You control what appears on this canvas by defining a `draw` function:

Expand Down Expand Up @@ -32,7 +32,7 @@ avoid this problem, the `@guarded` macro wraps your code in a
when initially writing and debugging code. See [further
discussion](../doc/more_signals.md) about when `@guarded` is relevant.

Finally, `Canvas`es have a field called `mouse` that allows you to
`Canvas`es have a field called `mouse` that allows you to
easily write callbacks for mouse events:

```julia
Expand All @@ -50,3 +50,85 @@ Resizing the window will make them go away; they were drawn on the
canvas, but they weren't added to the `draw` function.

Note the use of the `@guarded` macro here, too.

Finally, we can put this all together to make an interactive animation.

```julia
using Gtk, Graphics

# Physics
position = 100rand(3)
velocity = 100randn(3)
t = time()
function update_ball!(bounds)
global t, bounce_time
dt = time()-t
t += dt
for i in eachindex(position, velocity, bounds)
position[i] += velocity[i]*dt
lo, hi = bounds[i]
position[i] = mod(position[i]-lo, 2(hi-lo))+lo
if position[i] > hi
position[i] = 2hi - position[i]
velocity[i] = -velocity[i]
end
end
end

# Initialization
c = @GtkCanvas()
win = GtkWindow(c, "3D-Animation")

# Rendering
@guarded draw(c) do widget
ctx = getgc(c)
h = height(c)
w = width(c)

# Paint background
rectangle(ctx, 0, 0, w, h)
set_source_rgb(ctx, 0, 0, 0)
fill(ctx)
set_source_rgb(ctx, .4, .4, .4) # color and path can appear in either order
rectangle(ctx, w/4, h/4, w/2, h/2)
fill(ctx)

# Compute physics
r = 20
depth = hypot(w,h)/sqrt(2)
update_ball!([(r, w-r), (r, h-r), (0, depth-r)])

# Paint ball
set_source_rgb(ctx, .6, .5, 1)
x,y,z = position
z = z/depth + 1
arc(ctx, (x-w/2)/z+w/2, (y-h/2)/z+h/2, r/z, 0, 2pi)
fill(ctx)
end

# Event handling
c.mouse.button1press = @guarded (widget, event) -> begin
# Move toward the mouse position
velocity[1] = event.x - position[1]
velocity[2] = event.y - position[2]
velocity[3] = 0 - position[3]
end

running = Ref(true)
signal_connect(win, :destroy) do widget
running[] = false
end

# Initialization part 2
show(c)
while !c.is_sized
sleep(.0001) # Wait for the canvas to initialize before we can call getgc(c)
end

# Main loop
while running[]
c.draw(true) # Manually repaint the scene (this does not automatically clear the background)
reveal(c) # Tell Gtk that the canvas needs to be re-drawn
sleep(.0001) # Hand control back to Gtk to display the redrawn window and handle events.
end
```

0 comments on commit 3fe1be5

Please sign in to comment.