8.canvas 简单实现一下环形动图

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

image.png 1.gif

写得很糙, 一旦要添加各种细节时, 就会发现结构本身很重要, 驾驭结构还是感觉不清不楚的, 下面的结构,估计过两天就看不懂了,

版本1.0

思路: 如果用canvas? 用ctx.arc 根据不同百分比求出不同角度, linewidth + strokeStyle 能够完成 渲染 中间总资产 求和 用 filltext 需要一个数据 各项资产的数值. 传进函数中时, 会遍历求出总和, 以及各自的百分比, 根据百分比, 再转换成 弧度, 把该百分比,传入函数,即可完成绘图. 如何实现动画? canvas 无法通过 css transition , 和animation 可以通过 setInterval 让百分比数值渐变,每次变化都渲染一次, 到达目标数据,就停止动画.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
        <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
        <title>dddd</title>
        <style type="text/css">
          canvas {
            border: 1px solid black;
            margin: 100px;
          }
          .item{
            position: fixed;
            right: 200px;
            top: 200px;
            border: 1px solid black;
            padding: 30px;
            border-radius: 15px;
          }
        </style>
    </head>
    <body>
      
      <canvas id="myCanvas" width="500" height="500"></canvas>
      
         
         
         <div class="item">
           house: <input type="range" min="0" max="1000" value="500"  name="house" id="house" value="" /><br />
           car : <input type="range" min="0" max="1000" value="500" name="car" id="car" value="" /><br />
           monye : <input type="range" min="0" max="1000" value="500" name="money" id="money" value="" />
         </div>
         
        <script type="text/javascript">
            var myCanvas = document.getElementById("myCanvas");
            var ctx = myCanvas.getContext("2d");
            // 返回一个随机颜色
            function randomNum (num) {
            	return parseInt(Math.random() * num + 1);
            }
            
            function randomColor () {
            	return 'rgb(' + randomNum(255) +','+randomNum(255)+','+randomNum(255)+')';
            }
            
            // 假设有三个值, 先进行画图.
            // 基本数值
            
            var data = {
            }
            data.house = 55;
            data.money = 21;
            data.car = 77;
            
            
            // 构造函数
            function Data (data,ctx) {
              this.createData = function (data) {
                this.data1 = {};
                var data1 = this.data1;
                data1.sum = 0;
                for(var key in data) {
                  data1.sum += Number(data[key]);
                }
                for(var key in data){
                  data1[key] = {};
                  data1[key].rad = data[key] / data1.sum * 2 * Math.PI;
                  if (!data1[key].bgColor) {
                    data1[key].bgColor = randomColor();
                  }
                }
              }
              this.targetData = function (data) {
                // data2 为 要到达的 数据.
                this.data2 = new this.createData(data).data1;
                console.log(this.data2);
                return this;
              }
              this.render = function () {
                var beginRad = 0;
                var stopRad = 0;
                var data1 = this.data1;
                for(var key in data1){
                  if (key == "sum") {
                  	continue
                  }
                  beginRad = stopRad;
                  stopRad += data1[key].rad;
                  ctx.beginPath();
                  ctx.arc(250,250,150,beginRad,stopRad,0);
                  ctx.lineWidth = 20;
                  ctx.strokeStyle = data1[key].bgColor;
                  ctx.stroke();
                }
                ctx.font = "20px 微软";
                ctx.fillStyle = "#007AFF";
                ctx.textAlign = "center";
                ctx.verticalAlign = "middle";
                ctx.clearRect(160,160,190,190);// 这个地方也许有更简单的解决办法,
              	ctx.fillText("总资产为"+data1.sum,255,255);
              }
              
              this.change = function (data) {
              	this.targetData(data);
              	//根据data2 重新赋值给data1
              	var self = this;
              	var data2 = self.data2;
              	var data1 = self.data1;
                data1.sum = data2.sum;
              	clearInterval(this.timer);
              	this.timer = setInterval(function () {
              	  var flag = true;
              	  for(var key in data2) {
              	    if (key != "sum") {
              	    if (typeof data1[key] == "undefined") {
              	      console.log(123);
              	    	data1[key] = {};
              	    	data1[key].rad = 0;
              	    	data1[key].bgColor = data2[key].bgColor;
              	    }
              	    if (Math.abs(data2[key].rad * 100 - data1[key].rad * 100) > 1) {
              	    	data1[key].rad += (data2[key].rad*100 - data1[key].rad*100)/ 700;
              	    	flag = false;
              	    }
              	    self.render();
              	  }
              	    }
              	  if (flag) {
              	  	clearInterval(self.timer);
              	  	console.log("over");
              	  	console.log(data1);
              	  }
              	},50);
              	
              }
              
            	this.init = function () {
            		this.createData(data);
            		this.render();
            	}
              this.init();
            }
            
            var a = new Data(data,ctx);
            
            
            // 下面的是用来测试.
            var house = document.getElementById("house");
            var car = document.getElementById("car");
            var money = document.getElementById("money");
            
            house.onmouseup = function () {
              data.house = this.value;
              console.log(data);
            	a.change(data);
            }
            car.onmouseup = function () {
              data.car = this.value;
              console.log(data);
            	a.change(data);
            }
            money.onmouseup = function () {
              data.money = this.value;
              console.log(data);
            	a.change(data);
            }
            
            
            //a.change({house:123,money:111,car:156,aaa:777});

            // 能解决一个增加属性的问题,
            // 怎么解决一个减少属性的问题?
            // 对data2进行处理?
            
//            
//            var timer = setInterval(,50);
//          	
//          }
            
            
        </script>
    </body>
</html>