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

2. html(包含svg)结构
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值的时候 需要单独加分号)
立即学习“Java免费学习笔记(深入)”;
(3)clipPath的标签的运用,是这个案例实现滚动波纹从下到上的一个核心 。










