【前端】【canvas】在canvas中绘制和拖动

DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>在canvas中绘制和拖动title>
    <style>
        canvas {
            background-color: #ccc;
        }
    style>
head>

<body>
    <input type="color" />
    <canvas>canvas>

    <script>
        const colorPicker = document.querySelector('input');
        const cvs = document.querySelector('canvas');
        const ctx = cvs.getContext('2d');

        function init() {
            const w = 500,
                h = 300;
            cvs.width = w * devicePixelRatio;
            cvs.height = h * devicePixelRatio;
            cvs.style.width = w + 'px';
            cvs.style.height = h + 'px';

        }
        init();

        const shapes = [];

        class Rectangle {
            constructor(color, startX, startY) {
                this.color = color;
                this.startX = startX;
                this.startY = startY;
                this.endX = startX;
                this.endY = startY;
            }

            get minX() {
                return Math.min(this.startX, this.endX);
            }
            get maxX() {
                return Math.max(this.startX, this.endX);
            }
            get minY() {
                return Math.min(this.startY, this.endY);
            }
            get maxY() {
                return Math.max(this.startY, this.endY);
            }

            draw() {
                ctx.beginPath();
                ctx.lineTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio);
                ctx.lineTo(this.maxX * devicePixelRatio, this.minY * devicePixelRatio);
                ctx.lineTo(this.maxX * devicePixelRatio, this.maxY * devicePixelRatio);
                ctx.lineTo(this.minX * devicePixelRatio, this.maxY * devicePixelRatio);
                ctx.lineTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio);
                ctx.fillStyle = this.color;
                ctx.fill();
                ctx.strokeStyle = '#fff';
                ctx.lineCap = 'square';
                ctx.lineWidth = 3 * devicePixelRatio;
                ctx.stroke();
            }

            isInside(x, y) {
                return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
            }
        }

        // const rect = new Rectangle('#f00', 0, 0);
        // rect.endX = 300;
        // rect.endY = 300;
        // rect.draw();

        cvs.onmousedown = (e) => {
            const rect = cvs.getBoundingClientRect();
            const clickX = e.clientX - rect.left;
            const clickY = e.clientY - rect.top;
            const shape = getShape(clickX, clickY);
            if (shape) {
                // 拖到
                const { startX, startY, endX, endY } = shape;
                window.onmousemove = (e) => {
                    const disX = e.clientX - rect.left - clickX;
                    const disY = e.clientY - rect.top - clickY;
                    shape.startX = startX + disX;
                    shape.endX = endX + disX;
                    shape.startY = startY + disY;
                    shape.endY = endY + disY;
                }
            } else {
                // 新建
                const shape = new Rectangle(colorPicker.value, clickX, clickY)
                shapes.push(shape)
                window.onmousemove = (e) => {
                    shape.endX = e.clientX - rect.left;
                    shape.endY = e.clientY - rect.top;
                };
            }

            window.onmouseup = (e) => {
                window.onmousemove = null;
                window.onmouseup = null;
            };
        };

        function getShape(x, y) {
            for (let i = shapes.length - 1; i >= 0; i--) {
                const s = shapes[i];
                if (s.isInside(x, y)) {
                    return s;
                }
            }
            return null;
        }

        function draw() {
            requestAnimationFrame(draw);
            ctx.clearRect(0, 0, cvs.width, cvs.height);
            for (const s of shapes) {
                s.draw();
            }
        }
        draw();
    script>
body>

html>

效果:
【前端】【canvas】在canvas中绘制和拖动_第1张图片
【前端】【canvas】在canvas中绘制和拖动_第2张图片
【前端】【canvas】在canvas中绘制和拖动_第3张图片
【前端】【canvas】在canvas中绘制和拖动_第4张图片

你可能感兴趣的:(HTML,前端,javascript,开发语言)