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>
相关推荐
宇木灵3 小时前
C语言基础-十、文件操作
c语言·开发语言·学习
QQ24391976 小时前
语言在线考试与学习交流网页平台信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·spring boot·sql·学习·java-ee
程序员小李白7 小时前
CSS 盒子模型
前端·css·html
Zzz不能停7 小时前
单行 / 多行文本显示省略号(CSS 实现)
前端·css
键盘鼓手苏苏7 小时前
Flutter for OpenHarmony:csslib 强力 CSS 样式解析器,构建自定义渲染引擎的基石(Dart 官方解析库) 深度解析与鸿蒙适配指南
css·flutter·harmonyos
xiaoxue..7 小时前
TailwindCSS:从“样式民工”到“UI乐高大师”的逆袭
前端·css·ui
The_Uniform_C@t28 小时前
论文浅读(第三期)|摘自《UAV Resilience Against Stealthy Attacks》(第一节)
网络·物联网·学习·网络安全
青衫码上行8 小时前
高频 SQL 50题(基础版)| 查询 + 连接
数据库·sql·学习·mysql
宇木灵8 小时前
C语言基础学习-X0前置
c语言·开发语言·学习
希望之晨8 小时前
c++ 11 学习 override
开发语言·c++·学习