接上篇的业务,实现了基础的画图,选中与拖动的效果,还有点细节问题,多个元素重叠在一起,选中的不能在最上面显示,以及最后绘制的元素要能覆盖前面绘制的,
优化如下
优化后效果
- 在后面绘制的矩形要能覆盖前面的,这个比较简单,改变每个
div
的z-index
就可以
- 代码调整
drawRect() {
const div = document.createElement("div");
div.className = "draw-rect";
div.style = `width: ${this.disX}px;height: ${
this.disY
}px;border:1px solid #ccc;position: absolute;left: ${this.startX}px;top: ${
this.startY
}px;z-index:${this.zIndex++};background:greenyellow`;
div.appendChild(this.addDeleteBtn());
document.body.appendChild(div);
this.allRect.push(div);
this.setCurrentBorderColor(div);
}
- 多个图形重叠在一起的时候,选择的元素在最顶层,也比较简单
changeBorderColor(target) {
this.nowMoveTarget = target;
this.setCurrentBorderColor(target);
// 改变鼠标指针
target.style.cursor = "move";
target.style.zIndex = ++this.zIndex;
}
- 完整代码
class Draw {
constructor() {
this.x = 0;
this.y = 0;
this.disX = 0;
this.disY = 0;
this.startX = 0;
this.startY = 0;
this.offsetX = 0;
this.offsetY = 0;
this.nowMoveTarget = null;
this.mouseDown = this.mouseDown.bind(this);
this.mouseMove = this.mouseMove.bind(this);
this.mouseUp = this.mouseUp.bind(this);
this.handleRectMove = this.handleRectMove.bind(this);
this.handleRectUp = this.handleRectUp.bind(this);
this.zIndex = 0;
this.allRect = [];
this.shadowBox = document.createElement("div");
this.init();
}
init() {
this.draw();
}
draw() {
document.addEventListener("mousedown", this.mouseDown, false);
}
mouseDown(e) {
console.log("🚀 ~ Draw ~ mouseDown ~ e:", e);
if (e.target.className == "delete-btn") return;
// 校验点击的是不是画的的元素
if (e.target.className == "draw-rect") {
// 改变边框颜色
this.changeBorderColor(e.target);
this.handleRectDown(e);
return false;
} else {
this.x = e.clientX;
this.y = e.clientY;
document.addEventListener("mousemove", this.mouseMove);
document.addEventListener("mouseup", this.mouseUp);
}
}
mouseMove(e) {
// 不要选中文字
e.preventDefault();
// this.disX = e.clientX - this.x
// this.disY = e.clientY - this.y
// const startX = e.clientX < this.x ? e.clientX : this.x
// const startY = e.clientY < this.y ? e.clientY : this.y
// this.disX = e.clientX > this.x ? e.clientX - this.x : this.x - e.clientX
// this.disY = e.clientY > this.y ? e.clientY - this.y : this.y - e.clientY
this.startX = Math.min(e.clientX, this.x);
this.startY = Math.min(e.clientY, this.y);
this.disX = Math.abs(e.clientX - this.x);
this.disY = Math.abs(e.clientY - this.y);
// console.log('🚀 ~ Draw ~ mouseMove ~ e:', this.disX, this.disY)
this.drawShadeRect();
}
mouseUp(e) {
document.removeEventListener("mousemove", this.mouseMove);
document.removeEventListener("mouseup", this.mouseUp);
this.drawRect();
this.shadowBox && this.shadowBox.remove();
}
drawShadeRect(startX, startY) {
this.shadowBox.style = `width: ${this.disX}px;height: ${
this.disY
}px;border:1px solid red;background:rgba(94,243,243,.5);position: absolute;left: ${
this.startX
}px;top: ${this.startY}px;z-index:${this.zIndex++}`;
document.body.appendChild(this.shadowBox);
}
drawRect() {
const div = document.createElement("div");
div.className = "draw-rect";
div.style = `width: ${this.disX}px;height: ${
this.disY
}px;border:1px solid #ccc;position: absolute;left: ${this.startX}px;top: ${
this.startY
}px;z-index:${this.zIndex++};background:greenyellow`;
div.appendChild(this.addDeleteBtn());
document.body.appendChild(div);
this.allRect.push(div);
this.setCurrentBorderColor(div);
}
handleRectDown(e) {
this.startX = e.clientX;
this.startY = e.clientY;
this.offsetX = e.clientX - this.nowMoveTarget.offsetLeft;
this.offsetY = e.clientY - this.nowMoveTarget.offsetTop;
document.addEventListener("mousemove", this.handleRectMove);
document.addEventListener("mouseup", this.handleRectUp);
}
handleRectMove(e) {
this.disX = e.clientX - this.offsetX;
this.disY = e.clientY - this.offsetY;
this.nowMoveTarget.style.left = `${this.disX}px`;
this.nowMoveTarget.style.top = `${this.disY}px`;
}
handleRectUp() {
document.removeEventListener("mousemove", this.handleRectMove);
document.removeEventListener("mouseup", this.handleRectUp);
}
changeBorderColor(target) {
this.nowMoveTarget = target;
this.setCurrentBorderColor(target);
// 改变鼠标指针
target.style.cursor = "move";
target.style.zIndex = ++this.zIndex;
}
// 动态添加一个删除按钮
addDeleteBtn() {
const btn = document.createElement("button");
btn.innerHTML = "删除";
btn.className = "delete-btn";
btn.style = `position: absolute;right: 0px;bottom: -25px`;
// 绑定事件
btn.onclick = function () {
this.parentElement.remove();
};
return btn;
}
setCurrentBorderColor(target) {
// 改变边框颜色,当前选中的高亮
this.allRect.forEach((item) => {
if (item != target) {
item.style.border = "1px solid #ccc";
}
});
target.style.border = "1px solid blue";
}
}
const d = new Draw();
d.init();
这样就对我们的画图的层级问题优化完成了。
总结
- 层级问题多半是css的z-index问题,需要我们手动去更新
- 还需要实现拖拉边框实现调整矩形大小的业务