0

0

javascript制作svg进度球实例分享

小云云

小云云

发布时间:2018-03-15 09:27:06

|

2486人浏览过

|

来源于php中文网

原创

在SVG发展到今天,已经在互联网上进行了各式各样的运用,当然也就包括进度条以及进度球的制作,制作这个类型的动画交互该如何制作呢?接下来就带大家来揭秘吧!

1. 兴趣引导  > 最终效果 - SVG进度球:

360截图20180315092656052.jpg

2. html(包含svg)结构

<!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='pathGroup' 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='192.668' y='195.399' class="perText">50%</text>
	</g>
</svg>
</body>
</html>

3. javascript计算path路径,控制svg动画

class svgPercent
{

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

		//初始 进度球
		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,'path');
		this.animate = document.createElementNS(this.xmlns,'animate');
		this.pathOne.setAttribute('style','fill:url(#SVGID_3_)');
		this.pathOne.setAttribute('d',this.d1);
		this.animate.setAttribute('dur','5s');
		this.animate.setAttribute('attributeName','d');
		this.animate.setAttribute('attributeType','XML');
		this.animate.setAttribute('repeatCount','indefinite');
		this.animate.setAttribute('keyTimes','0;0.55;1');
		this.animate.setAttribute('values',this.d1+';'+this.a1+';'+this.d1);
		this.pathOne.appendChild(this.animate);
		this.group.appendChild(this.pathOne);	 
		
		this.pathTwo = document.createElementNS(this.xmlns,'path');
		this.animate2 = document.createElementNS(this.xmlns,'animate');
		this.pathTwo.setAttribute('style','fill:url(#SVGID_3_)');
		this.pathTwo.setAttribute('d',this.d2);
		this.animate2.setAttribute('dur','5s');
		this.animate2.setAttribute('attributeName','d');
		this.animate2.setAttribute('attributeType','XML');
		this.animate2.setAttribute('repeatCount','indefinite');
		this.animate2.setAttribute('keyTimes','0;0.55;1');
		this.animate2.setAttribute('values',this.d2+';'+this.a2+';'+this.d2);
		this.pathTwo.appendChild(this.animate2);
		this.group.appendChild(this.pathTwo);
	}

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

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

	//改变路径形状
	changePathShape()
	{	
		let dis = 0.3;
		let percent = '';
		let p = '';
		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 + '%';
			This.setPercentText(p);
			
			if(percent < 50){
				requestAnimationFrame(step);
			}
		}

		requestAnimationFrame(step);	
	}
}

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

new svgPercent(obj);

4.  总结:

     (1) 通过animate控制path的d属性 (注意,有坑,values至少三组值 values="原来的值 ; 要变化到的值 ; 原来的值")   

     (2) 通过js控制用到了path的d属性(注意,有坑,拼接字符串的时候,末尾不能有分号,会报错;在拼接values值的时候                 需要单独加分号)   

会译·对照式翻译
会译·对照式翻译

会译是一款AI智能翻译浏览器插件,支持多语种对照式翻译

下载

立即学习Java免费学习笔记(深入)”;

     (3)clipPath的标签的运用,是这个案例实现滚动波纹从下到上的一个核心 。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

chatgpt官网入口地址合集
chatgpt官网入口地址合集

本专题整合了chatgpt官网入口地址、使用教程等内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

minimax入口地址汇总
minimax入口地址汇总

本专题整合了minimax相关入口合集,阅读专题下面的文章了解更多详细地址。

4

2026.03.16

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

7

2026.03.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

114

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

141

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

396

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

65

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

111

2026.03.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6.1万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号