スタートページJavascriptCANVAS

アニメーション(2)

以前の図を消す-残像効果-

アニメーションは「動く」ものだとすれば、前の画像を消す必要があります。そのため、いったん全画面を消して、改めて現在の画面を表示します。消えている時間が短いと、残像効果により、連続して動いているように見えます。その方法を示します。


遅延時間=(ms)

パターン1

円がスムーズに大きくなっていくように見えます。
 ソースコードのサワリの部分を示します。
 点(0,0)を中心に半径rの円を描きます。rは、初期値を0.01、遅延時間(interval)をおいて、dr=0.01づつ増加していくようにしています。
 このとき、直前までの円が残っていると同心円の画像になってしまうので、それを消す必要があります。

  setCanvas("canvas1", "black");         黒い背景のcanvas1を定義する
  var dr = 0.01;
  var r = dr;
  var timerId = setInterval(function(){
    clearScreen("black");           A:いったん全画面を黒にする。円も消える。
    drawCircle(0,0, r, "white", 4, "none");  大きくなった円を表示する
    if(r >= 1) clearInterval(timerId);
    r = r + dr;
  }, interval);

パターン2

背景が必要なことがあります。パターン1のAでは背景も消してしまいます。それで、Aの直後で背景を再表示する必要があります。

  setCanvas("canvas1", "black");
  drawRect(0,0, 1, 1, "yellow", 1, "yellow");    ┐
  drawRect(0,0, 1,-1, "green", 1, "green");     │背景の初期表示
  drawRect(0,0, -1, 1, "blue",  1, "blue");     │
  drawRect(0,0, -1,-1, "red",  1, "red");      ┘
  var dr = 0.01;
  var r = dr;
  var timerId = setInterval(function(){
    clearScreen("black");
    drawRect(0,0, 1, 1, "yellow", 1, "yellow");  ┐
    drawRect(0,0, 1,-1, "green", 1, "green");   │背景の再表示
    drawRect(0,0, -1, 1, "blue",  1, "blue");   │
    drawRect(0,0, -1,-1, "red",  1, "red");    ┘
    drawCircle(0,0, r, "white", 4, "none");
    if(r >= 1) clearInterval(timerId);
    r = r + dr;
  }, interval);

パターン3

背景も時間経過とともに変化させる必要があるかもしれません。パターン2の「背景の再表示」の部分を修正すればよいのです。ここでは、左下の赤の部分をrと連動させて広げています。

    drawRect(0,0, 1, 1, "yellow", 1, "yellow");  ┐
    drawRect(0,0, 1,-1, "green", 1, "green");   │背景の再表示
    drawRect(0,0, -1, 1, "blue",  1, "blue");   │
    drawRect(r,r, -1,-1, "red",  1, "red");    ┘

パターン4

機能は、パターン2と同じです。パターン2では、背景表示を2回記述しました。背景の記述が複雑なときは記述が煩雑になります。それを1回ですますための工夫です。
 背景記述部分を function にしても実現できるでしょうが、ここでは ctx.getImageData() / ctx.putImageData を用いました。これらはcanvasの標準関数ですので、 ctx. が必要です。これらの機能については、「CANVASの基本(1)」を参照してください。
 ここでは、Aで背景の初期画面を配列に取り込み、それをBで再表示しています。

  drawRect(0,0, 1, 1, "yellow", 1, "yellow");
  drawRect(0,0, 1,-1, "green", 1, "green");
  drawRect(0,0, -1, 1, "blue",  1, "blue");
  drawRect(0,0, -1,-1, "red",  1, "red");
  var ctxImage = ctx.getImageData(0, 0, cw, ch);    A:背景画像をctxImageに取り込む
  var dr = 0.01;
  var r = dr;
  var timerId = setInterval(function(){
    clearScreen("black");
    ctx.putImageData(ctxImage, 0, 0);        B:ctxImageを表示する
    drawCircle(0,0, r, "white", 4, "none");
    if(r>=1) clearInterval(timerId);
    r = r + dr;
  }, interval);