[plt-scheme] MrEd - Animated canvas
At Tue, 06 Mar 2007 13:25:13 -0800, "Laurent" wrote:
> While seeking a little bit I saw that a double buffer had to be used,
> but I do not know how that goes. Somebody could it explain me how to
> simply carry out an animation without flutter in scheme ?
>
> [...]
>
> (define canvas_1 (new canvas% (parent vpanel_2)
> (min-width 400)
> (style '(border))
> (paint-callback (lambda (obj dc)
> (send dc draw-rounded-
> rectangle
> CURSOR_POSITION 570 150 15 5)
> ))))
Implement the buffer using bitmap%, and draw into it using bitmap-dc%.
Then draw the bitmap to the canvas using `draw-bitmap'.
One tricky part is creating a bitmap of the right size. Here's a bit of
code to help manage an offscreen bitmap given, a canvas:
(define offscreen-w 0)
(define offscreen-h 0)
(define offscreen-bm #f)
(define offscreen-dc (make-object bitmap-dc%))
(define (reset-offscreen! canvas)
;; Get the size of the canvas's drawing area:
(let-values ([(w h) (send canvas get-client-size)])
;; If the bitmap isn't the right size, create a new one:
(unless (and (= offscreen-w w)
(= offscreen-h h))
(set! offscreen-w w)
(set! offscreen-h h)
(set! offscreen-bm (make-object bitmap% w h))
(send offscreen-dc set-bitmap offscreen-bm))))
Here's how it would be used in your example. Note that I added the
'no-autoclear style flag for the canvas% instance (otherwise a flicker
persists), and I added an explicit call to the `clear' method of the
offscreen drawing context (because the drawing area is no longer
automatically cleared):
(define canvas_1
(new canvas% (parent vpanel_2)
(min-width 400)
(style '(border no-autoclear))
(paint-callback
(lambda (canvas dc)
;; Make sure the buffer is the right size:
(reset-offscreen! canvas)
;; Draw the picture offscreen:
(send offscreen-dc clear)
(send offscreen-dc draw-rounded-rectangle
CURSOR_POSITION 570 150 15 5)
;; Copy the picture onto the screen:
(send dc draw-bitmap offscreen-bm 0 0)))))
Matthew