今天 1024,分享一个两点之间绘制线的方法,纯 div 绘制,拿之即用,希望搜索引擎能分享给需要的人。
先看下效果图:
可点击查看 在线预览
// 中心点坐标(相较于滚动条外的 dom 边界)
function useElementCenterPoint(el: HTMLElement) {
try {
const { x, y, width, height } = el.getBoundingClientRect()
return {
x: x + width / 2 + window.scrollX,
y: y + height / 2 + window.scrollY
}
} catch (e) {
console.warn(`获取元素位置信息报错:`, e)
}
}
因为我们绘制的线是连接两个点的中心点,这样效果更好。
使用 getBoundingClientRect
获取元素的位置信息,其中 x
和 y
在这里可以理解为是元素的 left
和 top
,为了获取它们的中心点坐标,这里需要加上元素一半的宽高,这个脑补一下很好理解。
另外 getBoundingClientRect
是相对于 视口 获取元素的位置的,也就是它不考虑滚动条的位置。考虑到会有滚动的情况,我们需要加上横、纵向滚动条位置。
// 两点之间的距离
function usePointsDistance(point, point2) {
const horizontalLength = Math.abs(point.x - point2.x)
const verticalLength = Math.abs(point.y - point2.y)
return Number(Math.sqrt(Math.pow(horizontalLength, 2) + Math.pow(verticalLength, 2)).toFixed(2))
}
如图所示,我们在有坐标的情况下,根据 勾股定理 可以很轻易的获取到两点之间的距离。
根据坐标计算蓝线的长度,从而计算出红线的长度。
export function drawLine(
dotOne: HTMLElement,
dotTwo: HTMLElement,
options: {
thickness: number // 线粗
lineClassName?: string // 线的类名
lineStyle?: Partial<CSSStyleDeclaration> // 线的 css 样式
}
) {
const line = document.createElement('div')
const { x: x1, y: y1 } = useElementCenterPoint(dotOne)!
const { x: x2, y: y2 } = useElementCenterPoint(dotTwo)!
const point = {
x: x1,
y: y1
}
const point2 = {
x: x2,
y: y2
}
// 线的长度
const distance = usePointsDistance(point, point2)
// 线的坐标
const topValue = (y1 + y2) / 2 - options.thickness / 2
const letValue = (x1 + x2) / 2 - distance / 2
// 线的角度
const angle = Math.atan2(y1 - y2, x1 - x2) * (180 / Math.PI)
Object.assign(line.style, {
...options.lineStyle,
position: 'absolute',
top: `${topValue}px`,
left: `${letValue}px`,
width: `${distance}px`,
transform: `rotate(${angle}deg)`
})
// 用来定位已存在的 line
line.classList.add('unique-line-class')
options.lineClassName && line.classList.add(options.lineClassName)
document.body.appendChild(line)
}
调用以下代码即可绘制一条线
drawLine(dotOne, dotTwo, {
thickness: 2,
lineClassName: 'line-style'
})
// 线的角度
const angle = Math.atan2(y1 - y2, x1 - x2) * (180 / Math.PI)
Math.atan2(y1 - y2, x1 - x2) 的目的是为了计算从点 (x1, y1) 到点 (x2, y2) 的角度。Math.atan2 是反正切函数,它返回的是从原点到点 (x2, y2) 的角度。 在二维平面上,点的位置是由 x 和 y 坐标决定的。
当我们想要知道两点之间的角度时,我们需要考虑这两个点的 x 和 y 坐标的差值。 当我们使用 Math.atan2(y1 - y2, x1 - x2) 时,我们实际上是在计算这两点之间的角度。
x 坐标的差值 (x1 - x2) 表示在 x 轴方向上的移动距离,而 y 坐标的差值 (y1 - y2) 则表示在 y 轴方向上的移动距离。 这个角度的计算考虑了 x 和 y 坐标的相对大小,因此它能够准确地表示出这两点之间的角度关系,而不仅仅是直线距离。
这个函数返回的角度是以弧度为单位的,但是如果你想用度来表示,你只需要乘以(180/π)。这就是为什么在代码中会有 * (180 / Math.PI)
的部分。
以上就是纯 div 实现两点之间绘制线的核心实现了,全部代码可查阅 这里 。