Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

Canvasお絵描きツールをjQuery Mobileで

こんにちは、間藤です。

以前中山が「Windows8 + IE10 でCanvasお絵描きツールを」という記事を書きました。この記事では、IE10におけるタッチイベントの扱いが、MS独自仕様になっているということに触れていました。これは、マルチタッチ対応などの用途に利用することを想定したものだということでしたが、記事に掲載していたサンプルは、その恩恵に預かるためのコードではありませんでした。
そこで、MS独自仕様に対応するための分岐を記述しないように、サンプルを書き換えてみたいと思います。

仮想イベント

クロスブラウザ対応のために、今回は「jQuery Mobile」を利用したいと思います。「jQuery Mobile」には、「仮想イベント」というものが用意されています。これは、タッチ関連のイベントと、マウス関連のイベントを統合したイベントです。例えば、「vclick」という仮想イベントは、タッチイベントのtouchend、マウスイベントのclickを統合したイベントです。
今回作成するお絵描きツールでは、以下の4つの仮想イベントをハンドリングします。

仮想イベント マウスイベント タッチイベント
vmousedown mousedown touchstart
vmousemove mousemove touchmove
vmouseup mouseup touchend
vmouseout mouseout touchend

canvasの扱いについて

なるべく元のサンプルコードから乖離しないように修正しようと考えていましたが、canvasの幅が固定になっていたのが気になったので、ここは修正することにしました。

【元のサンプルコード】

<div style="width:600px;border:2px solid #808080;">
  <!-- disables scrolling by "-ms-touch-action:none" -->
  <canvas id="myCanvas" height="400" width="600" style="-ms-touch-action:none;"></canvas>
</div>

【修正後のコード】

<div style="margin:auto; width:90%; border:2px solid #808080;">
  <canvas id="myCanvas" style="width:100%; height:400px; -ms-touch-action:none;"></canvas>
</div>

ただ、このようにすることで、canvasの幅は可変になります。ところが、何もしないでおくと、canvasのwidth属性およびheight属性が正しく設定されないことがわかりました。そのため、イベントオブジェクトから取得される座標系と、canvasの座標系がずれてしまい、正しく描画が行われません。そこで、canvasのwidth属性とheight属性に、正しい値を設定するための関数を用意しました。

initCanvas : function() {
  this.canvas.get(0).width = this.canvas.width();
  this.canvas.get(0).height = this.canvas.height();
  this.context = this.canvas.get(0).getContext("2d");
  this.setPencil();
},

ここでthis.canvasには、jQueryのラップ集合が格納されています。

this.canvas = $("#myCanvas");

このあたりのcanvasに関する情報は、以下のサイトから得ました。

http://www.html5.jp/tag/elements/canvas.html

また、デバイスの回転時や、ブラウザウィンドウサイズの変更時に、initCanvas関数を呼び出すようにしています。但し、これによって描画していた内容はクリアされることになります。

サンプル

サンプルをjsdo.itに掲載しました。IE10でも描画できることが確認できます。

やはり、厄介なクロスブラウザ問題への対処は、jQueryなどのライブラリになるべく任せて、本質的なアプリケーション開発に注力できるようにしたいですね。