svg用弯曲的路径动画为标记端/标记端设置动画 [英] svg animate marker-end/marker-start with curved path animation

查看:111
本文介绍了svg用弯曲的路径动画为标记端/标记端设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

i具有使用animate元素进行动画处理的弯曲路径.它确实结合了@keyframes来为路径设置动画,但是当我在弯曲路径内添加标记时,标记不会设置动画.我通过更改路径值属性使用一个简单的路径进行了测试.使用简单的路径可以完美工作,但是如何使标记元素与弯曲的路径保持动画呢?

i have curved paths that animate using the animate element. it does animate the path in combination with @keyframes, but when i add markers inside the curved path, the markers do not animate. i tested one using a simple path by changing the path values attribute. it worked perfectly using a simple path but how do i get the marker elements animate with the curved path?

codepen演示: https://codepen.io/tfss/pen/yZoBLo 使用简单弯曲的路径

codepen demo: https://codepen.io/tfss/pen/yZoBLo using simple and curved paths

推荐答案

由于拥有的是贝塞尔曲线,因此您可以计算将曲线从原点绘制到新位置的点.要了解接下来会发生什么,您需要了解什么是贝塞尔曲线.

Since what you have is a Bézier curve, you can calculate the points to draw the curve from the origin to the new position. To understand what comes next you need to understand what is a Bézier curve.

在下一个示例中,我使用输入类型范围来更改曲线.您可以为其设置动画.请阅读代码中的注释.

In the next example I'm using an input type range to change the curve. You may animate it instead. Please read the comments in the code.

//the points used to draw the final curve
let points = [[308.7, 34.9],[381.3, 37.4],[444.3, 78],[478.7,137.5]];
//the position of the final point of the actual curve on the final curve.
let t = 0.5;
//the points for the actual curve
let newPoints = getBezierPoints(t);
drawCBezier(newPoints, the_bezier);

// on input recalcalculate the points for the curve and the curve
T.addEventListener("input", function() {
  t = this.value;
  newPoints = getBezierPoints(t);
  drawCBezier(newPoints, the_bezier);
});


function getBezierPoints(t) {
  let helperPoints = [];

  // helper points 0,1,2
  for (let i = 1; i < 4; i++) {
    //points.length must be 4 !!!
    let p = lerp(points[i - 1], points[i], t);
    helperPoints.push(p);
  }

  // helper points 3,4
  helperPoints.push(lerp(helperPoints[0], helperPoints[1], t));
  helperPoints.push(lerp(helperPoints[1], helperPoints[2], t));

  // helper point 5 is where the first Bézier ends and where the second Bézier begins
  helperPoints.push(lerp(helperPoints[3], helperPoints[4], t));

  // points for the dynamic bézier
  let firstBezier = [
    points[0],
    helperPoints[0],
    helperPoints[3],
    helperPoints[5]
  ];
  
  return firstBezier;
}

function lerp(A, B, t) {
  // a virtual line from A to B
  // get the position of a point on this line
  // if(t == .5) the point in in the center of the line
  // 0 <= t <= 1
  let ry = [
    (B[0] - A[0]) * t + A[0], //x
    (B[1] - A[1]) * t + A[1] //y
  ];
  return ry;
}

function drawCBezier(points, path) {
  let d = `M${points[0][0]},${points[0][1]} C`;
  // points.length == 4
  for (let i = 1; i < 4; i++) {
    d += ` ${points[i][0]},${points[i][1]}`;
  }
  
  path.setAttributeNS(null, "d", d);
}

svg {
  border: 1px solid;
  width:100vh
}

<input type="range" value=".5" min="0" max="1" step=".01" id="T">
<svg viewBox="290 0 200 150">
  <defs>
  <marker
    id="arrow"
    orient="auto-start-reverse"
    viewBox="0 0 7.1 11.5"
    markerWidth="7.1"
    markerHeight="11.5"
    markerUnits="strokeWidth"
    refX="5" refY="5.75">
    <path d="M1 11.5L0 10.4L5.1 5.7L0 1L1 0L7.1 5.7L1 11.5" fill="#00897b"></path> 
  </marker>
  
  <marker id="circle" viewBox="0 0 6 6" refX="1" refY="3"
			markerUnits="userSpaceOnUse" orient="auto"
			markerWidth="6" markerHeight="6">
			<circle cx="3" cy="3" r="3" fill="#4caf50"/>
   </marker>
</defs>

  
  <path id="the_bezier" d=""
    marker-start="url(#circle)"
    marker-end="url(#arrow)"
    stroke-width="2"
    fill="none"
    stroke="blue" />
</svg>

您可能会发现有关贝塞尔曲线的文章很有用:如何在SVG中的三次贝塞尔曲线上添加点

You may find this post about Bézier curves useful: How to add a point to a Cubic Bézier Curve In SVG

对于其他方法,您可能希望阅读以下答案:

For a different approach you may like to read this answer: Stroke animation, how to attach another path to the appearing stroke?

我希望这会有所帮助.

这篇关于svg用弯曲的路径动画为标记端/标记端设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