h5--手写svg动态饼图

手写了一个动态的饼图效果如下,由于不会传视频不清晰请见谅

做这个的难点是三角函数的知识可能忘干净了。现在来整理下思路

  1. 首先我们需要分析环形有哪些属性

        圆心,外半径,内半径,两个个可变的数组(分别用来存放每一部分的数量,和其对应的颜色)...

  1. 画出环形
    1. 通过for循环分别计算出对应的比例及坐标值(需要用到三角函数)
    2. 使用creatTagEle来遍历可变数组,渲染颜色属性,及path
  1. 使环形动起来

    使用定时器,通过使用时间变化计算出动态比例,控制每一份数据所占弧度同比增大

    <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>

 

posted @ 2019-06-12 20:22  杜帅夫人  阅读(540)  评论(0编辑  收藏  举报