【问题标题】:Svg with marker and no overflow带有标记且没有溢出的 Svg
【发布时间】:2019-12-20 06:52:30
【问题描述】:

我需要显示一个箭头来显示某些指标的演变,为此我创建了一个算法来绘制线条并添加使用标记以具有箭头的形状。

我尝试更改 refX 以使标记在最后完成,但由于线条很粗,它会在标记之后显示线条的其余部分。我可以减少更改此 refX 的方式,我看不到该行的其余部分,但我想在 svg 的范围内看到整个标记。

我还可以减少线条的长度,使线条 + 标记占据整个位置,但我找不到需要移除的正确像素数量。

线条是动态渲染的,这意味着它不会总是这样。 在从 (0,0) 到 (100,100) 的 svg(x,y) 中,它可以从 (100,0) 到 (100,100)。

当前代码显示溢出 svg 的箭头,我想把所有东西都放在里面。

<svg class="svg" style="height: 190px; width: 328px; border:1px solid blue;">
        <marker class="red_arrow_normal" markerUnits="strokeWidth" viewBox="0 0 10 10" refY="6" orient="auto"
            markerHeight="10" markerWidth="10" id="red-3" refX="10">
            <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: red;"></path>
        </marker>
        <line x1="0" y1="0" x2="328" y2="190" stroke="red" stroke-width="10" marker-end="url(#red-3)"></line>
    </svg>

【问题讨论】:

  • 将 refX 属性的值更改为较小的值,例如:refX="9" 但是,由于您的线与 svg 画布对角线的大小相同,因此箭头的尖端会稍微落在 svg 画布之外. Y 假设您需要更大的画布或做svg{overflow:visible;}
  • 是的,但是稍微大一点呢?宽高多少,切记线可以改变方向
  • 您需要使用三角函数将线条缩短某个固定长度
  • 有道理,但我需要知道标记的确切长度,而且它的宽度或长度看起来不等于 10px,我错过了什么?
  • 您可以将路径复制到主文档中并调用 getBBox 来查找其尺寸。

标签: javascript math svg


【解决方案1】:

您可以在 codepen here 中在线编辑它。我已经修改了宽度和高度。

<svg class="svg" style="height: 190px; width: 328px; border:1px solid blue;">
        <marker class="red_arrow_normal" markerUnits="strokeWidth" viewBox="0 0 10 10" refY="6" orient="auto"
            markerHeight="10" markerWidth="10" id="red-3" refX="9">
            <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: red;"></path>
        </marker>
        <line x1="0" y1="0" x2="320" y2="180" stroke="red" stroke-width="10" marker-end="url(#red-3)"></line>
    </svg>

【讨论】:

  • 问题是它需要是动态的,因为它并不总是这条线。因此,即使它适用于这种情况,也不应该只是一次。
  • 必须修复生成器功能。如果您可以分享,我们可以找到一些更好的解决方案来动态生成 svg。
【解决方案2】:

对于这个问题似乎没有不涉及一些 javascript 的干净解决方案,但您可以通过一些数学来解决它:

function drawArrow(x1, y1, x2, y2) {
  const svg = document.getElementById("my-svg")
  
  let dx = x2 - x1;
  let dy = y2 - y1;
  const length = Math.sqrt(dx * dx + dy * dy);
  if (length > 0)
  {
      dx /= length;
      dy /= length;
  }
  const SHORTEN = 6
  const x3 = x1 + dx * (length - SHORTEN)
  const y3 = y1 + dy * (length - SHORTEN)
  
  svg.innerHTML += `<line x1=${x1} y1=${y1} x2=${x3} y2=${y3} stroke="red" stroke-width="5" marker-end="url(#arrow)"></line>`
}

您首先必须确保您的箭头延伸到线的末端之外,这样线的方形末端就不会显示出来。然后你必须调整 SHORTEN 变量来抵消箭头的额外长度。

我的小提琴:https://jsfiddle.net/h4pgoaLw/

【讨论】:

    猜你喜欢
    • 2014-03-23
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2019-07-18
    相关资源
    最近更新 更多