LoginSignup
4
5

More than 5 years have passed since last update.

マウスドラッグのハンドリングに関するアイデア

Posted at

概要

マウスドラッグのハンドリングに関するアイデア

提案

  • mousedown で mousemove, mouseup を登録する関数を渡す

背景

ツール系アプリに鉛筆ツールや範囲選択ツールなど複数の機能を実装するにあたって、それぞれのツールをクラスとして作っていましたが、複雑だし this がカッコ悪いなぁと思いました。
JavaScript ではなるべく普通の変数、関数を使うのが良いと最近思うので、そのように書き直してみました。

元々のクラス

export class PencilMouseHandler {
  constructor(emitter) {
    this.emitter = emitter
  }

  onMouseDown(e) {
    const {offsetX, offsetY} = e
    this.startPosition = {x: offsetX, y: offsetY}
    this.emitter.trigger("start-pencil-drawing", this.startPosition)
  }

  onMouseMove(e) {
    const {offsetX, offsetY} = e
    this.emitter.trigger("move-pencil", {movement: {
      x: offsetX - this.startPosition.x,
      y: offsetY - this.startPosition.y
    }})
  }

  onMouseUp() {}
}

関数版1

イベントを登録する関数 onMouseDown, onMouseMove を渡すことで
this.emitterthis.startPosition を普通の変数にできました。

function handlePencilMouse(emitter, onMouseDown, onMouseMove, onMouseUp) {
  let startPosition

  onMouseDown(e => {
    const {offsetX, offsetY} = e
    startPosition = {x: offsetX, y: offsetY}
    emitter.trigger("start-pencil", startPosition)
  })

  onMouseMove(e => {
    const {offsetX, offsetY} = e
    emitter.trigger("move-pencil", {movement: {
      x: offsetX - this.startPosition.x,
      y: offsetY - this.startPosition.y
    }})
  })
}

(onMouseDown, onMouseMove, onMouseUp で登録した関数は mouseup 後に破棄されることにします)

関数版2

このアプリではマウスダウン中のドラッグしか扱わないので、onMouseDown で onMouseMove, onMouseUp を渡します。(提案する部分です)

これで onMouseMove, onMouseUp が onMouseDown の後に呼ばれることがハッキリするのと、let startPosition を const にできました。

function handlePencilMouse(emitter, onMouseDown) {
  onMouseDown((e, onMouseMove, onMouseUp) => {
    const {offsetX, offsetY} = e
    const startPosition = {x: offsetX, y: offsetY}
    emitter.trigger("start-pencil", startPosition)

    onMouseMove(e => {
      const {offsetX, offsetY} = e
      emitter.trigger("move-pencil", {movement: {
        x: offsetX - this.startPosition.x,
        y: offsetY - this.startPosition.y
      }})
    })
  })
}

関数版3

そもそも動作が onMouseDown から始まるので、関数自体を mousedown イベントに登録します

function handlePencilMouseDown(emitter, e, onMouseMove, onMouseUp) => {
  const {offsetX, offsetY} = e
  const startPosition = {x: offsetX, y: offsetY}
  emitter.trigger("start-pencil", startPosition)

  onMouseMove(e => {
    const {offsetX, offsetY} = e
    emitter.trigger("move-pencil", {movement: {
      x: offsetX - this.startPosition.x,
      y: offsetY - this.startPosition.y
    }})
  })
}

まとめ

  • クラスよりも関数を使いたい
  • mousedown 時に mouseup, mousemove を登録させると短くできる

オチ

読みづらいので実際のアプリでは関数版1を使いました

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5