1.如何使用带箭头的虚线将div连接
a.了解path命令
我们可以使用svg的path配合marker属性来实现,首先我们需要了解path元素的命令
M(x,y) 起始位置的坐标
L(x,y) 结束位置的坐标
<!-- 从 坐标(150,0) ~ (300,300) -->
<!-- <path d="M 150,0 L 300,300" style="stroke: red ;stroke-width:2px" /> -->
这样我们就会得到一条这样的直线
那么如何绘制一条虚线,只需要添加"stroke-dasharray: 0.5%"属性就可以了
<!-- 从 坐标(150,0) ~ (300,300) -->
<path d="M 150,0 L 300,300" style="stroke: red; stroke-width: 2px ;stroke-dasharray: 0.5%;" />
H(x) 绘制一条给定x坐标的横线
<!-- 从 坐标(150,300) ~ (600,0) 的横线 -->
<path d="M 150,300 H 600" style="stroke: aqua" />
V(y) 绘制一条给定y坐标的垂线
<!-- 从 坐标(150,300) ~ (0,600) 的垂线 -->
<path d="M 150,300 V 600" style="stroke: red; stroke-width: 2px" />
C(x1,y1 x2,y2 x,y) 绘制一条 x1,y1 x2,y2 为控制点 终点为x,y的三次贝塞尔曲线
<!-- 从(50,200)出发,以(0,50)(150,50)为控制点,以(300,200)为终点的三次贝塞尔曲线 /> -->
<path d="M 50,200 C 0,50 150,50 300,200" style="stroke-width: 2px" fill="#fff" />
b.marker属性实现箭头
markerWidth: marker标记的宽度
markerHeight: marker标记的高度
markerUnits: 默认为strokeWidth 将marker的标记的大小设置为允许缩放
refX refY: 是图形和marker标记连接位置的坐标
orient: 他决定marker在与其他元素连接时 是否会旋转
我们图形应用marker有以下几种方法
marker-start=”url(#marker-id)”
marker-mid=”url(#marker-id)”
marker-end=”url(#marker-id)”
marker=”url(#marker-id)”
<defs>
<marker
markerWidth="10"
markerHeight="10"
markerUnits="strokeWidth"
id="wjl"
refX="0"
refY="2"
orient="auto"
>
<path d="M 0 0 L 5 2 L 0 4 z" />
</marker>
</defs>
<path
d="M 0,0 C 150,0 150,100 200,100"
class="line3"
style="marker-end: url(#wjl)"
fill="none"
/>
// .line3 {
// stroke-width: 2px;
// stroke: black;
// }
这样我们就可以绘制一条有箭头的虚线了
2. 了解clientX/Y、 screenX/Y 、offsetX/Y
想要完成这个功能,我们必须了解的就是clientX/Y、 screenX/Y 、offsetX/Y
clientX/Y | 事件被触发时鼠标相对于浏览器区域的水平/垂直坐标 |
screenX/Y | 事件被触发时鼠标相对于屏幕的水平/垂直坐标 |
offsetX/Y | 事件被触发时鼠标相对于事件源的水平/垂直坐标 |
3.接下来我们要实现div的拖动
1、为需要拖动的元素添加鼠标按下事件
2、通过计算坐标实现鼠标拖动div 同理 为第二个div添加此方法
3.接下来通过设置path的M(x,y)和L(x,y)来实现鼠标拖动 连接线始终连接的效果
updated() {
this.d = `M ${this.fX + 25?this.fX + 25:50},${this.fY?this.fY:0} L ${this.sX != ''?this.sX + 25:250},${this.sY?this.sY:55}`;
},
这时候我们在鼠标拖动方法中获得的fX和fY就起到了作用
由于我的div大小为50px,所以为x坐标加25是为了使连接点的起始位置和终点位置都在两个div的中心,我们通过三元运算符来判断以确定在我们没有拖动时连接线的位置,到这一步我们就已经完成了拖动但是连接线保持连接
4.通过进一步判断实现连接线根据两个div位置切换的效果
updated() {
this.d = `M ${this.fX + 25?this.fX + 25:50},${this.fY?(this.fY>this.sY+25?this.fY:this.fY+50):0} L ${this.sX != ''?this.sX + 25:250},${this.sY?(this.sY>this.fY+25?this.sY:this.sY+50):55}`
},