Maison >interface Web >js tutoriel >Partage d'exemples de boule de progression SVG de production Javascript

Partage d'exemples de boule de progression SVG de production Javascript

小云云
小云云original
2018-03-15 09:27:062120parcourir

Avec le développement du SVG aujourd'hui, il a été utilisé dans diverses applications sur Internet, notamment la production de barres de progression et de boules de progression. Comment créer ce type d'interaction animée ? Dévoilons ensuite le secret !

1. Orientation des intérêts > Effet final - Boule de progression SVG :

Partage dexemples de boule de progression SVG de production Javascript

2. Structure

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
	<style type="text/css">
		.perText{font-size:58pt;font-family:Arial Rounded MT Bold;fill:#AD054A;text-anchor:middle;dominant-baseline: middle;text-shadow: 3px 0 6px #fff;transform:translate3d(6px,0,0);}
	</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="384.415px" height="383.232px" viewBox="0 0 384.415 383.232" >
	<circle style="fill:#E8427D;" cx="192.668" cy="195.399" r="180"/>
	<circle style="fill:#FFFFFF;" cx="192.668" cy="195.399" r="150"/>
	<circle style="display:none;fill:none;stroke:#000000;stroke-miterlimit:10;" cx="796.667" cy="-58.434" r="140.123"/>
	<path style="fill:none;" d="M656.667,8386.899"/>
	<path style="fill:none;" d="M656.667-7996.101"/>
	<g>

		<!-- 定义变量 -->
		<defs>
			<circle id="SVGID_1_" cx="191.668" cy="195.069" r="135" fill="red"/>
		</defs>
		<clipPath id="SVGID_2_">
			<use xlink:href="#SVGID_1_"  style="overflow:visible;" cx="191.668" cy="295.069" />
		</clipPath>
		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="431.4199" y1="221.6279" x2="-31.4133" y2="488.8449">
			<stop  offset="0" style="stop-color:#DA1654"/>
			<stop  offset="0.6452" style="stop-color:#E1457C;stop-opacity:0.4731"/>
			<stop  offset="1" style="stop-color:#F7F8F8;stop-opacity:0.3"/>
		</linearGradient>
		<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="462.0762" y1="286.5215" x2="-63.9186" y2="590.2048">
			<stop  offset="0" style="stop-color:#F7F8F8;stop-opacity:0.3"/>
			<stop  offset="0.5" style="stop-color:#E1457C;stop-opacity:0.4731"/>
			<stop  offset="0.871" style="stop-color:#DA1654"/>
		</linearGradient>
		
		<!-- clip-path:url(#SVGID_2_) -->
		<g class="group" id=&#39;pathGroup&#39; style="clip-path:url(#SVGID_2_)">
			<!--<path class="bgPath bgPath_01" style="fill:url(#SVGID_3_);" id="bgPathOne">
					<animate 
						dur="5s" 
						attributeName="d" 
						attributeType="XML" 
						repeatCount="indefinite" 
						values="" 
						calcMode="linear"
						keyTimes="0;.6;1"></animate>			
			</path> -->
			<path class="bgPath bgPath_02" style="fill:url(#SVGID_3_);" d="">
				<animate 
						dur="5s" 
						attributeName="d" 
						attributeType="XML" 
						repeatCount="indefinite" 
						values="" 
						calcMode="linear"
						keyTimes="0;.3;1"></animate>	
			</path>-->
		</g>
		
		<text x=&#39;192.668&#39; y=&#39;195.399&#39; class="perText">50%</text>
	</g>
</svg>
</body>
</html>

3. JavaScript calcule le chemin et contrôle l'animation svg

class svgPercent
{

	constructor({y1,y2,group,text})
	{
		this.y1 = y1 ? y1 : 0;
		this.y2 = y2 ? y2 : 0;
		this.group = group;
		this.xmlns = &#39;http://www.w3.org/2000/svg&#39;;
		this.textBox = text;
		this.currentPercentText = &#39;0%&#39;;

		//初始 进度球
		this.init();
	}

	init()
	{	
		//1.获取路径数据
		this.getSvgPathData(this.y1,this.y2);
		
		//2.根据数据绘制路径
		this.createPath();

		//3.设置百分比
		this.setPercentText();

		//4.模拟进度增长的情况
		this.changePathShape();

	}

	initChangeShape()
	{
		//1.获取路径数据
		this.getSvgPathData(this.y1,this.y2);

		//2. 设置路径形状改变
		this.setPaths();
	}

	//获取路径数据
	getSvgPathData(y,y2)
	{
		this.d1=`M327.898,${225.235+y}c3.086,${-11.496+y},4.74,${-11.496+y},4.74,${-36.167+y}c0,${0+y},-31.712,${-28.628+y},-140.67,${-2+y}c-120.71,${29.5+y},-125.21,${11+y}-140.67,${0.35+y}c0.032,${13.105+y},1.862,${25.787+y},5.247,${37.817+y}h-90.043 v390 h467 v-390 H327.898 z`;

		this.a1=`M 327.898,${225.235+y}c 3.086,${-11.496+y},4.74,${-23.611+y},4.74,${-36.167+y}c 0,${0+y},-23.971,${54.165+y},-140.67,${-2+y}c-111.97,${-53.888+y}-135.301,${-9.835+y}-140.67,${0.35+y}c 0.032,${13.105+y},1.862,${25.787+y},5.247,${37.817+y}h-90.043 v390 h 467 v-390 H 327.898 z`;	

		this.d2 = `M 327.898,${237.031+y2}c 3.086,${-14.234+y2},4.74,${-29.236+y2},4.74,${-44.785+y2}c 0,${0+y2}-30.305,${36.653+y2}-140.67,${-2.477+y2}c-118.866,${-42.144+y2}-134.529,${-9.191+y2}-140.67,${0.434+y2}c 0.032,${16.229+y2},1.862,${31.933+y2},5.247,${46.828+y2}h-90.043 v 405.865 h 467 V ${237.031+y2} H 327.898 z`;

		this.a2 = `M 327.898,${237.031+y2}c 3.086,${-14.234+y2},4.74,${-29.236+y2},4.74,${-44.785+y2}c 0,${0+y2}-56.638,${-36.347+y2}-140.67,${-2.477+y2}C 74.997,${236.916+y2},63,${199.232+y2},51.299,${190.203+y2}c 0.032,${16.229+y2},1.862,${31.933+y2},5.247,${46.828+y2}h-90.043 v 405.865 h 467 V ${237.031+y2} H 327.898 z`;
	}

	//创建path路径
	createPath(group)
	{
		this.pathOne = document.createElementNS(this.xmlns,&#39;path&#39;);
		this.animate = document.createElementNS(this.xmlns,&#39;animate&#39;);
		this.pathOne.setAttribute(&#39;style&#39;,&#39;fill:url(#SVGID_3_)&#39;);
		this.pathOne.setAttribute(&#39;d&#39;,this.d1);
		this.animate.setAttribute(&#39;dur&#39;,&#39;5s&#39;);
		this.animate.setAttribute(&#39;attributeName&#39;,&#39;d&#39;);
		this.animate.setAttribute(&#39;attributeType&#39;,&#39;XML&#39;);
		this.animate.setAttribute(&#39;repeatCount&#39;,&#39;indefinite&#39;);
		this.animate.setAttribute(&#39;keyTimes&#39;,&#39;0;0.55;1&#39;);
		this.animate.setAttribute(&#39;values&#39;,this.d1+&#39;;&#39;+this.a1+&#39;;&#39;+this.d1);
		this.pathOne.appendChild(this.animate);
		this.group.appendChild(this.pathOne);	 
		
		this.pathTwo = document.createElementNS(this.xmlns,&#39;path&#39;);
		this.animate2 = document.createElementNS(this.xmlns,&#39;animate&#39;);
		this.pathTwo.setAttribute(&#39;style&#39;,&#39;fill:url(#SVGID_3_)&#39;);
		this.pathTwo.setAttribute(&#39;d&#39;,this.d2);
		this.animate2.setAttribute(&#39;dur&#39;,&#39;5s&#39;);
		this.animate2.setAttribute(&#39;attributeName&#39;,&#39;d&#39;);
		this.animate2.setAttribute(&#39;attributeType&#39;,&#39;XML&#39;);
		this.animate2.setAttribute(&#39;repeatCount&#39;,&#39;indefinite&#39;);
		this.animate2.setAttribute(&#39;keyTimes&#39;,&#39;0;0.55;1&#39;);
		this.animate2.setAttribute(&#39;values&#39;,this.d2+&#39;;&#39;+this.a2+&#39;;&#39;+this.d2);
		this.pathTwo.appendChild(this.animate2);
		this.group.appendChild(this.pathTwo);
	}

	//设置path路径
	setPaths()
	{
		this.pathOne.setAttribute(&#39;d&#39;,this.d1);
		this.pathTwo.setAttribute(&#39;d&#39;,this.d2);
		this.animate.setAttribute(&#39;values&#39;,this.d1+&#39;;&#39;+this.a1+&#39;;&#39;+this.d1);
		this.animate2.setAttribute(&#39;values&#39;,this.d2+&#39;;&#39;+this.a2+&#39;;&#39;+this.d2);
	}

	//设置百分比文字
	setPercentText(val)
	{	
		let vals = val ? val : this.currentPercentText;
		this.textBox.textContent = vals;
	}

	//改变路径形状
	changePathShape()
	{	
		let dis = 0.3;
		let percent = &#39;&#39;;
		let p = &#39;&#39;;
		let start = this.y1;
		let end = -50;

		let This = this;
		function step()
		{
			This.y1 -= dis;
			This.y2 -= dis;
			
			This.initChangeShape();
			percent = parseInt((Math.abs(This.y1 - start) / Math.abs(end-start))*100);
			p = percent + &#39;%&#39;;
			This.setPercentText(p);
			
			if(percent < 50){
				requestAnimationFrame(step);
			}
		}

		requestAnimationFrame(step);	
	}
}

// 初始化配置参数调用
let obj = {
	y1: 50,
	y2: 50,
	group: document.querySelector(&#39;#pathGroup&#39;),
	text: document.querySelector(&#39;.perText&#39;)
}

new svgPercent(obj);

4 Résumé :

(1) Contrôler le chemin via l'attribut d animé. (notez qu'il y a des pièges, les valeurs​​ont au moins trois ensembles de valeurs​​values="valeur originale ; valeur à modifier ; valeur originale")

(2) L'attribut d du chemin est utilisé via le contrôle js (notez qu'il y a un piège. Lors de l'épissage de chaînes, il ne peut pas y avoir de point-virgule à la fin et une erreur sera signalée ; lors de l'épissage des valeurs, vous devez ajouter un point-virgule séparé)

(3) L'utilisation de balises clipPath est dans ce cas un noyau qui implémente des ondulations roulantes de bas en haut.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn