Posted at

Canvas をメソッドチェーンできるようにする

掲題の通り、今さら感漂う小ネタです。

Canvas 、というか Canvas コンテキストの関数はメソッドチェーン(めちゃくちゃ懐かしい)できないので、下記のようなダルい書き方を強いられるケースが多々あります。

context.beginPath()

context.moveTo(x1, y1)
context.lineTo(x2, y2)
context.lineTo(x3, y3)
context.closePath()
context.fillStyle = '#ff0000'
context.fill()

メソッドチェーンできればこう書けますよね。

context.fillStyle = '#ff0000'

context.beginPath().moveTo(x1, y1).lineTo(x2, y2).lineTo(x3, y3).closePath().fill()

どうやら「 undefined を返す」関数をラップして、「コンテキスト自体( this )を返す」ようにすれば良さそうです。

で、作ったのが下記スニペットです。

// Canvas Method Chaining

const prototype = CanvasRenderingContext2D.prototype
const exclusions = [ 'createImageData', 'createLinearGradient', 'createPattern', 'createRadialGradient', 'getImageData', 'getLineDash', 'getTransform', 'isPointInPath', 'isPointInStroke', 'measureText' ]
for (let key in prototype) {
try {
if (typeof prototype[key] === 'function' && exclusions.indexOf(key) === - 1) {
const f = prototype[key]
prototype[key] = function () {
f.apply(this, arguments)
return this
}
}
} catch (error) {}
}

だいぶ evil ですけどね。タイプ量減らしたいだけっていう…こういうのはプライベートでのみ使うようにしましょう(。ŏ﹏ŏ)