サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

EaselJS 0.7.0でインスタンスをドラッグ&ドロップする

ID: FN1310003 Technique: HTML5 and JavaScript Library: EaselJS 0.7.0

2013年9月25日にCreateJSの新バージョンがリリースされました。EaselJSは0.7.0になります。とくにイベントモデルが大きく変わりました。イベントがより扱いやすくなり、一貫した仕組みになります(「EaselJS次期バージョンのイベントモデル改訂」参照)。前のバージョンとスクリプティングが変わった例として、インスタンスのドラッグ&ドロップを採上げます。


01 ドラッグ&ドロップをマウスイベントでどう扱うか

インスタンスのドラッグ&ドロップは、3つのイベントを組合わせて行います。(1)インスタンスのうえでマウスボタンを押したとき、ドラッグを始めます。(2)マウスのボタンをプレスしたまま動かすと、インスタンスの位置をポインタに追随させます。(3)マウスボタンを放したら、ドラッグが終わります。これら3つのイベントは、つぎの表001のとおりDisplayObjectクラスに定められています。

表001■ドラッグ&ドロップに用いるDisplayObjectクラスのマウスイベント
DisplayObjectクラスの
マウスイベント
マウス操作
mousedown インスタンス上でマウスボタンが押された。
pressmove インスタンス上でマウスボタンが押されたまま、ポインタが動かされた。
pressup インスタンス上で押されたマウスボタンが放された。

前のEaselJS 0.6.1では、上述のマウス操作で(2)マウスボタンを押したまま動かし、(3)マウスボタンを放すイベントはMouseEventクラスが扱いました。これらのイベントを表示リストのインスタンスすべてにゆき渡らせると、負荷が大きくなり過ぎます。そのため、マウスボタンが押されたインスタンスに対するマウス操作だけを見るようにしたのです。

とはいえ、このままではマウスイベントを扱うクラスがふたつに分かれて整合性に欠けます。そこで、EaselJS 0.7.0ではイベントをDisplayObjectクラスにまとめる替わりに、インスタンス上でマウスボタンが押されたことを前提としたのです(「EaselJSの次期バージョンにおけるイベントのバブリングとマウスイベント」参照)。

DisplayObjectインスタンスのマウスイベントにリスナーを加えるには、EventDispatcher.addEventListener()メソッドを用います。第1引数はイベントの名前(種類)、第2引数がイベントで呼出すリスナー関数です。イベントの処理が済んで要らなくなったリスナーは、EventDispatcher.removeEventListener()メソッドで除きます。引数はEventDispatcher.addEventListener()メソッドと揃えます。

オブジェクト.addEventListener(イベント, リスナー関数)

オブジェクト.removeEventListener(イベント, リスナー関数)


02 ステージにインスタンスを置く

ドラッグ&ドロップの処理の前に、ドラッグするインスタンスをステージにつくります。矩形のShapeインスタンスを真ん中に置きましょう(図001)。HTMLドキュメントのbody要素にはcanvas要素を加え、JavaScriptで扱えるようにid属性("myCanvas")も定めておきます。なお、コードは後で全体を掲げます(コード001)。行番号もそのコードにもとづきます。

  1. <canvas id="myCanvas" width="240" height="180"></canvas>

図001■ステージに置かれたShapeインスタンス
図001

Shapeインスタンスをつくって返す関数(createShape())は新たに定めました(第27〜33行目)。引数にはxy座標値を与えます。また、ShapeインスタンスのShape.graphicsプロパティを別の関数(drawRectangle())に渡して、矩形を描いています(第34〜39行目)。そうしてつくったShapeインスタンスをStageオブジェクトの表示リストに加えます(第6および第8行目)。

  1. var stage;
  2. var canvasElement = document.getElementById("myCanvas");
  3. var instance = createShape(canvasElement.width / 2, canvasElement.height / 2);
  4. stage = new createjs.Stage(canvasElement);
  5. stage.addChild(instance);
  6. stage.update();
  1. function createShape(x, y) {
  2.   var instance = new createjs.Shape();
  3.   instance.x = x;
  4.   instance.y = y;
  5.   drawRectangle(instance.graphics);
  6.   return instance;
  7. }
  8. function drawRectangle(myGraphics) {
  9.   var randomNumber = Math.floor(Math.random() * 0xFFFFFF);
  10.   myGraphics.beginStroke("blue");
  11.   myGraphics.beginFill("cyan");
  12.   myGraphics.drawRect(-20, -20, 40, 40);
  13. }

