【问题标题】:Svg path arrowhead without use of marker不使用标记的 Svg 路径箭头
【发布时间】:2020-08-27 16:12:37
【问题描述】:

我想在不使用标记的情况下在 SVG 路径或行的开头和结尾创建箭头。 这样我就可以只用 css(鼠标悬停)来操作箭头

使用路径作为 javascript 函数的输入,我假设应该可以使用开始/结束坐标来绘制多边形(箭头)。

【问题讨论】:

  • 听起来很有趣。由于 SVG 是一种用于绘制路径和显示“图形”的语言,您能否为您的问题添加更多细节?
  • CSS 悬停状态在 SVG 子元素上没有得到很好的支持,所以无论你做什么都将使用 Javascript。
  • 使用 Inkscape 等 SVG 编辑器,随心所欲地绘制,
  • @RobertLongson 这是一个 javascript 项目,我在其中根据某些数据动态绘制 SVG 路径。在某些路径的开头和结尾,我需要添加一个箭头多边形。我设法通过使用开始/结束坐标和线的角度来确定我的多边形点来做到这一点,但我对代码还不满意。通过绘制我自己的多边形作为我的线(组)的一部分,我可以从 css 操作所有内容
  • 如果您有代码,请向我们展示。说明你不满意的部分。

标签: javascript svg


【解决方案1】:

我最终做了以下事情:

// Determine polygon points
beginArrowPoints(pathCoords: { x: number; y: number }[]) {
  return this.getPolygonCoords(pathCoords, 0);
}

endArrowPoints(pathCoords: { x: number; y: number }[]) {
  return this.getPolygonCoords(pathCoords, pathCoords.length - 1);
}

// set rotation on transform
rotateBegin(pathCoords: { x: number; y: number }[]) {
  const endPoint = pathCoords[1];
  const startPoint = pathCoords[0];
  const angleDeg = this.determineRotationAngle(endPoint, startPoint);
  return `rotate(${angleDeg}, ${startPoint.x}, ${startPoint.y})`;
}

rotateEnd(pathCoords: { x: number; y: number }[]) {
  const endPoint = pathCoords[pathCoords.length - 1];
  const startPoint = pathCoords[pathCoords.length - 2];
  const angleDeg = this.determineRotationAngle(endPoint, startPoint);
  return `rotate(${angleDeg}, ${endPoint.x}, ${endPoint.y})`;
} 

private determineRotationAngle(endPoint: { x: number; y: number }, startPoint: { x: number; y: number }) {
  const deltaX = Math.abs(endPoint.x - startPoint.x);
  const deltaY = endPoint.y - startPoint.y;
  return Math.atan2(deltaY, deltaX) * 180 / Math.PI + 180; // invert by turning 180 degrees
}

private getPolygonCoords(pathCoords: { x: number; y: number }[], index: number) {
  const {x, y} = pathCoords[index];
  const p1 = `${x} ${y}`;
  const p2 = `${x + 7.5} ${y + 5}`;
  const p3 = `${x + 7.5} ${y - 5}`;
  return `${p1}, ${p2}, ${p3}`;
}

产生如下多边形:

<g>
   <polygon id="start" points="240 0, 247.5 5, 247.5 -5" ="rotate(180, 240, 0)"></polygon>
   <polygon id="end" points="1038 694.32, 1045.5 699.32, 1045.5 689.32" transform="rotate(235.4921735667412, 1038, 694.32)"></polygon>
   
   <path d="M240,0L330,0L402,29.82L507,158.32L522,174.82L690,320.94L720,320.94L792,372.32L819,405.52L825,411.92L852,445.48L936,556.32L987,618.96L990.0000000000001,624.5L1038,694.32" ></path>
</g>

然后可以对整个组进行样式设置和事件处理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 2022-01-15
    • 2017-07-22
    • 1970-01-01
    • 2013-04-23
    • 2017-06-03
    • 2011-01-11
    相关资源
    最近更新 更多