jQueryでCanvasを使ってお絵かき - 実践編

このエントリーをはてなブックマークに追加
ご無沙汰しております、株式会社シャノン技術統括部プロダクト開発部のHealerです。

あけましておめでとうございます。
冬も本番となり、寒さが厳しくなってきましたが、お風邪などを召しておられませんでしょうか?
そして本年も本ブログともども、弊社株式会社シャノンをよろしくお願い致します。

さて、前回、
jCanvas(jQueryプラグイン)でCanvasを使ってお絵かき - 対応ブラウザ確認編
なるものを書いてから早半年以上空いてしまいました。。
実はスケジュールの都合が合わなくて1回パスをしているんです。
当ブログは基本的に当番制でスケジュールの割り当てをいただいて技術部内の人間が順繰りに書いていくわけですが、1回だけパスが認められています。
従って、1回パスをしたところ、今回は捕まえられてどうにも逃げられず書いている次第です。(笑)

という冗談はさておき、今回は
jQueryでCanvasを使ってお絵かき - 実践編
です。
良質な読み物エントリの多いブログですが、
作ったもので遊べる系エントリでニッチなところを攻めていきたいと思います。

ん?前回とタイトルを比べてみましょう。

jCanvas(jQueryプラグイン)でCanvasを使ってお絵かき - 対応ブラウザ確認編
jQueryでCanvasを使ってお絵かき - 実践編

jCanvasという言葉が消えましたね。。
そうなんです。
CanvasをjQueryでいじくり倒す目的は変わりないのですが、
とある事情のためjCanvasを使わなくなってしまったんです。

そのとある事情とは、描いた図形を動かして動的に線で繋げたい!という事情です。
絵を描くだけならjCanvasでもよかったんですが、
下にある要件を満たすために描いた図形を動かしたかったのですが、
うまく動かすことが出来なかったので
今回は、
HTML5のCanvas図形をクリッカブルにするjQueryプラグイン ClickableCanvas
を使うことにしました。
こちらの方が色々なアニメーションチックな動きにも対応していて、
かつ書き方自体もjCanvasと同じくCSSライクな記法が使えるので簡単で助かりました。

さて、ここからは実際に作ってみたサンプルを元にClickableCanvasを見ていきたいと思います。

作ったサンプルはこちら。(Internet Exproler以外で開いてください)
Cooperation Checker with Canvas
PC限定ですが触ってみてください。
(Flashに変換したIE対応版を近日中に公開します)

作る際に念頭においた要件は以下のとおりです。
  1. サッカーのフィールドに11人+ベンチ5人を並べて好き勝手にフォーメーションを組めるようにしたい
  2. ゴールキーパーとベンチは動かさない
  3. 各ポジションは色を別にして見やすく
  4. 移動してポジションが変わったら色もそのポジションのものに変わる
  5. 動物占い準拠で相性の良し悪しが一目で分かる(おまけ)
要するに、某S◯GA社のアーケードサッカーカードゲームのチーム編成をする時に、
自分のチームの選手の相性が視覚的にチェックできるといいよね、というものです。
何のことかわからない方は捨て置いてください。(笑)

jQuery ClickableCanvas デモページ2
を参考に作りました。

まずjQueryとClickableCanvasを使う用意をしましょう。
HEADタグに
<script src="js/jquery-1.6.1.min.js" type="text/javascript"></script>
<script src="js/jquery.clickablecanvas.v1.4.js" type="text/javascript"></script>
BODYタグに
<div id="field" class="test"></div>
のようにすれば十分です。

まずはCanvas全体のスタイルを指定しましょう。
これが下地になります。
<style type="text/css">
#field {
margin: 15px 30px;
width: 550px;
height: 600px;
position: absolute;
background-color: #00800;
zIndex: 0;
}
</style>

そして、
var cc = $('#field').clickableCanvas({ flashCanvas: true });
のようにclickableCanvasのオブジェクトを用意すれば、
後はひたすら図形を書いていくだけです。

