LoginSignup
1
1

More than 1 year has passed since last update.

【JavaScript】Canvasで単純なお絵描きツール

Last updated at Posted at 2022-03-28

サンプル

結論(ソース)

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
1
1
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
1
1