手写了一个动态的饼图效果如下,由于不会传视频不清晰请见谅
做这个的难点是三角函数的知识可能忘干净了。现在来整理下思路
- 首先我们需要分析环形有哪些属性
圆心,外半径,内半径,两个个可变的数组(分别用来存放每一部分的数量,和其对应的颜色)...
- 画出环形
- 通过for循环分别计算出对应的比例及坐标值(需要用到三角函数)
- 使用creatTagEle来遍历可变数组,渲染颜色属性,及path
- 使环形动起来
使用定时器,通过使用时间变化计算出动态比例,控制每一份数据所占弧度同比增大
<script> let svg = document.getElementById("svg");// let svgNS = "http://www.w3.org/2000/svg";//创建一个xml命名空间 // 封装一个函数用来传递标签名和样式 function creatTagEle( tag , tagAttr ){ let oTag = document.createElementNS( svgNS , tag )//在命名空间里创建svg // 遍历标签样式,添加属性 for(let attr in tagAttr){ oTag.setAttribute(attr,tagAttr[attr])//设置节点的属性 } return oTag; } let num = ["25",'20',"20",'5'];//数据比例,和要等于100 let color = ["pink",'blue',"yellow","red"];//颜色 let angle = 360;//总 let outR = 120; let inR = 70; let cx = 250; let cy = 250; let time = 1000; function move(){ let nowTime =new Date(); console.log(nowTime) let timer = setInterval(function(){ let prop = (new Date() - nowTime)/time; console.log(prop) if( prop >= 1 ){ prop = 1 clearInterval( timer ) } let angleNum = 0;//初始总弧度 let outXY = [{x:370,y:250}]; //用于存放每个弧的起点坐标 let inXY = [{x:320,y:250}]; //开始计算每一个对应的值 for (let i = 0;i<num.length;i++){ // 得出每一部分的比例值 let aNum = num[i]/100*angle; angleNum += aNum; //确定每个弧的起点坐标 if( i == num.length - 1 ){ angleNum = 360; } //外圆 let outX = Math.cos(angleNum*prop*Math.PI/180)*outR + cx; let outY = Math.sin(angleNum*prop*Math.PI/180)*outR + cy; outXY.push({x:outX,y:outY}) //内圆 let inX = Math.cos(angleNum*prop*Math.PI/180)*inR + cx; let inY = Math.sin(angleNum*prop*Math.PI/180)*inR + cy; inXY.push({x:inX,y:inY}) } console.log(inXY) console.log(outXY) //画环 for( let i = 0;i<outXY.length;i++ ){ //处理到达最后一个值的情况 if( i == outXY.length -1 ){ break; } let oPath = creatTagEle('path',{ fill:color[i],//渲染颜色值; d:`M${outXY[i].x} ${outXY[i].y}A${outR} ${outR} 0 0 1 ${outXY[i+1].x} ${outXY[i+1].y}L${inXY[i+1].x} ${inXY[i+1].y}A${inR} ${inR} 0 0 0 ${inXY[i].x} ${inXY[i].y}` }); svg.appendChild( oPath ) } },1000/60) } move() </script>