サンプル
結論(ソース)
index.html
<canvas style="border: 1px solid black;" width="600" height="600"></canvas><!--
--><button id="clear-button" style="margin-left: 30px; user-select: none;">クリア</button>
<script src="drawingCanvas.js"></script>
<script src="main.js"></script>
main.js
const canvasHtmlElement = document.getElementsByTagName("canvas")[0];
const clearButtonHtmlElement = document.getElementById("clear-button");
const drawingCanvas = new DrawingCanvas(canvasHtmlElement);
["mousedown", "mouseover"].forEach(eventName => {
canvasHtmlElement.addEventListener(eventName, function(event) {
if (event.buttons !== 1) return; // 左クリック以外描画不可
drawingCanvas.drawStart();
});
});
["mouseup", "mouseout"].forEach(eventName => {
canvasHtmlElement.addEventListener(eventName, function(event) {
drawingCanvas.drawEnd(event.offsetX, event.offsetY);
});
});
canvasHtmlElement.addEventListener("mousemove", function(event) {
drawingCanvas.draw(event.offsetX, event.offsetY);
});
clearButtonHtmlElement.addEventListener("click", function() {
drawingCanvas.clear();
});
drawingCanvas
class DrawingCanvas {
#context; #lastPosition; #canDraw;
constructor(canvas) {
this.#context = canvas.getContext("2d");
this.#context.lineCap = "round";
this.#context.lineJoin = "round";
this.#context.lineWidth = 5;
this.#context.strokeStyle = "black";
this.#lastPosition = {x: null, y: null};
this.#canDraw = false;
}
draw(x, y) {
if(this.#canDraw === false) {
return;
}
if (this.#lastPosition.x === null || this.#lastPosition.y === null) {
this.#context.moveTo(x, y);
} else {
this.#context.moveTo(this.#lastPosition.x, this.#lastPosition.y);
}
this.#context.lineTo(x, y);
this.#context.stroke();
this.#lastPosition.x = x;
this.#lastPosition.y = y;
}
drawStart() {
this.#context.beginPath();
this.#canDraw = true;
}
drawEnd(x, y) {
this.draw(x, y); // クリックのみでドラッグされなかった場合、点を描画するために呼び出す。
this.#context.closePath();
this.#canDraw = false;
this.#lastPosition.x = null;
this.#lastPosition.y = null;
}
clear() {
const canvas = this.#context.canvas;
this.#context.clearRect(0, 0, canvas.width, canvas.height);
}
}
以上
参考元サイト
参考元サイトのソースとの違い
- contextの設定が一度だけ行われるようにした。
- 点が描けるようにした。
- mouseoverでも描けるようにした。
- event.layerX, event.layerY → event.offsetX, event.offsetY