KONVA イベントの実行順序調査!

こんにちは。石川さんです。
KONVAを使ってTMのお絵かきツールを作っています。しかし、イベントの処理順序がよく分からなくなってきましたので、実際のスクリプトで検証してみることにします。せっかくなので、皆さんにも結果を公開します!(必要なひと、滅多にいないと思いますが!(笑))

イベント一覧

KONVAのチュートリアルサイトの中にあるイベントに関する記事からイベントを抜き出しました。(左側に「EVENTS」と書いてあるところにある記事です。)そして、それぞれのオブジェクト毎にどのような順番で実行されるのか、出力するようにしてみます。

【マウスイベント】

  • mouseover
  • mouseout
  • mouseenter
  • mouseleave
  • mousemove
  • mousedown
  • mouseup
  • wheel
  • click
  • dblclick

【タッチイベント】

  • touchstart
  • touchmove
  • touchend
  • tap
  • dbltap

【ポインターイベント】

  • pointerdown
  • pointermove
  • pointereup
  • pointercancel
  • pointerover
  • pointerenter
  • pointerout
  • pointerleave
  • pointerclick
  • pointerdblclick

【ドラッグイベント】

  • dragstart
  • dragmove
  • dragend

【トランスフォームイベント】

  • transformstart
  • transform
  • transformend

実験です

先日お試しでjavascriptを組み込んでみましたが、今回もそれで試してみます!

赤い丸はドラッグ可能です。いろんなイベントを試してみてください。

ソースコード

<script src="https://unpkg.com/konva@9.2.0/konva.min.js"></script>
<div id="container20230724"></div>
<script>
  function writeMessage(message) {
    let lines = text.text().split("\n");
    lines.splice(0, lines.length - 10);
    if(lines[lines.length - 1].indexOf(message) == -1) {
      lines.push(message);
    } else {
      lines[lines.length - 1] = lines[lines.length - 1] + "."
    }
    text.text(lines.join("\n"));
  }

  var stage = new Konva.Stage({
    container: 'container20230724',
    width: window.innerWidth,
    height: 500/*window.innerHeight*/,
  });

  var layer = new Konva.Layer();

  var text = new Konva.Text({
    x: 10,
    y: 200,
    fontFamily: 'Calibri',
    fontSize: 24,
    text: '',
    fill: 'black',
  });

  var triangle = new Konva.RegularPolygon({
    x: 280,
    y: 120,
    sides: 3,
    radius: 80,
    fill: '#00D2FF',
    stroke: 'black',
    strokeWidth: 4,
    draggable: false,
  });

  var circle = new Konva.Circle({
    x: 430,
    y: 100,
    radius: 60,
    fill: 'red',
    stroke: 'black',
    strokeWidth: 4,
    draggable: true,
  });

  const KEVENTS = [{
  eventName:'MouseEvents',
      event:['mouseover','mouseout','mouseenter','mouseleave','mousemove',
             'mousedown','mouseup','wheel','click','dblclick',]
  },{
  eventName:'TouchEvents',
      event:['touchstart','touchmove','touchend','tap','dbltap',],
  },{
  eventName:'PointerEvents',
      event:['pointerdown','pointermove','pointereup','pointercancel','pointerover',
             'pointerenter','pointerout','pointerleave','pointerclick','pointerdblclick',],
  },{
  eventName:'DragEvents',
      event:['dragstart','dragmove','dragend',],
  },{
  eventName:'TransferEvent',
      event:['transformstart','transform','transformend',],
  }
  ]

  for(const e1 of KEVENTS) {
    for(const e2 of e1.event){
      stage.on(e2, (event) => { writeMessage(e1.eventName + " Stage " + e2); })
      triangle.on(e2, (event) => { writeMessage(e1.eventName + " Triangle " + e2); });
      circle.on(e2, (event) => { writeMessage(e1.eventName + " Circle " + e2); });
    }
  }

  layer.add(text);
  layer.add(triangle);
  layer.add(circle);

  // add the layer to the stage
  stage.add(layer);
</script>

ステージと三角と丸とテキストをつくって、テキスト以外のそれぞれにイベントを登録しました。テキストはイベント内容の出力用です。丸はドラッグ可能、▲はドラッグ不可能にセットして、それぞれイベントが発生したときに、発生したイベントをテキストに出力するようにしてみました。

まとめ

イベント、たくさんありますね!たくさんありすぎて、動かしていくと訳が分かりません。そのうち、イベントをオフにする機能も追加してわかりやすくしたいと思います。→と、思って色々とやってみましたが、HTML要素をプログラムで追加するとうまく表示を制御できなかったので、いったん諦めます。