canvas基础学习(鼠标点位拖拽)

一. 效果

二. 代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            overflow: hidden;
            margin: 0;
            padding: 0;
        }

        #div {
            width: 100%;
            height: 100vh;
        }

        #canvas {
            width: 100%;
            height: 100%;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="div">
        <canvas id="canvas"></canvas>
    </div>
    <script>
        // 获取元素
        const canvas = document.getElementById("canvas");
        const div = document.getElementById("div");
        // 获取canvas画布
        const ctx = canvas.getContext("2d");
        // 获取宽高
        const w = div.offsetWidth;
        const h = div.offsetHeight;
        // 设置宽高
        canvas.width = w;
        canvas.height = h;

        // 是否可以拖拽
        let isMove = false
        // 点位对象数组
        let pointList = [];

        // 构造点位函数  批量生产点位
        function Point(x, y, color) {
            // 点位坐标
            this.x = x;
            this.y = y;
            // 点位颜色
            this.color = color;
            // 点位半径
            this.r = 20;
        }

        // 绘制点位函数
        Point.prototype.draw = function () {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
            ctx.fillStyle = this.color;
            ctx.fill();
        }

        // 鼠标点击事件
        div.addEventListener("mousedown", (e) => {
            // 鼠标的坐标
            let x = e.clientX;
            let y = e.clientY;

            // 点位坐标和鼠标坐标的距离
            for (let i = 0; i < pointList.length; i++) {
                let point = pointList[i];
                // 勾股定理判断  鼠标在点位的半径内
                let distance = Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2));
                if (distance < point.r) {
                    // 将点位放到数组的第一位
                    let obj = pointList[i];
                    pointList[i] = pointList[0]
                    pointList[0] = obj
                    // 开启拖拽
                    isMove = true
                }
            }
        })

        // 鼠标移动事件
        div.addEventListener("mousemove", (e) => {
            // 鼠标的坐标
            let x = e.clientX;
            let y = e.clientY;
            // 判断鼠标是否变为手指
            let boolean = false;
            // 鼠标是否在点位的半径内
            for (let i = 0; i < pointList.length; i++) {
                let point = pointList[i];
                let distance = Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2));
                if (distance < point.r) {
                    // 鼠标变为手指
                    boolean = true
                }
            }

            // 拖拽点位(鼠标点击时已经将拖拽点位提到了点位数组的第一个所以只需要将第一个点位的坐标改为鼠标的坐标即可)
            if (isMove) {
                pointList[0].x = x;
                pointList[0].y = y;
                // 清除画布  
                ctx.clearRect(0, 0, w, h);
                // 重新绘制点位
                for (let i = 0; i < pointList.length; i++) {
                    if (i !== 0) {
                        let point = pointList[i];
                        point.draw();
                    }
                }
                // 最后绘制的点位层级最高
                pointList[0].draw();

            }
            // 鼠标是否变为手指
            if (boolean) {
                div.style.cursor = 'pointer'
            } else {
                div.style.cursor = 'default'
            }

        })

        // 鼠标抬起事件
        div.addEventListener("mouseup", (e) => {
            // 关闭拖拽
            isMove = false
        })

        // 随机生成点位  随机颜色  随机坐标
        for (let i = 0; i < 10; i++) {
            let point = new Point(Math.random() * w, Math.random() * h, "hsl(" + Math.random() * 360 + ", 100%, 50%)");
            pointList.push(point);
            point.draw();
        }


    </script>
</body>

</html>
相关推荐
xiaoxiaoxiaolll20 分钟前
金刚石基植入体新突破!Adv. Funct. Mater. 报道首例增材制造固态摩擦电能量收集器
学习
x.Jessica27 分钟前
网络的构成元素
网络·学习·计算机网络
yiqiqukanhaiba1 小时前
STM32学习笔记14-I2C硬件控制
笔记·stm32·学习
悠哉悠哉愿意1 小时前
【Python语法基础学习笔记】if语句
笔记·python·学习
杜子不疼.2 小时前
《Python学习之第三方库:开启无限可能》
开发语言·python·学习
小张的博客之旅3 小时前
宁波市第八届网络安全大赛初赛(REVERSE-Writeup)
学习·网络安全·reverse
墨雨听阁4 小时前
8.18网络编程——基于UDP的TFTP文件传输客户端
网络·网络协议·学习·udp
小晶晶京京4 小时前
day35-负载均衡
运维·网络·网络协议·学习·负载均衡
前端老鹰4 小时前
CSS backdrop-filter:给元素背景添加模糊与色调的高级滤镜
前端·css·html
long3166 小时前
构建者设计模式 Builder
java·后端·学习·设计模式