以下のようにcreateShapeメソッドを使って書いていきます。
cc.createShape({
name: 'center_circle',
type: 'circle',
coords: { x: 225, y: 2, r: 50 },
attr: { shapeZIndex: 0 },
style: {
lineWidth: 2.0,
strokeStyle: '#ffffff',
noFill: true
}
});
name(図形の名前)、type(図形の形)、coords(図形の座標など)が必須項目で、
style(デフォルト)、hoverStyle(ポインタが乗ったとき)、activeStyle(クリックしたとき)のスタイルを指定することが出来ます。
また、styleの代わりにgradientを使うとグラデーション付きスタイルを指定できます。
図形にテキストを追加したいときはtextStyleを指定することでテキストが追加されます。
下記のように、イベントハンドラも実装されていますので、
イベントを機に図形を新たに描画したりすることも出来ます。
onClick: function(shape, coord) {
shape.name.match(/player(\d+)/);
ppoint[RegExp.$1] = false;
},
ここでの 第1引数は図形オブジェクト、第2引数はカーソル座標が渡されます。

今回作成したサンプルの範囲だと、このくらいで事足りますが、
他にもanimateShapeというアニメーションを行うことの出来るメソッドも用意されています。

サンプルに関してですが、
まず画面のロード時にフィールドの描画と選手の初期配置を行うようにしました。
選手の描画には、
textStyleでその選手の番号を表示し、
hoverStyleでカーソルを載せたときに色が変わるようにしました。
onMouseDownで

ppoint[s] = true;

とすることによって移動を可能にし、
onMouseMoveで移動前、移動後の座標の差を計算して図形を移動させるようにしてあります。

shape.coords.x += (x[num] - preX[num]);
shape.coords.y += (y[num] - preY[num]);
var pos = position = checkPosition(shape.coords.x,shape.coords.y, false);
shape.normal.fillStyle = positions[pos];

onMouseMoveはかなり細かく移動を認識するので重たい処理を書くと
図形の移動がスムーズに見えなくなるので注意が必要です。
移動後の座標から、ポジションが変わっていたら色を変えるようにしてあります。

ppoint[RegExp.$1] = false;

最後にonClickで再び図形の移動を不許可にしています。


ここまでで要件の4まで満たしており、かなり簡単に図形の描画と移動を行うことが出来ました。

5の要件に関しては、
各選手に対応するselectタグを配置して 、
選択された値をinputタグに保存しておいて
onMouseOverで動物占いの相性によって色付きの線が出るようにしました。
最も相性がいい場合が金色で以下、赤、青、白、グレーの順になっています。
グリグリ動かしたりして、色々試して遊んで挙動を楽しんでみてください。



最後に、個人的な不満点や課題をいくつか。

まずコードが汚くなってしまったこと。。
設定関連の値をゴチャ混ぜに書いてしまったため、かなり汚いです。
読者の方には申し訳ないですが今回は我慢していただいて、
次回はそのへんを整理して別のファイルに切り出すなどしてコードの可読性を上げたいと思います。
時間が取れれば今回の分も書き直します。

ClickableCanvasを最終的に使いこなすところまで持って行けなかったところも課題です。
実は、色付きの線が描画された状態で 選手を移動すると線だけ残ります。。
各選手に一旦カーソルを当てると順次描画しなおすので消えていきますが、
最後まで解決方法が分かりませんでした。
それにともなってエラーが出る場合もあります。
このようなバグを残さないよう精進していきます。

後はCanvasそのものに対する不満です。
今回、textStyleに選手の番号をいれていますが、
当初の構想では番号を入れると同時に指定されている動物の名前も直上に表示するつもりでした。
また、select要素もページ上に常に表示しておくのではなく、
ポインタが当たった時点でフロートのようにselect要素を表示しようと考えたのですが、
残念ながら現在はHTMLのレンダリングには対応しておらず、
タグはエスケープされて表示されます。
仕様書の通りなら可能になるはずなので、早めに対応して欲しいものですね。

次回はこの可動式Canvasサンプルをスマートフォンで動かせるようにしていきたいと思います。手元のiPhoneのSafariだとフィールドの描画とポインタ乗せ時の線の描画まではされたんですが、
配置をいじることは出来ませんでした。
何かまた違った要素があるようですね。
その辺を勉強してみます。


以上、JavaScriptだけでこんなにお絵かき出来るんだ!のコーナーでした。
業務とは全く関係の無いエントリですいません。。
次の記事
« Prev Post
前の記事
Next Post »
Related Posts Plugin for WordPress, Blogger...