【问题标题】:SVG object animation on a path line路径线上的 SVG 对象动画
【发布时间】:2018-11-26 17:48:02
【问题描述】:

我想在一条线上制作一条 svg 路径的动画。就像这个代码笔一样,但我不想使用多边形,而是想使用更复杂的 svg。 (小路) Codepen example

HTML:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="100%" height="100%" viewBox="0 0 800 300" enable-background="new 0 0 800 300" xml:space="preserve">

    <path d="M30,30 L770,30" />
    <path d="M29.833,113.5C29.833,178.667,99,271.334,257,271.334 S475.5,81,375.5,81S305,271.334,770,271.334"/>

    <polygon points="15,0 18.541,11.459 30,11.459 20.729,18.541 24.271,30 15,22.918 5.729,30 9.271,18.541 0,11.459 11.459,11.459    "/>

    <polygon points="15,0 18.541,11.459 30,11.459 20.729,18.541 24.271,30 15,22.918 5.729,30 9.271,18.541 0,11.459 11.459,11.459    "/>

</svg>

有人知道如何用 svg 路径文件替换多边形吗?

谢谢你,

【问题讨论】:

  • 您可以使用许多不同的库来为您完成此任务。 SVGsnap Anime.js greensock.com mojs.io 仅举几例。

标签: javascript animation svg


【解决方案1】:

在这个例子中,我使用了一个复杂的&lt;symbol&gt; 元素而不是星号。 &lt;symbol&gt; 包含一个路径和 4 个圆圈。我已将此符号放在隐藏的 SVG 元素中。

在主要的 SVG 元素中,我用 2 个使用 #cow 符号的 &lt;use&gt; 元素更改了多边形(星形)。

在 Javascript 中,我将 var stars = svgContainer.getElementsByTagName("polygon"); 更改为 var stars = svgContainer.getElementsByTagName("use");

如果您想在所有 javascript 中将变量名称从 stars 更改为 cows,您可以这样做。

/*	A variable to keep track of where we are on the line
	0 = start, 1 = end */
var counter = 0;

/*	A boolean variable to keep track of the direction we want to travel in 
	true = move to the left, false move to the right */
var direction = true;

/*	First get a reference to the enclosing div and then to
	the 2 svg paths */
var svgContainer = document.getElementById("outerWrapper");
var ns = "http://www.w3.org/2000/svg";
var svg = svgContainer.getElementsByTagNameNS(ns, "path");
/*	the var 'svg' contains a reference to two paths so svg.length = 2
	svg[0] is the straight line and svg[1] is the curved lines */

/*	Now get the length of those two paths */
var straightLength = svg[0].getTotalLength();
var curveLength = svg[1].getTotalLength();

/*	Also get a reference to the two star polygons */
var stars = svgContainer.getElementsByTagName("use");

function moveStar() {
	/*	Check to see where the stars are journeys to determine 
		what direction they should be travelling in */
	if (parseInt(counter,10) === 1) {
		/* we've hit the end! */
		direction = false;
	} else if (parseInt(counter,10) < 0) {
		/* we're back at the start! */
		direction = true;
	}

	/*	Based on the direction variable either increase or decrease the counter */
	if (direction) {
		counter += 0.003;
	} else {
		counter -= 0.003;
	}

	/*	Now the magic part. We are able to call .getPointAtLength on the tow paths to return 
		the coordinates at any point along their lengths. We then simply set the stars to be positioned 
		at these coordinates, incrementing along the lengths of the paths */
	stars[0].setAttribute("transform","translate("+ (svg[0].getPointAtLength(counter * straightLength).x -15)  + "," + (svg[0].getPointAtLength(counter * straightLength).y -15) + ")");
	stars[1].setAttribute("transform","translate("+ (svg[1].getPointAtLength(counter * curveLength).x -15)  + "," + (svg[1].getPointAtLength(counter * curveLength).y -15) + ")");

	/*	Use requestAnimationFrame to recursively call moveStar() 60 times a second
		to create the illusion of movement */
	requestAnimationFrame(moveStar);
}
requestAnimationFrame(moveStar);
body {
  margin: 0;
  background: #565279;
}

.outerWrapper {
	width: 800px;
	height: 300px;
	position: relative;
}

.outerWrapper svg {
	position: absolute;
}

.outerWrapper svg path {
	fill:none; 
	stroke:#DABDD8;
	stroke-width:5; 
	stroke-dasharray:10,10;
}

.outerWrapper svg polygon {
	fill:orange; 
}
<svg style="display:none">
	<defs>		
<symbol id="cow" viewBox= "0 0 200 200">
	<path class="head" fill="gold" stroke-width="1" d="M87 110 c5 0 12-0 21-0 c9-0 26 2 33-4 c5-4 2-14 0-19 c-6-11-14-11-25-11c-10-0-15-7-8-16 c11-13 22-2 35-3 c7-0.622 15.812-11.692 5.757-14.441c-3.556-0.973-12.802 0.949-15.412-0.906c6.371 4.5 20.854-11.553 23.774-15.168 c4.103-5.079 7.713-10.561 10.987-16.205c0.678-1.169 2.928-7.366 4.133-7.882c-7.42 3.175-14.234 8.021-22.368 10.7 c-20.585 6.695-42.426 9.711-64.039 9.711c-18.865 0.045-41.083-2.831-60.479-8.723C16.774 10.2 9.1 5 0.6 1.4 C4.425 3 11 19.4 13.8 23.083c3.03 4 18.5 22.6 25.6 17.551c-2.173 1.544-10.67-0.021-13.562 0.5 c-9.382 1.672-7.292 11.8 1 14.308c12.151 3.7 23.371-8.617 35 0.611c7.217 5.7 11.1 18.941-1.428 19.4 c-10.27 0.355-20.138-1.575-26.384 8.23c-4.091 6.423-6.256 13.976-2.265 20.886c3.503 6.1 24.2 4.7 30.3 4.9 C70.382 109.8 78.7 109.9 87 109.8"/>
	
		<circle class="eyeR" fill="#040B13"  stroke-width="1"  cx="117.3" cy="64.9" r="6"/>
		<circle class="eyeL" fill="#040B13"  stroke-width="1"  cx="55.4" cy="64.9" r="6"/>	
		<circle class="nostrilL" fill="#446B70" stroke-width="1"  cx="50.6" cy="92.9" r="9"/>	
		<circle class="nostrilR" fill="#446B70"  stroke-width="1" cx="123.4" cy="92.9" r="9"/>
</symbol>
</defs>	
</svg>

<div class="outerWrapper" id="outerWrapper">

	<svg version="1.1" id="Layer_1"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
		 width="100%" height="100%" viewBox="0 0 800 300" enable-background="new 0 0 800 300" xml:space="preserve">
	 
		<path class="pth" d="M30,30 L770,30" />
		<path class="pth" d="M29.833,113.5C29.833,178.667,99,271.334,257,271.334 S475.5,81,375.5,81S305,271.334,770,271.334"/>

		<use xlink:href="#cow" width="30" height="30" />
    <use xlink:href="#cow" width="30" height="30" />
	</svg>
       
</div>

【讨论】:

  • 非常感谢。如果我有任何问题,我会尝试植入我的 svg 并回复你。你知道如何让 svg 对象自动沿路径方向旋转吗?
猜你喜欢
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 2021-08-16
  • 2018-12-12
  • 2019-02-13
  • 2016-02-14
相关资源
最近更新 更多