问题描述
前端在采样canvas 绘制,可拖动矩形时,产生了一个bug,检查了很久找不到原因,请求大佬们解惑;
bug 演示
当图中有两个可拖动块时,拖动一个,另外一个 会发生小许的偏移
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>绘制</title>
</head>
<body>
<div style="display: flex">
<div style="width: 200px;margin-top: 100px;margin-right: 20px;margin-left: 10px">
<div draggable="true" id="box" style="width: 200px;height: 50px; background-color: #409eff"></div>
</div>
<div id="main" style="display: flex;justify-content: center;margin-top: 100px">
</div>
</div>
<script>
let mainCard = document.getElementById("main");
mainCard.ondrop = function(e) {
e.preventDefault();
console.log("进入");
let elementById = document.getElementById("main").querySelector("canvas");
let x = e.clientX - elementById.getBoundingClientRect().left;
let y = e.clientY - elementById.getBoundingClientRect().top;
let { canvas, ctx, image } = canvasData;
new CreateBlank(canvas, ctx, { x: x, y: y, width: 200, height: 50, image });
};
mainCard.ondragover = function(e) {
e.preventDefault();//解禁当前元素为可放置被拖拽元素的区域,即允许在此放置物体
};
let pathList = [];
class CreateBlank {
constructor(canvas, ctx, area) {
this.ctx = ctx;
this.canvas = canvas;
this.image = area.image;
//创建滑块
this.blob1 = this.createBlob(area.x, area.y, area.width, area.height, "#409eff", 1);
//绘制圆滑块
this.DrawBlob(this.blob1);
pathList.push(this.blob1);
let that = this;
//鼠标按下,将鼠标按下坐标保存在x,y中
this.canvas.onmousedown = function(e) {
//记录鼠标所在位置的坐标
that.x = e.clientX - that.canvas.getBoundingClientRect().left;
that.y = e.clientY - that.canvas.getBoundingClientRect().top;
pathList.forEach((res) => {
res.InnerWidth = that.x - res.x;
res.InnerHeight = that.y - res.y;
that.drag(res, that.x, that.y);
});
};
}
//拖拽函数
drag(blob, x, y) {
// 判断鼠标是否在检测区域
let bo = this.getBounds(blob);
if (this.containsPoint(bo, x, y)) {
let that = this;
//注册鼠标移动事件
this.canvas.onmousemove = function(e) {
let x = e.clientX - that.canvas.getBoundingClientRect().left;
let y = e.clientY - that.canvas.getBoundingClientRect().top;
//清除画布内容
that.ctx.clearRect(0, 0, bo.width, bo.height);
that.ctx.drawImage(that.image, 0, 0);
pathList.forEach(res => {
that.DrawBlob(res);
if (bo.name === res.name) {
//更新块所在的位置
res.x = x - res.InnerWidth;
res.y = y - res.InnerHeight;
}
});
};
//注册鼠标松开事件
this.canvas.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
};
}
}
//创建圆滑块
createBlob(x, y, width, height, color, alpha) {
//定义对象
let blob = {};
blob.alpha = alpha;
blob.color = color;
blob.x = x;
blob.y = y;
blob.width = width;
blob.height = height;
blob.InnerWidth = 0;
blob.InnerHeight = 0;
blob.name = Symbol("name");
return blob;
};
DrawBlob(blob) {
this.ctx.globalAlpha = blob.alpha;
this.ctx.beginPath();
this.ctx.fillStyle = blob.color;
this.ctx.rect(blob.x, blob.y, blob.width, blob.height);
this.ctx.fill();
this.ctx.closePath();
this.ctx.globalAlpha = 1;
};
//获取检测区域
getBounds(blob) {
return {
x: blob.x,
y: blob.y,
width: blob.width,
height: blob.height,
name: blob.name
};
}
//判断鼠标是否点击在指定检测区域
containsPoint(rect, x, y) {
return !(x < rect.x || x > rect.x + rect.width ||
y < rect.y || y > rect.y + rect.height);
}
}
function createCanvas(id) {
let elementById = document.getElementById(id);
return new Promise((resolve, reject) => {
let canvas = document.createElement("canvas");
let image = new Image();
image.src = "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg";
// 如果有缓存,读缓存
image.onload = function() {
image.onload = null; // 避免重复加载
canvas.height = image.height;
canvas.width = image.width;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
elementById.appendChild(canvas);
resolve({ canvas, ctx, image });
};
image.onerror = function() {
reject();
};
});
}
let canvasData = {};
createCanvas("main").then(res => {
canvasData = res;
});
</script>
</body>
</html>
我想要达到的结果
移动另外一个时,原本内容保持原有状态