2017-02-25 8 views
0

次のコードを使用して、キャンバス上に画像のリストを表示しようとしています。ただし、空のフレームが表示され、 'for'ループ全体が実行されて最終的なエフェクトがフレームに表示されるまで画像は表示されません。キャンバス上の画像のリストをアニメ化する

#lang racket/gui 
(require 2htdp/image) 

(define frame (new frame% 
        [label "Example"] 
        [width 500] 
        [height 500])) 

(send frame show #t) 
; (sleep 1) ; tried this to allow time for frame to show properly; does not help; 

(new canvas% [parent frame] 
    [paint-callback 
     (lambda (canvas dc) 
     (for ((i imglist))  ; imglist is a list of images to be displayed @ 1/second. 
      (send dc clear) 
      (send dc draw-bitmap 
        (image->bitmap i) 
        20 20) 
      ; (send dc flush)  ; this statement also does not help; 
      (sleep 1)    ; to show animation effect from list of images; 
     ))]) 

イメージ - >ビットマップ機能はからです:;から:https://lists.racket-lang.org/users/archive/2014-December/065110.html

(define (image->bitmap image) 
    (let* ([width (image-width image)] 
     [height (image-height image)] 
     [bm (make-bitmap width height)] 
     [dc (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

はどこに問題があるとどのようにそれを解決することができますか?

答えて

1

paint-callbackは、キャンバスをすばやく更新して戻すことを目的としています。 返されると、システムはキャンバスが更新されたことを認識します。

希望することを行う1つの方法:1)現在表示中の画像を保持するパラメータを導入します。 2)paint-callbackが現在の画像を描くようにします。 3)1秒ごとに現在のイメージを変更する別のスレッドを作成します。

注:以下は、幅と高さに+1を加えたものです(image->bitmap)。円のエッジがカットオフされました。作品に続き

#lang racket/gui 
(require 2htdp/image) 

(define images (list (circle 30 "outline" "red") 
        (circle 20 "outline" "red") 
        (circle 10 "outline" "red") 
        (circle 5 "outline" "red"))) 

(define current-image (make-parameter (first images))) 

(define (image->bitmap image) 
    (let* ([width (+ (image-width image) 1)] 
     [height (+ (image-height image) 1)] 
     [bm  (make-bitmap width height)] 
     [dc  (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

(define frame (new frame% 
        [label "Example"] 
        [width 500] 
        [height 500])) 

(define canvas (new canvas% [parent frame] 
        [paint-callback 
        (lambda (canvas dc) 
         (send dc clear) 
         (send dc draw-bitmap (image->bitmap (current-image)) 20 20))])) 

(send frame show #t) 

(thread (λ() 
      (let loop ([is images]) 
      (cond 
       [(null? is) (loop images)] 
       [else  (current-image (first is)) 
          (send canvas on-paint) 
          (sleep 1) 
          (loop (rest is))])))) 
+0

はい、非常にうまく動作します。私は、DCオブジェクトを取得して無限ループで描画ビットマップを作成するために "(canvas get-dcを送信する")こともできますが、フレームクローズボタンが機能せず、プロセスがSTOPpedされなければなりませんDrRacket IDE。スレッドを使用するソリューションにはこのような問題はありません。 – rnso

+0

私はそれを明確に示すための答えとしてこれを追加しました。 – rnso

0

(define images (list (circle 30 "outline" "red") 
        (circle 20 "outline" "red") 
        (circle 10 "outline" "red") 
        (circle 5 "outline" "red"))) 

(define (image->bitmap image) 
    (let* ([width (image-width image)] 
     [height (image-height image)] 
     [bm (make-bitmap width height)] 
     [dc (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

(define frame (new frame% [label "Frame"] [width 300] [height 300])) 
(define canvas (new canvas% [parent frame])) 
(define dc (send canvas get-dc)) 

(send frame show #t) 
(sleep/yield 1) 

(let loop() 
    (for ((i images)) 
    (send dc clear) 
    (send dc draw-bitmap 
      (image->bitmap i) 
      20 20) 
    (sleep 0.5)) 
    (loop)) 

しかし、アニメーションを示す枠が閉じないが、IDEから停止する必要があります。

関連する問題