使用raphael画线,升级版(有横向水平线,可拖拽)
效果图1:
效果图2:
应用场景:设备端前端页面(图为倒车影像,设备显示的辅助线)
代码:
目前左边线可拖拽,代码写法尚未简洁化,实现效果为主
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>简洁循环并可拖拽两条线以及两线连接的水平线</title>
<style>
#paper{
width:500px;
height:500px;
background:url('img/猫猫.jpg');
background-size: cover;
}
</style>
</head>
<body>
<div id="paper"></div>
<script src="js/jquery.1.12.1.min.js"></script>
<script src="js/raphael.js"></script>
<script>
let width = 500
let height = 500
let paper = new Raphael(document.getElementById("paper"), width, height)
// let array = getRandomData()
//以下可以利用高级而且简洁一点的循环遍历进行命名和实现画线
let arr = [
{
name1:'one',
points:[{x:120,y:50},{x:90,y:420}],
x1:120,
y1:50,
x2:90,
y2:420,
value1:1,
value2:2,
//横向连接的水平线,
corssX:0,
corssY:0,
},
{
name1:'two',
points:[{x:420,y:70},{x:480,y:420}],
x1:420,
y1:70,
x2:480,
y2:420,
value1:1,
value2:2,
},
]
// let array = arr
// let data = data2PathAndMax(array, width, height)
//计算斜率 目的是这条线不仅仅是利用仅有坐标画出的线段,而是拥有斜率的充满画布的线
let computedLine = function(item){
// 求斜率 x * k + b = y
let k = (item.y2 - item.y1) / (item.x2 - item.x1)
let b = item.y1 - item.x1 * k
// 使 y = 0,求 x
item.y3 = 0
item.x3 = k === 0 ? -b : -b / k
// 使 y = height,求 x
item.y4 = height
item.x4 = k === 0 ? height - b : (height - b) / k
}
//计算中点
let computedMiddlePoint = function(item,type){
if(type==='default'){
//计算中点 用于连接水平线
let cuY
if(((arr[0].y1+arr[0].y2)/2-(arr[1].y1+arr[1].y2)/2)>0){
cuY = (arr[0].y1+arr[0].y2)/2
}else{
cuY = (arr[1].y1+arr[1].y2)/2
}
arr[0].corssY = cuY
arr[1].corssY = cuY
}
let k1 = (arr[0].y2-arr[0].y1)/(arr[0].x2-arr[0].x1)
let k2 = (arr[1].y2-arr[1].y1)/(arr[1].x2-arr[1].x1)
//数学公式 移动中点连线 原线段上点并未移动 即原直线斜率不变 当移动中点连线,会已知y坐标,对应原直线上的点的y坐标
//也就已知了,用原直线的上的一个点和这个已知y的点,利用斜率可以反算出x k=((y2-y1)/(x2-x1)=(y-y1)/(?-x1)
//直线一上
arr[0].corssX = (arr[0].corssY-arr[0].y1)/k1+arr[0].x1
//直线二上
arr[1].corssX = (arr[1].corssY-arr[1].y1)/k2+arr[1].x1
}
let line1MiddlePoint = {corssX:0,corssY:0}
let line2MiddlePoint = {corssX:0,corssY:0}
//首次绘制 后面就只进行更改坐标即可
let startDrow = function(arr){
arr.forEach((item,index)=>{
computedLine(item)
let path = paper.path(`M${item.x3} ${item.y3}L${item.x4} ${item.y4}`).attr({
stroke: 'red',
'stroke-width': 2
})
paper.circle(item.x1, item.y1, 10).attr({
fill: '#FF6767',
stroke: 'red',
'stroke-width': 2,
'cursor': 'all-scroll'
})
paper.circle(item.x2, item.y2, 10).attr({
fill: '#FFF',
stroke: 'red',
'stroke-width': 2,
'cursor': 'all-scroll'
})
//中点
computedMiddlePoint(item,'default')
//绘制中点
paper.circle(item.corssX, item.corssY, 3).attr({
fill: '#FFF',
stroke: 'red',
'stroke-width': 1,
'cursor': 'all-scroll'
})
// paper.text(item.x1, item.y1, item.value1).attr({
// 'font-size': '12',
// 'fill': '#fff',
// 'text-anchor': 'middle',
// 'cursor': 'all-scroll',
// })
// paper.text(item.x2, item.y2, item.value2).attr({
// 'font-size': '12',
// 'fill': 'red',
// 'text-anchor': 'middle',
// 'cursor': 'all-scroll'
// })
//命名为的是进行标记元素 方便判断鼠标按下的dom元素
document.getElementsByTagName('path')[index].setAttribute('data-id','onePath')
})
document.getElementsByTagName('circle')[0].setAttribute('data-id','onePoint')
document.getElementsByTagName('circle')[1].setAttribute('data-id','twoPoint')
document.getElementsByTagName('circle')[3].setAttribute('data-id','threePoint')
document.getElementsByTagName('circle')[4].setAttribute('data-id','fourPoint')
//连接中点
let path = paper.path(`M${arr[0].corssX} ${arr[0].corssY}L${arr[1].corssX} ${arr[1].corssY}`).attr({
stroke: 'red',
'stroke-width': 5,
'cursor': 'all-scroll'
})
}
startDrow(arr)
document.getElementsByTagName('path')[2].setAttribute('data-id','middlePath')
//更新连接中点
let updateLinkMiddlePoint = function(arr){
//点
document.getElementsByTagName('circle')[2].setAttribute('cx',arr[0].corssX)
document.getElementsByTagName('circle')[2].setAttribute('cy',arr[0].corssY)
document.getElementsByTagName('circle')[5].setAttribute('cx',arr[1].corssX)
document.getElementsByTagName('circle')[5].setAttribute('cy',arr[1].corssY)
//线
document.getElementsByTagName('path')[2].setAttribute('d',`M${arr[0].corssX} ${arr[0].corssY}L${arr[1].corssX} ${arr[1].corssY}`)
}
//防止鼠标粘连的属性
let isDone = false
//更新位置
let updateDrow = function(arr){
console.log('执行更新')
computedLine(arr[0])
//线
document.getElementsByTagName('path')[0].setAttribute('d',`M${arr[0].x3} ${arr[0].y3}L${arr[0].x4} ${arr[0].y4}`)
//点
document.getElementsByTagName('circle')[0].setAttribute('cx',arr[0].x1)
document.getElementsByTagName('circle')[0].setAttribute('cy',arr[0].y1)
document.getElementsByTagName('circle')[1].setAttribute('cx',arr[0].x2)
document.getElementsByTagName('circle')[1].setAttribute('cy',arr[0].y2)
//文字
}
let clickDom
//按下事件
document.addEventListener('mousedown',function(target,event){
// console.log('按下',$(target)[0].target.attributes['data-id'])
if($(target)[0].target.attributes['data-id']){
isDone = true
clickDom = $(target)[0].target.attributes['data-id'].nodeValue // point-id、text-point-id
}
})
var wraps = document.getElementById('paper')
//移入画布 只有当点击的元素是点的时候才可以进行拖拽
let newClientX
let newClientY
wraps.addEventListener('mousemove',function(target, event){
if(isDone){
let clientX = 0 // 用来判断鼠标是否移动
let clientY = 0
let _self = this
newClientX = target.clientX
newClientY = target.clientY
if(clickDom&&clickDom=='onePoint'){
// console.log(newClientX,newClientY)
arr[0].x1 = newClientX
arr[0].y1 = newClientY
updateDrow(arr)
//中点
arr.forEach((it,ix)=>{
computedMiddlePoint(it,'test')
})
updateLinkMiddlePoint(arr)
}else if(clickDom&&clickDom=='twoPoint'){
arr[0].x2 = newClientX
arr[0].y2 = newClientY
updateDrow(arr)
//中点
arr.forEach((it,ix)=>{
computedMiddlePoint(it,'test')
})
updateLinkMiddlePoint(arr)
}else if(clickDom&&clickDom=='middlePath'){
arr[0].corssY = newClientY
arr[1].corssY = newClientY
//中点
arr.forEach((it,ix)=>{
computedMiddlePoint(it,'test')
})
updateLinkMiddlePoint(arr)
}else{
return
}
}
})
//鼠标抬起
document.addEventListener('mouseup',function(target, event){
console.log('监控到')
isDone = false
return
})
//鼠标离开
document.addEventListener('mouseleave',function(target, event){
isDone = false
return
})
</script>
</body>
</html>