Next2D NoCode ToolでJavaScriptを使う[中級編]

今日はマウス・タップのイベント制御に関して書きたいと思います。

# EventDispatcher
マウス・タップのイベント制御は`EventDispatcher`クラスが管理・実行しています。
このクラスで実装されている機能や関数を紹介します。
まずは、イベント発火順番と機能を紹介します。

## イベントフェーズ
イベントフェーズは`キャプチャ段階`、`ターゲット段階`、`バブリング段階`の3段階に別れており、イベントが発火する順番は

1. キャプチャ段階
2. ターゲット段階
3. バブリング段階

の順番で実行されていきます。

## キャプチャ段階(use_capture)
祖先要素(Stage)から子孫(イベント発火したDisplayObject)に向かって順番に実行されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/2f069477-6966-28c6-0716-9bc49d5aec45.png" width="500">

`MovieClipC`の`parent`は`MovieClipB`
`MovieClipB`の`parent`は`MovieClipA`
`MovieClipA`の`parent`は`RootMovieClip`
`RootMovieClip`の`parent`は`Stage`
という親子関係の場合で、`MovieClipC`が発火元で、その他、全てのDisplayObjectにキャプチャイベントが登録されていた場合の`キャプチャ段階`の実行順番は

1. Stage
2. RootMovieClip
3. MovieClipA
4. MovieClipB

という順番で実行されていきます。

## ターゲット段階
イベント発火元のDisplayObjectに登録されたイベントが実行されます。
今回の例だと`MovieClipC`に登録されたイベントが実行されます。
実行される順番は`addEventListener`の第四引数の`priority`の数字の大きい順番に実行されます。
デフォルト値は`0`の為、引数に指定がない場合は登録順に実行されます。

## バブリング段階（bubbles）
キャプチャ段階とは逆に、イベントの発火したDisplayObjectから祖先要素(Stage)までさかのぼってイベントを伝搬させる機能で、異なるDisplayObject間でのイベント伝搬が可能になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/de1a4dcb-e641-1195-ca50-9c9cd7381378.png" width="500">

1. MovieClipB
2. MovieClipA
3. RootMovieClip
4. Stage

という順番で実行されていきます。



# マウスイベント
次にイベントの種類を紹介します。マウスイベントはスマートフォンでの閲覧時は自動的にタッチイベントに切り替わります。その為、タッチイベントクラスは存在せず、マウスイベントクラスでタッチ機能も実装しています。

マウスイベントクラスの呼び出しサンプル

```javascript
const { MouseEvent } = next2d.events;
```

イベント名|バブリング|説明
---|---|---
MouseEvent.DOUBLE_CLICK|true|対象のDisplayObject上でマウスをダブルクリックした際に発火します。※タップイベントには対応していません。
MouseEvent.MOUSE_DOWN|true|対象のDisplayObject上でマウスを押下、もしくは画面をタップした際に発火します。
MouseEvent.MOUSE_UP|true|対象のDisplayObject上でマウスを押下し離した、もしくは画面をタップし離した際に発火します。
MouseEvent.MOUSE_MOVE|true|対象のDisplayObject上でマウスを移動した、もしくは画面をタップし移動した際に発火します。
MouseEvent.MOUSE_OVER|true|対象のDisplayObject上にマウスがヒットした際に発火します。※タップイベントには対応していません。
MouseEvent.MOUSE_OUT|true|対象のDisplayObject上にあったマウスが外れた際に発火します。
MouseEvent.ROLL_OVER|false|対象のDisplayObject上にマウスがヒットした際に発火します。MOUSE_OVERと大きく違う点はbubblesがfalseの為、バブリングが発生しません。※タップイベントには対応していません。
MouseEvent.ROLL_OUT|false|対象のDisplayObject上にあったマウスが外れた際に発火します。MOUSE_OUTと大きく違う点はbubblesがfalseの為、バブリングが発生しません。
MouseEvent.MOUSE_WHEEL|true|対象のDisplayObject上でマウスホイールを動かした際に発火します。※タップイベントには対応していません。

# イベントの登録・削除
イベントを登録して発火するサンプルコードと登録したイベントを削除するサンプルコードを記載します。

## addEventListener
任意のイベント名に対して、コールバック関数を登録する事ができます。

プロパティ|型|初期値|説明
---|---|---|---
type|string|必須|イベント名
listener|function|必須|コールバック関数
use_capture|boolean|false|trueにした場合キャプチャイベントとして登録されます。
priority|number|0|イベントの実行順番、降順で実行されます。

### 事前技術共有
DisplayObjectには任意の名前を付ける事ができ、名前を付与したDisplayObjectは`this.{{名前}}`でアクセスする事が可能になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/065e031c-2255-31d2-b979-61e20e0d13f1.png" width="500">
今回は`mc`という名前を付与します。

```javascript
const { MouseEvent } = next2d.events;

this.mc.addEventListener(MouseEvent.MOUSE_DOWN, (event) => 
{
    event.currentTarget.startDrag();
});

this.mc.addEventListener(MouseEvent.MOUSE_UP, (event) => 
{
    event.currentTarget.stopDrag();
});
```

サンプルコードでは、クリックもしくはタップしたタイミングで対象のDisplayObjectの座標移動を可能にする`startDrag`を実行します。マウスもしくはタップを離すと、移動を終了する`stopDrag`を実行します。
### 動作サンプル動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/1QDAauMOnC0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## removeEventListener
任意のイベント名で登録されているコールバック関数を削除する事ができます。

プロパティ|型|初期値|説明
---|---|---|---
type|string|必須|イベント名
listener|function|必須|コールバック関数
use_capture|boolean|false|trueにした場合キャプチャイベントを削除します。

```javascript
const { MouseEvent } = next2d.events;

this.mc.addEventListener(MouseEvent.MOUSE_DOWN, (event) => 
{
    event.currentTarget.alpha = 0.5;
    event.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN, event.listener);
});

this.mc.addEventListener(MouseEvent.MOUSE_UP, (event) => 
{
    event.currentTarget.alpha = 1.0;
    event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, event.listener);
});
```

サンプルコードでは、クリックもしくはタップしたタイミングで対象のDisplayObjectを半透明(0.5)にして、イベントを削除します。その後、マウス、もしくはタップを離したタイミングで対象のDisplayObjectを透明度を元に戻して、イベントを削除します。二回目以降に対象のDisplayObjectをクリックもしくはタップしてもイベントを削除してる為、何も起こりません。

### 動作サンプル動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/oeds0zwxlNw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

如何だったでしょうか？
もし、この記事を見て、興味が出た方はこちらか動作確認ができます。
[NoCode Tool](https://tool.next2d.app)

また、その他の関数に関しては、`Next2D Player`の[API Docs](https://next2d.app/docs/player/)から閲覧できます。

明日はタイムラインでの変数の利用方法を紹介ができればと思います。