オブジェクト指向風味HTML5 Canvasテスト

今流行のHTML5 Canvasを触ってみた。オブジェクト指向風味です。ネイティブでcanvasタグをサポートしたブラウザ(FirefoxChromeなど)でしか動きません。


JavaScriptは初心者同然なので色々調べていたり、適当なところにアップしたXMLGoogleガジェット化する方法がGoogleのサイトに無くて探しまわったり*1していたためかなり時間がかかってしまった。

HTML+JavaScriptはこんな感じです。

<canvas id="thecanvas" width="300" height="300"></canvas>
<p>
<input name="stop" type="button" value="stop" id="stop" />
<input name="start" type="button" value="start" id="start" />
</p>
<script type="text/javascript">
function main(){
  var app = new Application();
}

var Application = function (){
  var tid = null;
  var mycanvas = new MyCanvas('thecanvas');
  if (mycanvas.isValid()){
    var box = new Box(100, 150, 100, 100, "#FF0000", 5, 5, mycanvas.width, mycanvas.height);
    function doDraw(){
      box.draw(mycanvas.context2d);
      tid = setTimeout(doDraw, 16);
    }
    start();
  }

  var startButton = document.getElementById('start');
  startButton.onclick = start;
  var stopButton = document.getElementById('stop');
  stopButton.onclick = function (){
    clearTimeout(tid);
    tid = null;
  };

  function start(){
    if (tid == null) {
      doDraw();
    }
  }
};

var MyCanvas = function (id) {
  this.canvas = document.getElementById(id);
  if (this.canvas.getContext) {
    this.context2d = this.canvas.getContext('2d');
  }
  else {
    this.context2d = null;
  }
  this.width = this.canvas.width;
  this.height = this.canvas.height;
}

MyCanvas.prototype = {
  isValid : function () {
    return (this.context2d != null);
  }
}

var Box = function (x, y, w, h, col, vx, vy, bbx, bby){
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
  this.color = col;
  this.vx = vx;
  this.vy = vy;
  this.bbx = bbx;
  this.bby = bby;
};

Box.prototype = {
  draw : function (ctx) {
    ctx.clearRect(this.x, this.y, this.w, this.h);
    var e;
    this.x += this.vx;
    if (this.vx > 0) {
      var e = this.x + this.w - this.bbx;
      if (e >= 0) {
        this.x -= e;
        this.vx *= -1;
      }
    }
    else {
      e = this.x;
      if (e <= 0) {
        this.x -= e;
        this.vx *= -1;
      }
    }
    this.y += this.vy;
    if (this.vy > 0) {
      e = this.y + this.h - this.bby;
      if (e >= 0) {
        this.y -= e;
        this.vy *= -1;
      }
    }
    else {
      e = this.y;
      if (e <= 0) {
        this.y -= e;
        this.vy *= -1;
      }
    }
    ctx.fillStyle = this.color;
    ctx.fillRect(this.x, this.y, this.w, this.h);
  }
};

main();
</script>

*1:結局「レガシー」の方で見つかった。いつの間にかAPIが刷新されていたらしい。現行のAPIはこの方法で使えないのか?