这是我参与「第四届青训营 」笔记创作活动的第5天
本文主要讲述低代码入门知识📖 本期讨论组件在画布上的移动与缩放
移动
在做组件的移动时第一个想到的就是在学习js时做的 盒子随着鼠标移动
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="moveDiv">movableDiv</div>
<script>
const div = document.getElementById('moveDiv')
div.onmousedown = function () {
console.log('a');
document.onmousemove = move
}
move = function (e) {
div.style.top = e.clientY +'px'
div.style.left = e.clientX + 'px'
console.log(div.style.top);
}
</script>
</body>
</html>
<style>
#moveDiv {
position: absolute;
background-color: skyblue;
width: 200px;
height: 200px;
color: white;
font-size: 30px;
}
</style>
但这个demo还存在一些问题 🤔🤓
- 无论点击哪里,移动过程中盒子的左上角始终与鼠标在同个位置,不太美观
- 点击后移动,与长按还不太一样,同时没有设置取消
在此基础上做出改进,采用另一种思路,即点击时鼠标与组件的位置差,在拖拽中不发生改变 即可得出公式
-
旧鼠标位置-组件旧位置 = 新鼠标位置 - 组件新位置
- 计算出鼠标与组件的位置差 (拿X举例)
disX = e.clientX-style.left
- 计算出鼠标与组件的位置差 (拿X举例)
-
组件新位置 = 新鼠标位置 - 位置差
核心代码
moveComponent(e) {
e.stopPropagation()
e.preventDefault()
this.$store.commit("Editor/SelectCur", this.comData);
//选中该组件
//旧鼠标Y - 旧top =新鼠标Y - 新TOP
//新鼠标Y - disY = 新TOP
const cur = e.currentTarget.parentElement;
const style = this.comStyle
const disX = e.clientX-style.left
const disY = e.clientY-style.top
//点击的位置与元素位置的x、y在移动中不改变
const move = function (ev) {
ev.stopPropagation()
ev.preventDefault()
style.left = ev.clientX -disX
style.top = ev.clientY - disY
};
const up = function () {
cur.removeEventListener("mousemove", move);
cur.removeEventListener("mouseup", up);
};
cur.addEventListener("mousemove", move);
cur.addEventListener("mouseup", up);
},
监听每个组件mousedown事件💡
做四件事📄
- 计算位置差
- 给画布添加mousemove监听和mouseup监听
- 监听mousemove 就根据位置差计算出新的位置并修改
- 监听到mouseup就将监听都移除 防止鼠标放开还能移动
缩放
重点还是谈一谈缩放 具体要实现的功能 八种缩放模式 拖拽实现缩放
一上来相信很多人和我想法一样——[与移动原理类似,只不过这次根据鼠标位置改变的是宽高而不是]
上手实现后 马上碰壁 🤦
问题有不少💭:
- 宽高的改变不只与鼠标移动时的位置有关,还与开始拖拽时 点击时的鼠标位置有关系
- 单单改变宽高,无论怎么该,默认坐标不变 举例:向上拉大 若设置高度变高 最终效果是:组件从下面延展以使得高度变高,这与我们像达到的效果不同
解决方法💡
- 对于第一点 我们转换思路🧠 计算开始时的位置 和移动时的位置 的差 即为 宽高的变化量
- 对于第二点 我们只需对不同情况做出判断 若向下向右的 ,改变宽高即可。其他情况,要改变其的位置 同时改变宽高 这样使得视觉效果达到预期 ✊
核心代码
// 点击小圆点进行放大缩小
changeSize(i, e) {
e.stopPropagation();
e.preventDefault();
const com = e.currentTarget.parentElement.parentElement
console.log(com);
const style = {...this.comStyle}
const height = Number(style.height)
const width = Number(style.width)
const top = Number(style.top)
const left = Number(style.left)
let startX = e.clientX;
let startY = e.clientY;
//初始鼠标位置
const cur = this.curComponent
// 记录初始宽度 和长度
const move = function (ev) {
console.log('1a');
const curX = ev.clientX
const curY = ev.clientY
const disX = curX - startX
const disY = curY - startY
if(i.includes('t')){
cur.style.top = top + disY
cur.style.height = height - disY
}
if(i.includes('b')){
cur.style.top = top
cur.style.height = height + disY
}
if(i.includes('l')){
cur.style.left = left + disX
cur.style.width = width - disX
}
if(i.includes('r')){
cur.style.left = left
cur.style.width = width + disX
}
};
const up = function () {
com.removeEventListener("mousemove",move);
com.removeEventListener("mouseup",up);
};
com.addEventListener("mousemove", move);
com.addEventListener("mouseup", up);
},
tips👀
-
缩放其实还涉及到选中框 在这简单说一下 🤓
-
选中框只显示在当前组件 选中框上有8个点 用于缩放
-
当点击组件时会将其设置成当前组件
-
对于八个点 我使用数组维护 同时根据名称给他们赋以对应的光标形状 同时判断缩放类型时也是根据名称判断 (如下)
-
这里与移动一样 要监听
mouseup移除事件监听
const pointList = ["lt", "t", "rt", "r", "rb", "b", "lb", "l"]
💭
记录低代码项目中的小问题📜
若本文对你有帮助 欢迎点赞收藏👍
若有纰漏,敬请包涵,评论区欢迎指正👂