Posted at

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

More than 3 years have passed since last update.


概要

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


提案


  • 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を使いました