这是一个 SVG 应用程序。我有一条具有
centerPoint
、startPoint
、endPoint
和 angle
属性的线条。我有一个带有 centerPoint
、width
和 height
的矩形。由此我可以计算出矩形的四个角。
我将矩形放在一条线上。矩形中心位于直线上的任意点。
现在我有一个用例,可以使用起点或终点拖动我的线。我可以单击并拖动端点并向任意方向移动。我的线条角度、起点或终点、中心点发生了变化。
当发生线拖动时,我希望我的矩形与线连接。
interface IPoint{
x: number,
y: number,
}
class Line {
startPoint: IPoint = { x: 0, y: 0 };
endPoint: IPoint = { x: 0, y: 0 };
centerPoint: IPoint = { x: 0, y: 0 };
angle: number = 0;
}
export class Rectangle {
centerPoint: IPoint;
height: number;
width: number;
angle: number;
offset: IPoint;
lineDisplacement: {
dx: number;
dy: number
};
}`
我尝试的是计算矩形中心和线中心之间的差异:
getDisplacement(p1: IPoint, p2: IPoint) {
return {
dx: p2.x - p1.x,
dy: p2.y - p1.y
};
}
rectangle.lineDisplacement = this.getDisplacement(
line.centerPoint,
rectangle.centerPoint
);
当我在线上的任何点上创建矩形时,我都会这样做,并将该值保留在矩形上作为
lineDisplacement
。然后,当线中心发生变化并与线的新角度成角度时,我尝试更新矩形中心。
const newCenter = {
x: line.midPoint.x + rectangle.lineDisplacement.dx,
y: line.midPoint.y + rectangle.lineDisplacement.dy
};
rectangle.setCenter(newCenter);
rectangle.setAngle(line.getAngle);
这已经很接近了,但新中心从未上线。仅当线的角度没有改变时它才起作用。我尝试过使用
Math.cos
和 Math.sin
的其他方法,但这还远远不够。所以我现在迷路了。
提前感谢您的任何指示。
我不知道你是否觉得这有用,但除了计算位置之外,也许你可以使用
<marker>
。我想这取决于 SVG 的复杂性。例如,标记不可点击,因此如果这是一个要求,那么这种方法可能不是理想的解决方案。
可以使用标记上的 refX 属性调整线条位移。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200">
<line marker-start="url(#square)" x1="5" y1="20" x2="95" y2="50" stroke="green" />
<defs>
<marker id="square" viewBox="0 0 10 10" refX="40" refY="5" markerWidth="10"
markerHeight="10" orient="auto-start-reverse">
<rect width="10" height="10" fill="none" stroke="red"/>
</marker>
</defs>
</svg>