如何正确地将SVG中的立方贝塞尔上的箭头移动到其中心

时间:2018-02-28 16:59:53

标签: javascript svg

有一个带箭头标记的立方贝塞尔:

<defs>
  <marker id="arrow" orient="auto" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" refX="10" refY="6">
    <path d="M0,0 L0,12 L12,6 z"></path>
  </marker>
</defs>

<path marker-end="url(#arrow)" d="M 220 104 C 220 144 400 184 400 224" stroke-width="2"></path>

我想将箭头移动到曲线的中心,但是当我变异refX marker的箭头时,箭头不会越过曲线而是直接移到顶部(http://prntscr.com/ikzuol)。它与二次贝塞尔曲线完美配合,但不适用于立方体。

有没有办法使用标记在正方形贝塞尔曲线的中心显示箭头?

我知道有一个选项可以获取长度坐标,计算旋转角度并自行进行定位和旋转,但我想避免这样的计算。

UPD:我已经创建了一个codepen来演示这个问题:https://codepen.io/onatolich/pen/LQqYvr

UPD2:再用一个代码来证明它正在使用二次贝塞尔曲线:https://codepen.io/onatolich/pen/NyoxQv

1 个答案:

答案 0 :(得分:1)

refXrefY是定义标记的坐标系中的点,与路径的方向无关。它们只是定义了被认为是标记原点的点,它将被放置在路径的末端。

无法沿计算路径定义标记。标记只能放在路径的顶点。所以看似直截了当的方法是找到一个中点,在那里放置一个带有适当的三次贝塞尔控制点的顶点......

<svg width="500" height="500">
<defs>
  <marker id="arrow" orient="auto" markerUnits="userSpaceOnUse"
          markerWidth="12" markerHeight="12" refX="3" refY="6">
    <path d="M0,0 L0,12 L12,6 z"></path>
  </marker>
</defs>
<path marker-mid="url(#arrow)"
      d="M 220,104 C 220,124 265,143 310,162.5 355,182 400,202 400,224"
      stroke-width="2" stroke="black" fill="transparent"></path>
</svg>

......但这显然也是很​​多计算。

这是一个使用<animateMotion>元素的黑客,不是为了动画任何东西,而是因为它可以将一个对象移动到路径上的每个点。运动只是在路径的中间开始,结束和冻结。

“标记”没有自己的视口,这意味着无法定义refX / refY。放置在路径上的点始终位于其用户空间坐标的(0,0)处。这就是标记必须在这些值的相反方向上移动的原因。

<svg width="500" height="500" >
  <path id="path1" d="M 220 104 C 220 144 400 180 400 224"
        fill="none" stroke-width="2" stroke="black" />
  <path d="M0,0 L0,12 L12,6 z" transform="translate(-3,-6)">
    <animateMotion dur="0s" rotate="auto" fill="freeze"
                   keyTimes="0;1" keyPoints="0.5;0.5" >
       <mpath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#path1"/>
    </animateMotion>
  </path>
</svg>

hack不适用于没有实现SMIL动画的Edge / IE。