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>
相关推荐
葡萄成熟时 !2 分钟前
JAVA 常用API学习笔记
java·笔记·学习
别动我齐刘海2 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
0566464 小时前
agent学习——流式响应与文本切分
网络·python·学习
for_ever_love__5 小时前
python基础语法学习: 面向对象的三大特性
开发语言·python·学习
Canmag 兴隆磁性7 小时前
C 系列充磁机
c语言·开发语言·学习·永磁材料·充磁·退磁
PC2005-cloud7 小时前
Go学习笔记:基本概念与项目结构——GOPATH、Go Modules 与常用命令
笔记·学习·golang
新手unity自用笔记8 小时前
unity基于Socket的网络学习
网络·网络协议·学习·unity·c#·游戏引擎
zyf1044168 小时前
暑期实践日志 Day32:完成第六章字幕添加,推进工作
学习·计算机网络·剪辑·暑期实践·课题任务
小雪崩8 小时前
嵌入式学习 day27:标准IO
linux·c语言·学习
hsjiasb9 小时前
FreeRTOS学习(三十五)——系统架构综合项目
学习·学习笔记·freertos