一. 效果
二. 代码
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>