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>
相关推荐
初学者7.11 分钟前
lodash手写源码-cloneDeep,debounce,throttle
笔记·学习·loadsh
剪刀石头布啊38 分钟前
css属性值计算过程
前端·css
eggcode1 小时前
IDEA与Maven使用-学习记录(持续补充...)
学习·maven·intellij-idea
hrrrrb2 小时前
【CSS3】金丹篇
前端·css·css3
IT、木易2 小时前
大白话如何利用 CSS 实现一个三角形?原理是什么?
前端·css
charlie1145141913 小时前
从0开始的操作系统手搓教程33:挂载我们的文件系统
学习·系统架构·操作系统·教程·文件系统·手搓教程
雨墨C4 小时前
LLM学习之路-01-第一章-预训练/搞懂大模型的分词器(二)
人工智能·学习·自然语言处理·chatgpt·大模型·transformer
skywalk81634 小时前
OWL(Optimized Workforce Learning): 优化劳动力学习的通用智能体,用于处理现实世界的自动化任务(58.18 平均分)
人工智能·学习·自动化·agent
charlie1145141914 小时前
IMX6ULL驱动开发uboot篇02
驱动开发·学习·操作系统·内核·教程·uboot