03 ドラッグ&ドロップのスクリプトを組立てる

では、本題のドラッグ&ドロップです。第1に、インスタンスのDisplayObject.mousedownイベントにリスナー(startDrag())を加えます(第10行目)。リスナー関数は、引数のオブジェクト(eventObject)のEvent.targetプロパティからマウス操作をしたインスタンス(instance)が得られますので、そのDisplayObject.pressmoveイベントにドラッグのための関数(drag())をリスナーとして加えます(第12〜13行目)。

第2に、インスタンスをドラッグするリスナー関数(drag())は、引数のオブジェクト(eventObject)のMouseEvent.stageXおよびMouseEvent.stageYプロパティでマウスポインタのステージ上の座標を調べて、インスタンス(instance)のxy座標に与えます(第17〜19行目)。これで、マウスポインタの位置に合わせてインスタンスが動きます。

  1. instance.addEventListener("mousedown", startDrag);
  2. function startDrag(eventObject) {
  3.   var instance = eventObject.target;
  4.   instance.addEventListener("pressmove", drag);
  1. }
  2. function drag(eventObject) {
  3.   var instance = eventObject.target;
  4.   instance.x = eventObject.stageX;
  5.   instance.y = eventObject.stageY;
  6.   stage.update();
  7. }

これでマウスボタンを放せば、ドラッグは止まります。けれど、DisplayObject.pressmoveイベントのリスナー(drag())がまだ残っています。このままでは、マウスイベントを扱ううえで意図しない問題が起こるかもしれません。

そこで第3に、要らなくなったマウスイベントのリスナーは除きます。その処理は、DisplayObject.pressupイベントのリスナー(stopDrag())として、マウスボタンを押したときのリスナー関数(startDrag())で加えます(第14行目)。そして、マウスボタンを放したときのリスナーは、DisplayObject.pressmoveDisplayObject.pressupイベントのリスナーをそれぞれインスタンスから除きます(第23〜25行目)。

  1. function startDrag(eventObject) {
  1.   instance.addEventListener("pressup", stopDrag);
  2. }
  1. function stopDrag(eventObject) {
  2.   var instance = eventObject.target;
  3.   instance.removeEventListener("pressmove", drag);
  4.   instance.removeEventListener("pressup", stopDrag);
  5. }

インスタンスのごく基本的なドラッグ&ドロップの処理が、これで組立てられます(図002)。script要素はbody要素に加えました。body要素の全体は、以下のコード001のとおりです。また、jsdo.itにコードを掲げ、そのリンクを添えましたので、ご参照ください。

図002■ステージのShapeインスタンスをドラッグ&ドロップする
図002

コード001■インスタンスをドラッグ&ドロップする
  1. <body>
  2. <canvas id="myCanvas" width="240" height="180"></canvas>
  3. <script>
  4. var stage;
  5. var canvasElement = document.getElementById("myCanvas");
  6. var instance = createShape(canvasElement.width / 2, canvasElement.height / 2);
  7. stage = new createjs.Stage(canvasElement);
  8. stage.addChild(instance);
  9. stage.update();
  10. instance.addEventListener("mousedown", startDrag);
  11. function startDrag(eventObject) {
  12.   var instance = eventObject.target;
  13.   instance.addEventListener("pressmove", drag);
  14.   instance.addEventListener("pressup", stopDrag);
  15. }
  16. function drag(eventObject) {
  17.   var instance = eventObject.target;
  18.   instance.x = eventObject.stageX;
  19.   instance.y = eventObject.stageY;
  20.   stage.update();
  21. }
  22. function stopDrag(eventObject) {
  23.   var instance = eventObject.target;
  24.   instance.removeEventListener("pressmove", drag);
  25.   instance.removeEventListener("pressup", stopDrag);
  26. }
  27. function createShape(x, y) {
  28.   var instance = new createjs.Shape();
  29.   instance.x = x;
  30.   instance.y = y;
  31.   drawRectangle(instance.graphics);
  32.   return instance;
  33. }
  34. function drawRectangle(myGraphics) {
  35.   var randomNumber = Math.floor(Math.random() * 0xFFFFFF);
  36.   myGraphics.beginStroke("blue");
  37.   myGraphics.beginFill("cyan");
  38.   myGraphics.drawRect(-20, -20, 40, 40);
  39. }
  40. </script>
  41. </body>


作成者: 野中文雄
作成日: 2013年10月22日


Copyright © 2001-2013 Fumio Nonaka.  All rights reserved.