路径线上的SVG对象动画

时间:2018-11-26 08:23:46

标签: javascript animation svg

我想为一条线上的svg路径设置动画。就像这样的Codepen,但我不想使用多边形,而是想使用更复杂的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路径文件替换多边形吗?

谢谢

1 个答案:

答案 0 :(得分:1)

在此示例中,我使用的是复杂的<symbol>元素而不是星形。 <symbol>包含一个路径和4个圆圈。我已将此符号放在隐藏的SVG元素中。

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

在Java语言中,我用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>