小公式大乐趣,可用作网页背景

canvas学习笔记:小公式大乐趣

2014/03/20 · HTML5 · 1
评论 ·
HTML5

原文出处: WAxes   

前不久想弄一个网页,把自己学HTML5历程中做的局地DEMO放上去做集合,不过,假设就只是做个网页把持有DEMO一个一个排列又认为太丢人了。就想,既然学了canvas,那就来折腾下浏览器,做个小小的开场动画吧。

开场动画的效益,想了一会,决定用粒子,因为觉得粒子比较好玩。还记得从前自己写的首先篇技术博文,就是讲文字图片粒子化的:文字图片粒子化 ,
那时就独自做的是直线运动,顺便加了一点3D职能。运动公式很简短。所以就想这么些开场动画就做的更动感一些啊。

先上DEMO:

意义是或不是比直线的移动更是动感呢?而且也真正很简单,别忘了那篇博文的标题,小小滴公式,大大滴乐趣。要做出这样的功效,用的就可是是大家初中。。或者高中时候的大体知识,加快移动,减速运动的公式啦。所以的确是小小滴公式。楼主很喜爱折腾一些酷炫的事物,纵然可能平时干活上用不上,不过,那乐趣确实很令人着迷啊。而且,做下这几个也得以抓好一下编程的思维能力哈。

废话不多说,进入正题啦。就概括的解释一下原理吧~~~

粒子运动的中坚代码就像此一点:

JavaScript

update:function(time){ this.x += this.vx*time; this.y += this.vy*time;
if(!this.globleDown&&this.y>0){ var yc = this.toy – this.y; var xc =
this.tox – this.x; this.jl = Math.sqrt(xc*xc+yc*yc); var za = 20; var
ax = za*(xc/this.jl), ay = za*(yc/this.jl), vx =
(this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97; this.vx = vx;
this.vy = vy; }else { var gravity = 9.8; var vy = this.vy+gravity*time;
if(this.y>canvas.height){ vy = -vy*0.7; } this.vy = vy; } },

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
update:function(time){
            this.x += this.vx*time;
            this.y += this.vy*time;
 
            if(!this.globleDown&&this.y>0){
                var yc = this.toy – this.y;
                var xc = this.tox – this.x;
 
                this.jl = Math.sqrt(xc*xc+yc*yc);
 
                var za = 20;
 
                var ax = za*(xc/this.jl),
                    ay = za*(yc/this.jl),
                    vx = (this.vx+ax*time)*0.97,
                    vy = (this.vy+ay*time)*0.97;
 
                this.vx = vx;
                this.vy = vy;
 
            }else {
                var gravity = 9.8;
                var vy = this.vy+gravity*time;
 
                if(this.y>canvas.height){
                    vy = -vy*0.7;
                }
 
                this.vy = vy;
            }
        },

粒子总共有二种情状,一种是自由落体,一种就是面临吸力。自由落体就隐瞒了。说吸力往日先贴出粒子的属性:

JavaScript

var Dot = function(x,y,vx,vy,tox,toy,color){ this.x=x; this.y=y;
this.vx=vx; this.vy=vy; this.nextox = tox; this.nextoy = toy; this.color
= color; this.visible = true; this.globleDown = false; this.setEnd(tox ,
toy); } setEnd:function(tox , toy){     this.tox = tox;
    this.toy = toy;     var yc = this.toy – this.y;     var
xc = this.tox – this.x; },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Dot = function(x,y,vx,vy,tox,toy,color){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.nextox = tox;
        this.nextoy = toy;
        this.color = color;
        this.visible = true;
        this.globleDown = false;
        this.setEnd(tox , toy);
    }
 
setEnd:function(tox , toy){
    this.tox = tox;
    this.toy = toy;
    var yc = this.toy – this.y;
    var xc = this.tox – this.x;
},

x,y就是粒子的义务,vx是粒子水平速度,vy是粒子的垂直速度,nexttox之类知否道都不在乎,只是暂时保留变量的。tox,和toy就是粒子的目标地地点。

首先,先予以负有粒子一个目的地,那几个目的地上面再会说。也就是要粒子到达的地方,然后再定义一个变量za作为加快度,具体数值的话,就协调多测试下就会有大概参数的了,我设成20,感觉就基本上了。za是粒子和目的地之间连线的增速度,所以,大家透过粒子的任务和目标地的职责,通过不难的三角形函数,就可以把粒子的品位加快度和垂直加快度求出来了,就那段

JavaScript

var ax = za*(xc/this.jl), ay = za*(yc/this.jl),

1
2
var ax = za*(xc/this.jl),
  ay = za*(yc/this.jl),

有了水平加速度和垂直加速度后,接下去就更简便易行了,直接统计水平速度和垂直速度的增量,从而改变程度速度和垂直速度的值

JavaScript

vx = (this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97;

1
2
vx = (this.vx+ax*time)*0.97,
vy = (this.vy+ay*time)*0.97;

所以要乘于0.97是为了仿功能量消耗,粒子才会减慢。time是每一帧的时日差

总结出速度后就立异粒子地点就行了。

JavaScript

this.x += this.vx*time; this.y += this.vy*time;

1
2
this.x += this.vx*time;
this.y += this.vy*time;

因为粒子在航空进程中,与目标地之间的连线方向是不停改变的,所以每一帧都要重复统计粒子的水准加速度和垂直加速度。

移步规律就是这么,是不是很简单吗。

运动规律说完了,再扯一下地点非凡动画的切实落到实处吗:动画开始化,在一个离屏canvas上把想要的字或者图片画出来,然后再通过getImageData这一个法子拿到离屏canvas的像素。然后用一个循环,把离屏canvas中有绘制的区域找出来,因为imageData里的data值就是一个rgba数组,所以大家判断最终一个的值也就是透明度大于128就是有绘制过的区域。然后拿走该区域的xy值,为了防止粒子对象过多导致页面卡顿,所以大家就限制一下粒子的数码,取像素的时候x值和y值每一遍递增2,从而减少粒子数量。

JavaScript

this.osCanvas = document.createElement("canvas"); var osCtx =
this.osCanvas.getContext("2d"); this.osCanvas.width = 1000;
this.osCanvas.height = 150; osCtx.textAlign = "center";
osCtx.textBaseline = "middle"; osCtx.font="70px
微软雅黑,钟鼓文 bold"; osCtx.fillStyle = "#1D181F"
osCtx.fillText("WelCome" , this.osCanvas.width/2 ,
this.osCanvas.height/2-40); osCtx.fillText("To wAxes'
HOME" , this.osCanvas.width/2 , this.osCanvas.height/2+40); var
bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); dots =
[]; for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]>128){ var dot = new Dot(
Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
-Math.random()*canvas.height*2, 0, 0,
x+(canvas.width/2-this.osCanvas.width/2),
y+(canvas.height/2-this.osCanvas.height/2),
"rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]+","+bigImageData.data[i+2]+",1)"
); dot.setEnd(canvas.width/2,canvas.height/2) dots.push(dot); } } }

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
this.osCanvas = document.createElement(&quot;canvas&quot;);
        var osCtx = this.osCanvas.getContext(&quot;2d&quot;);
 
        this.osCanvas.width = 1000;
        this.osCanvas.height = 150;
 
        osCtx.textAlign = &quot;center&quot;;
        osCtx.textBaseline = &quot;middle&quot;;
        osCtx.font=&quot;70px 微软雅黑,黑体 bold&quot;;
        osCtx.fillStyle = &quot;#1D181F&quot;
        osCtx.fillText(&quot;WelCome&quot; , this.osCanvas.width/2 , this.osCanvas.height/2-40);
        osCtx.fillText(&quot;To wAxes&#039; HOME&quot; , this.osCanvas.width/2 , this.osCanvas.height/2+40);
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        dots = [];
 
        for(var x=0;x&lt;bigImageData.width;x+=2){
            for(var y=0;y&lt;bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]&gt;128){
                    var dot = new Dot(
                        Math.random()&gt;0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
                        -Math.random()*canvas.height*2,
                        0,
                        0,
                        x+(canvas.width/2-this.osCanvas.width/2),
                        y+(canvas.height/2-this.osCanvas.height/2),
                        &quot;rgba(&quot;+bigImageData.data[i]+&quot;,&quot;+bigImageData.data[i+1]+&quot;,&quot;+bigImageData.data[i+2]+&quot;,1)&quot;
                    );
                    dot.setEnd(canvas.width/2,canvas.height/2)
                    dots.push(dot);
                }
            }
        }

经过轮回获取到粒子的岗位xy值后,把地点赋给粒子,成为粒子的目标地。然后动画开始,就可以做出文字图片粒子化的效率了。

下边贴出动画达成的js代码。如果对别的代码也有趣味的,可以一向看控制台哈,没压缩的。

JavaScript

var part_1 = (function(w){ var dots = [],DOT_SIZE = 2,cube=null; var
Dot = function(x,y,vx,vy,tox,toy,color){ this.x=x; this.y=y; this.vx=vx;
this.vy=vy; this.nextox = tox; this.nextoy = toy; this.color = color;
this.visible = true; this.globleDown = false; this.setEnd(tox , toy); }
Dot.prototype = { paint:function(){ ctx.fillStyle=this.color;
ctx.fillRect(this.x-DOT_SIZE/2 , this.y-DOT_SIZE/2 , DOT_SIZE ,
DOT_SIZE); }, setEnd:function(tox , toy){ this.tox = tox; this.toy =
toy; var yc = this.toy – this.y; var xc = this.tox – this.x; //
this.initjl = Math.sqrt(xc*xc+yc*yc); }, update:function(time){ this.x
+= this.vx*time; this.y += this.vy*time;
if(!this.globleDown&&this.y>0){ var yc = this.toy – this.y;
var xc = this.tox – this.x; this.jl = Math.sqrt(xc*xc+yc*yc); var za =
20; var ax = za*(xc/this.jl), ay = za*(yc/this.jl), vx =
(this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97; this.vx = vx;
this.vy = vy; //
if(Math.abs(this.vx)<1&&Math.abs(this.vy)<1){ // this.y =
this.toy // this.x = this.tox // } }else { var gravity = 9.8; var vy =
this.vy+gravity*time; if(this.y>canvas.height){ vy = -vy*0.7; }
this.vy = vy; } }, loop:function(time){ this.update(time); this.paint();
} } var animate = function(){ this.state = "before" } var ap =
animate.prototype; ap.init = function(){ this.osCanvas =
document.createElement("canvas"); var osCtx =
this.osCanvas.getContext("2d"); this.osCanvas.width = 1000;
this.osCanvas.height = 150; osCtx.textAlign = "center";
osCtx.textBaseline = "middle"; osCtx.font="70px
微软雅黑,大篆 bold"; osCtx.fillStyle = "#1D181F"
osCtx.fillText("WelCome" , this.osCanvas.width/2 ,
this.osCanvas.height/2-40); osCtx.fillText("To wAxes'
HOME" , this.osCanvas.width/2 , this.osCanvas.height/2+40); var
bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); dots =
[]; for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]>128){ var dot = new Dot(
Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
-Math.random()*canvas.height*2, 0, 0,
x+(canvas.width/2-this.osCanvas.width/2),
y+(canvas.height/2-this.osCanvas.height/2),
"rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]+","+bigImageData.data[i+2]+",1)"
); dot.setEnd(canvas.width/2,canvas.height/2) dots.push(dot); } } }
console.log(dots.length) } ap.changeState = function(){ var osCtx =
this.osCanvas.getContext("2d");
osCtx.clearRect(0,0,this.osCanvas.width,this.osCanvas.height);
this.osCanvas.width = 460; this.osCanvas.height = 100;
osCtx.fillStyle="#5C5656" osCtx.fillRect(20,20,60,60)
drawLogo(this.osCanvas , osCtx); var bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); var
index=0; dots.sort(function(a , b){ return Math.random()-Math.random();
}) for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]>128){ var d = dots[index];
if(d){ d.setEnd(x+(canvas.width/2-300) , y+50) d.color =
"rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]小公式大乐趣,可用作网页背景。+","+bigImageData.data[i+2]+",1)";
index++ } } } } setTimeout(function(){ var endindex = index; for(var
i=0;i<dots.length-endindex;i++){ if(dots[index]){ var d =
dots[index]; d.globleDown = true; d.vx = Math.random()*100-50; }
index++; } } , 2000) } function endState(){ canvas.width = 600;
canvas.height = 100; canvas.style.display="block";
canvas.style.top = "50px"; canvas.style.left =
(window.innerWidth-canvas.width)/2+"px"; cube = new Cube(50);
cube._initVector(50,50); } function drawLogo(canvas , ctx){
ctx.textAlign = "center"; ctx.textBaseline =
"middle"; ctx.font="65px 微软雅黑,黑体 bold"
ctx.fillStyle="#E06D2F" ctx.fillText("DEMO" , 300 ,
canvas.height/2) ctx.font="40px 微软雅黑,楷书 bold"
ctx.fillStyle="#405159" ctx.fillText("吖猩的" , 160
, canvas.height/2) ctx.fillText("小窝" , 420 ,
canvas.height/2) } var num = 0; ap.update = function(time){ time =
time/100;
if(this.state==="first"||this.state==="before"){ var
completeNum = 0; dots.forEach(function(dot){ if(dot.visible)
dot.loop(time); if(dot.jl<5){ completeNum++ } });
if(completeNum>=5*dots.length/6){
if(this.state==="before"){ this.state = "first";
dots.forEach(function(dot){ dot.setEnd(dot.nextox , dot.nextoy); });
}else { this.state = "second"; this.changeState(); } } }else
if(this.state==="second"){ var completeNum = 0, allnum = 0;
dots.forEach(function(dot){ if(dot.visible) dot.loop(time);
if(dot.globleDown){ allnum++; if(Math.abs(dot.y-canvas.height)<2){
completeNum++ } } }); if(completeNum===allnum&&allnum!==0){
this.state = "third"; part_2.animate(); endState(); } }else
if(this.state==="third"){ cube.update(); drawLogo(canvas ,
ctx); } } return new animate(); })(window)

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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
var part_1 = (function(w){
    var dots = [],DOT_SIZE = 2,cube=null;
 
    var Dot = function(x,y,vx,vy,tox,toy,color){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.nextox = tox;
        this.nextoy = toy;
        this.color = color;
        this.visible = true;
        this.globleDown = false;
        this.setEnd(tox , toy);
    }
 
    Dot.prototype = {
        paint:function(){
            ctx.fillStyle=this.color;
            ctx.fillRect(this.x-DOT_SIZE/2 , this.y-DOT_SIZE/2 , DOT_SIZE , DOT_SIZE);
        },
 
        setEnd:function(tox , toy){
            this.tox = tox;
            this.toy = toy;
            var yc = this.toy – this.y;
            var xc = this.tox – this.x;
            // this.initjl = Math.sqrt(xc*xc+yc*yc);
        },
 
        update:function(time){
            this.x += this.vx*time;
            this.y += this.vy*time;
 
            if(!this.globleDown&amp;&amp;this.y&gt;0){
                var yc = this.toy – this.y;
                var xc = this.tox – this.x;
 
                this.jl = Math.sqrt(xc*xc+yc*yc);
 
                var za = 20;
 
                var ax = za*(xc/this.jl),
                    ay = za*(yc/this.jl),
                    vx = (this.vx+ax*time)*0.97,
                    vy = (this.vy+ay*time)*0.97;
 
                this.vx = vx;
                this.vy = vy;
 
                // if(Math.abs(this.vx)&lt;1&amp;&amp;Math.abs(this.vy)&lt;1){
                //     this.y = this.toy
                //     this.x = this.tox
                // }
            }else {
                var gravity = 9.8;
                var vy = this.vy+gravity*time;
 
                if(this.y&gt;canvas.height){
                    vy = -vy*0.7;
                }
 
                this.vy = vy;
            }
        },
 
        loop:function(time){
            this.update(time);
            this.paint();
        }
    }
 
    var animate = function(){
        this.state = &quot;before&quot;
    }
 
    var ap = animate.prototype;
 
    ap.init = function(){
        this.osCanvas = document.createElement(&quot;canvas&quot;);
        var osCtx = this.osCanvas.getContext(&quot;2d&quot;);
 
        this.osCanvas.width = 1000;
        this.osCanvas.height = 150;
 
        osCtx.textAlign = &quot;center&quot;;
        osCtx.textBaseline = &quot;middle&quot;;
        osCtx.font=&quot;70px 微软雅黑,黑体 bold&quot;;
        osCtx.fillStyle = &quot;#1D181F&quot;
        osCtx.fillText(&quot;WelCome&quot; , this.osCanvas.width/2 , this.osCanvas.height/2-40);
        osCtx.fillText(&quot;To wAxes&#039; HOME&quot; , this.osCanvas.width/2 , this.osCanvas.height/2+40);
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        dots = [];
 
        for(var x=0;x&lt;bigImageData.width;x+=2){
            for(var y=0;y&lt;bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]&gt;128){
                    var dot = new Dot(
                        Math.random()&gt;0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
                        -Math.random()*canvas.height*2,
                        0,
                        0,
                        x+(canvas.width/2-this.osCanvas.width/2),
                        y+(canvas.height/2-this.osCanvas.height/2),
                        &quot;rgba(&quot;+bigImageData.data[i]+&quot;,&quot;+bigImageData.data[i+1]+&quot;,&quot;+bigImageData.data[i+2]+&quot;,1)&quot;
                    );
                    dot.setEnd(canvas.width/2,canvas.height/2)
                    dots.push(dot);
                }
            }
        }
        console.log(dots.length)
    }
 
    ap.changeState = function(){
        var osCtx = this.osCanvas.getContext(&quot;2d&quot;);
        osCtx.clearRect(0,0,this.osCanvas.width,this.osCanvas.height);
        this.osCanvas.width = 460;
        this.osCanvas.height = 100;
 
        osCtx.fillStyle=&quot;#5C5656&quot;
        osCtx.fillRect(20,20,60,60)
 
        drawLogo(this.osCanvas , osCtx);
 
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        var index=0;
        dots.sort(function(a , b){
            return Math.random()-Math.random();
        })
        for(var x=0;x&lt;bigImageData.width;x+=2){
            for(var y=0;y&lt;bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]&gt;128){
                        var d = dots[index];
                        if(d){
                            d.setEnd(x+(canvas.width/2-300) , y+50)
                            d.color = &quot;rgba(&quot;+bigImageData.data[i]+&quot;,&quot;+bigImageData.data[i+1]+&quot;,&quot;+bigImageData.data[i+2]+&quot;,1)&quot;;
                            index++
                        }
                }
            }
        }
 
        setTimeout(function(){
            var endindex = index;
            for(var i=0;i&lt;dots.length-endindex;i++){
                if(dots[index]){
                    var d = dots[index];
 
                    d.globleDown = true;
                    d.vx = Math.random()*100-50;
                }
                index++;
            }
        } , 2000)
    }
 
    function endState(){
        canvas.width = 600;
        canvas.height = 100;
        canvas.style.display=&quot;block&quot;;
        canvas.style.top = &quot;50px&quot;;
        canvas.style.left = (window.innerWidth-canvas.width)/2+&quot;px&quot;;
        cube = new Cube(50);
        cube._initVector(50,50);
    }
 
    function drawLogo(canvas , ctx){
        ctx.textAlign = &quot;center&quot;;
        ctx.textBaseline = &quot;middle&quot;;
        ctx.font=&quot;65px 微软雅黑,黑体 bold&quot;
        ctx.fillStyle=&quot;#E06D2F&quot;
        ctx.fillText(&quot;DEMO&quot; , 300 , canvas.height/2)
 
        ctx.font=&quot;40px 微软雅黑,黑体 bold&quot;
        ctx.fillStyle=&quot;#405159&quot;
        ctx.fillText(&quot;吖猩的&quot; , 160 , canvas.height/2)
        ctx.fillText(&quot;小窝&quot; , 420 , canvas.height/2)
    }
 
    var num = 0;
    ap.update = function(time){
        time = time/100;
        if(this.state===&quot;first&quot;||this.state===&quot;before&quot;){
            var completeNum = 0;
            dots.forEach(function(dot){
                if(dot.visible) dot.loop(time);
                if(dot.jl&lt;5){
                    completeNum++
                }
            });
            if(completeNum&gt;=5*dots.length/6){
 
                if(this.state===&quot;before&quot;){
                    this.state = &quot;first&quot;;
                    dots.forEach(function(dot){
                        dot.setEnd(dot.nextox , dot.nextoy);
                    });
                }else {
                    this.state = &quot;second&quot;;
                    this.changeState();
                }
            }
        }else if(this.state===&quot;second&quot;){
            var completeNum = 0,
                allnum = 0;
            dots.forEach(function(dot){
                if(dot.visible) dot.loop(time);
                if(dot.globleDown){
                    allnum++;
                    if(Math.abs(dot.y-canvas.height)&lt;2){
                        completeNum++
                    }
                }
            });
 
            if(completeNum===allnum&amp;&amp;allnum!==0){
                this.state = &quot;third&quot;;
                part_2.animate();
                endState();
            }
        }else if(this.state===&quot;third&quot;){
            cube.update();
            drawLogo(canvas , ctx);
        }
    }
 
    return new animate();
})(window)

赞 1 收藏 1
评论

美高梅开户网址 1

初稿出处: WAxes   

用HTML5中的Canvas结合公式绘制粒子运动的课程,html5canvas

这篇作品主要介绍了用HTML5中的Canvas结合公式绘制粒子运动的课程,并且须求利用Javascript代码作为公式,需求的对象可以参考下

近来想弄一个网页,把团结学HTML5进程中做的一部分DEMO放上去做集合,可是,假诺就独自做个网页把富有DEMO一个一个排列又觉得太不要脸了。就想,既然学了canvas,那就来折腾下浏览器,做个小小的开场动画吧。

开场动画的成效,想了一会,决定用粒子,因为觉得粒子相比好玩。还记得以前我写的第一篇技术博文,就是讲文字图片粒子化的:文字图片粒子化

那时就不过做的是直线运动,顺便加了一些3D职能。运动公式很不难。所以就想以此开场动画就做的更精神一些吧。

先上DEMO:

功效是还是不是比直线的位移进一步振奋呢?而且也确实很粗略,别忘了那篇博文的难点,小小滴公式,大大滴乐趣。要做出这么的法力,用的就一味是大家初中。。或者高中时候的大体知识,加速移动,减速运动的公式啦。所以的确是小小滴公式。楼主很喜爱折腾一些酷炫的事物,即使可能日常工作上用不上,不过,那乐趣确实很令人着迷啊。而且,做下这一个也足以增进一下编程的思维能力哈。

废话不多说,进入正题啦。就概括的解释一下原理吧~~~

粒子运动的中坚代码就这么一点:
 

XML/HTML Code复制内容到剪贴板

  1. update:function(time){   
  2.             this.x += this.vx*time;   
  3.             this.y += this.vy*time;   
  4.     
  5.             if(!this.globleDown&&this.y>0){   
  6.                 var yc = this.toy – this.y;   
  7.                 var xc = this.tox – this.x;   
  8.     
  9.                 this.jl = Math.sqrt(xc*xc+yc*yc);   
  10.     
  11.                 var za = 20;   
  12.     
  13.                 var ax = za*(xc/this.jl),   
  14.                     ay = za*(yc/this.jl),   
  15.                     vx = (this.vx+ax*time)*0.97,   
  16.                     vy = (this.vy+ay*time)*0.97;   
  17.     
  18.                 this.vx = vx;   
  19.                 this.vy = vy;   
  20.     
  21.             }else {   
  22.                 var gravity = 9.8;   
  23.                 var vy = this.vy+gravity*time;   
  24.     
  25.                 if(this.y>canvas.height){   
  26.                     vy = -vy*0.7;   
  27.                 }   
  28.     
  29.                 this.vy = vy;   
  30.             }   
  31.         },   

粒子总共有三种情况,一种是自由落体,一种就是饱受吸力。自由落体就不说了。说吸力以前先贴出粒子的品质:
 

JavaScript Code复制内容到剪贴板

  1. var Dot = function(x,y,vx,vy,tox,toy,color){   
  2.         this.x=x;   
  3.         this.y=y;   
  4.         this.vx=vx;   
  5.         this.vy=vy;   
  6.         this.nextox = tox;   
  7.         this.nextoy = toy;   
  8.         this.color = color;   
  9.         this.visible = true;   
  10.         this.globleDown = false;   
  11.         this.setEnd(tox , toy);   
  12.     }   
  13.     
  14. setEnd:function(tox , toy){   
  15.                 this.tox = tox;   
  16.                 this.toy = toy;   
  17.                 var yc = this.toy – this.y;   
  18.                 var xc = this.tox – this.x;   
  19.         },   
  20.   

x,y就是粒子的岗位,vx是粒子水平速度,vy是粒子的垂直速度,nexttox之类知道仍旧不知道道都无所谓,只是临时保留变量的。tox,和toy就是粒子的目的地地点。

先是,先予以负有粒子一个目的地,那几个目标地上边再会说。也就是要粒子到达的地方,然后再定义一个变量za作为加快度,具体数值的话,就自己多测试下就会有大概参数的了,我设成20,感觉就基本上了。za是粒子和目标地之间连线的增速度,所以,大家透过粒子的岗位和目标地的义务,通过不难的三角函数,就足以把粒子的档次加快度和垂直加快度求出来了,就那段
 

JavaScript Code复制内容到剪贴板

  1. var ax = za*(xc/this.jl),   
  2.  ay = za*(yc/this.jl),     

有了档次加快度和垂直加快度后,接下去就更简明了,直接总结水平速度和垂直速度的增量,从而改变程度速度和垂直速度的值
 

XML/HTML Code复制内容到剪贴板

  1. vx = (this.vx+ax*time)*0.97,   
  2. vy = (this.vy+ay*time)*0.97;  

就此要乘于0.97是为了仿效用量消耗,粒子才会减慢。time是每一帧的时刻差

测算出速度后就更新粒子地方就行了。
 

XML/HTML Code复制内容到剪贴板

  1. this.x += this.vx*time;   
  2. this.y += this.vy*time;  

因为粒子在宇航进度中,与目的地之间的连线方向是不停改变的,所以每一帧都要重新总括粒子的品位加速度和垂直加快度。

移动规律就是这么,是还是不是很简短吗。

活动规律说完了,再扯一下方面至极动画的现实贯彻呢:动画初叶化,在一个离屏canvas上把想要的字照旧图片画出来,然后再通过getImageData这些主意取得离屏canvas的像素。然后用一个循环往复,把离屏canvas中有绘制的区域找出来,因为imageData里的data值就是一个rgba数组,所以大家看清最后一个的值也就是透明度大于128就是有绘制过的区域。然后拿走该区域的xy值,为了幸免粒子对象过多导致页面卡顿,所以大家就限制一下粒子的数量,取像素的时候x值和y值每便递增2,从而减少粒子数量。
 

XML/HTML Code复制内容到剪贴板

  1. this.osCanvas = document.createElement(“canvas”);   
  2.         var osCtx = this.osCanvas.getContext(“2d”);   
  3.     
  4.         this.osCanvas.width = 1000;   
  5.         this.osCanvas.height = 150;   
  6.     
  7.         osCtx.textAlign = “center”;   
  8.         osCtx.textBaseline = “middle”;   
  9.         osCtx.font=”70px 微软雅黑,钟鼓文 bold”;   
  10.         osCtx.fillStyle = “#1D181F”  
  11.         osCtx.fillText(“WelCome” , this.osCanvas.width/2 , this.osCanvas.height/2-40);
      
  12.         osCtx.fillText(“To wAxes’ HOME” , this.osCanvas.width/2 , this.osCanvas.height/2+40);
      
  13.         var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
      
  14.     
  15.         dots = [];   
  16.     
  17.         for(var x=0;x<bigImageData.width;x+=2){   
  18.             for(var y=0;y<bigImageData.height;y+=2){   
  19.                 var i = (y*bigImageData.width + x)*4;   
  20.                 if(bigImageData.data[i+3]>128){   
  21.                     var dot = new Dot(   
  22.                         Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
      
  23.                         -Math.random()*canvas.height*2,   
  24.                         0,   
  25.                         0,   
  26.                         x+(canvas.width/2-this.osCanvas.width/2),   
  27.                         y+(canvas.height/2-this.osCanvas.height/2),
      
  28.                         “rgba(“+bigImageData.data[i]+”,”+bigImageData.data[i+1]+”,”+bigImageData.data[i+2]+”,1)”
      
  29.                     );   
  30.                     dot.setEnd(canvas.width/2,canvas.height/2)   
  31.                     dots.push(dot);   
  32.                 }   
  33.             }   
  34.         }   

透过轮回获取到粒子的岗位xy值后,把岗位赋给粒子,成为粒子的目标地。然后动画伊始,就可以做出文字图片粒子化的效果了。

那篇小说紧要介绍了用HTML5中的Canvas结合公式绘制粒子运动的科目,并且必要利用J…

HTML5梦境星空,可用作网页背景,html5网页背景

<html>
<head>
<title>星空</title>
<META http-equiv=”X-UA-Compatible”
content=”IE=edge”></META>
<META http-equiv=”Content-Type” content=”text/html;
charset=gb2312″/>
<script>
var BW = 800; //canvas width
var BH = 600; //canvas height
var MAX_STAR_SIZE = 3;
var MAX_STAR_SPEED = 1;
var STAR_COUNT = 120;
var BGCOLOR = “black”;
var ctx;
var stars = [];

function rndf(n){
return Math.floor(Math.random()*n);
}

function rndc(n){
return Math.ceil(Math.random()*n);
}

function Star(){
this.reset = function(){
this.x = 0;
this.y = rndf(BH);
this.size = rndc(MAX_STAR_SIZE);
this.vx = MAX_STAR_SPEED*this.size/MAX_STAR_SIZE;
this.vy = 0;
this.color = “rgba(“+rndf(255)+”, “+rndf(255)+”, “+rndf(255)+”, 0.5)”;
};

this.reset();
this.x = rndf(BW);
}
function render(){
ctx.globalCompositeOperation = “source-over”;
ctx.fillStyle = “rgba(0, 0, 0, 0.3)”;
ctx.fillRect(0, 0, BW, BH);
ctx.globalCompositeOperation = “lighter”;
for(var i = 0; i < STAR_COUNT; ++i){
var p = stars[i];
ctx.beginPath();
var gradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y,
p.size);
gradient.addColorStop(0, “white”);
gradient.addColorStop(0.4, “white”);
gradient.addColorStop(0.4, p.color);
gradient.addColorStop(1, “black”);
ctx.fillStyle = gradient;
ctx.arc(p.x, p.y, p.size, Math.PI*2, false);
ctx.fill();
p.x += p.vx;
p.y += p.vy;

if(p.x<=0 || p.x>=BW || p.y<=0 || p.y>=BH){
p.reset();
}
}
}
function init(){
if (!window.console){
console = {log:function(){},debug:function(){}};
}
//create canvas
var cv = document.createElement(‘canvas’);
cv.width = BW;
cv.height = BH;
cv.style.background = BGCOLOR;
document.body.appendChild(cv);
ctx = cv.getContext(“2d”);
//create all stars
for(var i=0;i<STAR_COUNT;++i){
var s = new Star();
stars.push(s);
}
setInterval(render, 33);
};
</script>
</head>
<body onload=”init()”>
<div>;
</body>
</html>

html
head title星空/title META http-equiv=”X-UA-Compatible”
content=”IE=edge”/META META http-equiv=”Content-Type” co…

目前想弄一个网页,把团结学HTML5进度中做的一部分DEMO放上去做集合,但是,如若就但是做个网页把拥有DEMO一个一个排列又认为太掉价了。就想,既然学了canvas,那就来折腾下浏览器,做个不大开场动画吧。

开场动画的法力,想了一会,决定用粒子,因为觉得粒子比较好玩。还记得往日自己写的第一篇技术博文,就是讲文字图片粒子化的:文字图片粒子化 ,
那时就一味做的是直线运动,顺便加了一些3D效益。运动公式很简单。所以就想以此开场动画就做的更饱满一些吗。

先上DEMO:

效果是否比直线的活动更是动感呢?而且也真正很简单,别忘了那篇博文的标题,小小滴公式,大大滴乐趣。要做出如此的成效,用的就独自是大家初中。。或者高中时候的物理知识,加快移动,减速运动的公式啦。所以的确是小小滴公式。楼主很兴奋折腾一些酷炫的事物,即使可能平常做事上用不上,但是,那乐趣确实很令人着迷啊。而且,做下那么些也能够进步一下编程的思维能力哈。

废话不多说,进入正题啦。就简单的解释一下原理吧~~~

粒子运动的为主代码就那样一点:

JavaScript

update:function(time){ this.x += this.vx*time; this.y += this.vy*time;
if(!this.globleDown&&this.y>0){ var yc = this.toy – this.y; var xc =
this.tox – this.x; this.jl = Math.sqrt(xc*xc+yc*yc); var za = 20; var
ax = za*(xc/this.jl), ay = za*(yc/this.jl), vx =
(this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97; this.vx = vx;
this.vy = vy; }else { var gravity = 9.8; var vy = this.vy+gravity*time;
if(this.y>canvas.height){ vy = -vy*0.7; } this.vy = vy; } },

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
update:function(time){
            this.x += this.vx*time;
            this.y += this.vy*time;
 
            if(!this.globleDown&&this.y>0){
                var yc = this.toy – this.y;
                var xc = this.tox – this.x;
 
                this.jl = Math.sqrt(xc*xc+yc*yc);
 
                var za = 20;
 
                var ax = za*(xc/this.jl),
                    ay = za*(yc/this.jl),
                    vx = (this.vx+ax*time)*0.97,
                    vy = (this.vy+ay*time)*0.97;
 
                this.vx = vx;
                this.vy = vy;
 
            }else {
                var gravity = 9.8;
                var vy = this.vy+gravity*time;
 
                if(this.y>canvas.height){
                    vy = -vy*0.7;
                }
 
                this.vy = vy;
            }
        },

粒子总共有二种情景,一种是自由落体,一种就是面临吸力。自由落体就背着了。说吸力之前先贴出粒子的特性:

var Dot = function(x,y,vx,vy,tox,toy,color){ this.x=x; this.y=y;
this.vx=vx; this.vy=vy; this.nextox = tox; this.nextoy = toy; this.color
= color; this.visible = true; this.globleDown = false; this.setEnd(tox ,
toy); } setEnd:function(tox , toy){     this.tox = tox;
    this.toy = toy;     var yc = this.toy – this.y;     var
xc = this.tox – this.x; },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Dot = function(x,y,vx,vy,tox,toy,color){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.nextox = tox;
        this.nextoy = toy;
        this.color = color;
        this.visible = true;
        this.globleDown = false;
        this.setEnd(tox , toy);
    }
 
setEnd:function(tox , toy){
    this.tox = tox;
    this.toy = toy;
    var yc = this.toy – this.y;
    var xc = this.tox – this.x;
},

x,y就是粒子的职责,vx是粒子水平速度,vy是粒子的垂直速度,nexttox之类知否道都不在乎,只是暂时保留变量的。tox,和toy就是粒子的目的地地方。

首先,先予以负有粒子一个目的地,那一个目标地上面再会说。也就是要粒子到达的地方,然后再定义一个变量za作为加速度,具体数值的话,就协调多测试下就会有大致参数的了,我设成20,感觉就大概了。za是粒子和目标地之间连线的加速度,所以,大家由此粒子的职分和目标地的义务,通过不难的三角形函数,就可以把粒子的档次加快度和垂直加快度求出来了,就那段

var ax = za*(xc/this.jl), ay = za*(yc/this.jl),

1
2
var ax = za*(xc/this.jl),
  ay = za*(yc/this.jl),

有了水平加速度和垂直加快度后,接下去就更简明了,直接统计水平速度和垂直速度的增量,从而改变程度速度和垂直速度的值

vx = (this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97;

1
2
vx = (this.vx+ax*time)*0.97,
vy = (this.vy+ay*time)*0.97;

为此要乘于0.97是为着仿功能量消耗,粒子才会减慢。time是每一帧的时刻差

计量出速度后就立异粒子位置就行了。

this.x += this.vx*time; this.y += this.vy*time;

1
2
this.x += this.vx*time;
this.y += this.vy*time;

因为粒子在航空进度中,与目标地之间的连线方向是不停改变的,所以每一帧都要双重总结粒子的程度加快度和垂直加速度。

挪动规律就是那般,是或不是很简短吗。

举手投足规律说完了,再扯一下地点非常动画的切实可行落成吗:动画开端化,在一个离屏canvas上把想要的字依旧图片画出来,然后再经过getImageData那么些办法获得离屏canvas的像素。然后用一个循环,把离屏canvas中有绘制的区域找出来,因为imageData里的data值就是一个rgba数组,所以大家看清最终一个的值也就是透明度大于128就是有绘制过的区域。然后拿走该区域的xy值,为了防患粒子对象过多导致页面卡顿,所以大家就限制一下粒子的数目,取像素的时候x值和y值每一趟递增2,从而收缩粒子数量。

this.osCanvas = document.createElement(“canvas”); var osCtx =
this.osCanvas.getContext(“2d”); this.osCanvas.width = 1000;
this.osCanvas.height = 150; osCtx.textAlign = “center”;
osCtx.textBaseline = “middle”; osCtx.font=”70px 微软雅黑,大篆 bold”;
osCtx.fillStyle = “#1D181F” osCtx.fillText(“WelCome” ,
this.osCanvas.width/2 , this.osCanvas.height/2-40); osCtx.fillText(“To
wAxes’ HOME” , this.osCanvas.width/2 , this.osCanvas.height/2+40); var
bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); dots =
[]; for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]美高梅开户网址 ,>128){ var dot = new Dot(
Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
-Math.random()*canvas.height*2, 0, 0,
x+(canvas.width/2-this.osCanvas.width/2),
y+(canvas.height/2-this.osCanvas.height/2),
“rgba(“+bigImageData.data[i]+”,”+bigImageData.data[i+1]+”,”+bigImageData.data[i+2]+”,1)”
); dot.setEnd(canvas.width/2,canvas.height/2) dots.push(dot); } } }

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
this.osCanvas = document.createElement("canvas");
        var osCtx = this.osCanvas.getContext("2d");
 
        this.osCanvas.width = 1000;
        this.osCanvas.height = 150;
 
        osCtx.textAlign = "center";
        osCtx.textBaseline = "middle";
        osCtx.font="70px 微软雅黑,黑体 bold";
        osCtx.fillStyle = "#1D181F"
        osCtx.fillText("WelCome" , this.osCanvas.width/2 , this.osCanvas.height/2-40);
        osCtx.fillText("To wAxes’ HOME" , this.osCanvas.width/2 , this.osCanvas.height/2+40);
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        dots = [];
 
        for(var x=0;x<bigImageData.width;x+=2){
            for(var y=0;y<bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]>128){
                    var dot = new Dot(
                        Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
                        -Math.random()*canvas.height*2,
                        0,
                        0,
                        x+(canvas.width/2-this.osCanvas.width/2),
                        y+(canvas.height/2-this.osCanvas.height/2),
                        "rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]+","+bigImageData.data[i+2]+",1)"
                    );
                    dot.setEnd(canvas.width/2,canvas.height/2)
                    dots.push(dot);
                }
            }
        }

经过轮回获取到粒子的岗位xy值后,把地方赋给粒子,成为粒子的目标地。然后动画开首,就可以做出文字图片粒子化的效劳了。

上面贴出动画完结的js代码。如果对其他代码也有趣味的,可以一向看控制台哈,没压缩的。

var part_1 = (function(w){ var dots = [],DOT_SIZE = 2,cube=null; var
Dot = function(x,y,vx,vy,tox,toy,color){ this.x=x; this.y=y; this.vx=vx;
this.vy=vy; this.nextox = tox; this.nextoy = toy; this.color = color;
this.visible = true; this.globleDown = false; this.setEnd(tox , toy); }
Dot.prototype = { paint:function(){ ctx.fillStyle=this.color;
ctx.fillRect(this.x-DOT_SIZE/2 , this.y-DOT_SIZE/2 , DOT_SIZE ,
DOT_SIZE); }, setEnd:function(tox , toy){ this.tox = tox; this.toy =
toy; var yc = this.toy – this.y; var xc = this.tox – this.x; //
this.initjl = Math.sqrt(xc*xc+yc*yc); }, update:function(time){ this.x
+= this.vx*time; this.y += this.vy*time;
if(!this.globleDown&&this.y>0){ var yc = this.toy – this.y; var xc =
this.tox – this.x; this.jl = Math.sqrt(xc*xc+yc*yc); var za = 20; var
ax = za*(xc/this.jl), ay = za*(yc/this.jl), vx =
(this.vx+ax*time)*0.97, vy = (this.vy+ay*time)*0.97; this.vx = vx;
this.vy = vy; // if(Math.abs(this.vx)<1&&Math.abs(this.vy)<1){ //
this.y = this.toy // this.x = this.tox // } }else { var gravity = 9.8;
var vy = this.vy+gravity*time; if(this.y>canvas.height){ vy =
-vy*0.7; } this.vy = vy; } }, loop:function(time){ this.update(time);
this.paint(); } } var animate = function(){ this.state = “before” } var
ap = animate.prototype; ap.init = function(){ this.osCanvas =
document.createElement(“canvas”); var osCtx =
this.osCanvas.getContext(“2d”); this.osCanvas.width = 1000;
this.osCanvas.height = 150; osCtx.textAlign = “center”;
osCtx.textBaseline = “middle”; osCtx.font=”70px 微软雅黑,金鼎文 bold”;
osCtx.fillStyle = “#1D181F” osCtx.fillText(“WelCome” ,
this.osCanvas.width/2 , this.osCanvas.height/2-40); osCtx.fillText(“To
wAxes’ HOME” , this.osCanvas.width/2 , this.osCanvas.height/2+40); var
bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); dots =
[]; for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]>128){ var dot = new Dot(
Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
-Math.random()*canvas.height*2, 0, 0,
x+(canvas.width/2-this.osCanvas.width/2),
y+(canvas.height/2-this.osCanvas.height/2),
“rgba(“+bigImageData.data[i]+”,”+bigImageData.data[i+1]+”,”+bigImageData.data[i+2]+”,1)”
); dot.setEnd(canvas.width/2,canvas.height/2) dots.push(dot); } } }
console.log(dots.length) } ap.changeState = function(){ var osCtx =
this.osCanvas.getContext(“2d”);
osCtx.clearRect(0,0,this.osCanvas.width,this.osCanvas.height);
this.osCanvas.width = 460; this.osCanvas.height = 100;
osCtx.fillStyle=”#5C5656″ osCtx.fillRect(20,20,60,60)
drawLogo(this.osCanvas , osCtx); var bigImageData =
osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height); var
index=0; dots.sort(function(a , b){ return Math.random()-Math.random();
}) for(var x=0;x<bigImageData.width;x+=2){ for(var
y=0;y<bigImageData.height;y+=2){ var i = (y*bigImageData.width +
x)*4; if(bigImageData.data[i+3]>128){ var d = dots[index];
if(d){ d.setEnd(x+(canvas.width/2-300) , y+50) d.color =
“rgba(“+bigImageData.data[i]+”,”+bigImageData.data[i+1]+”,”+bigImageData.data[i+2]+”,1)”;
index++ } } } } setTimeout(function(){ var endindex = index; for(var
i=0;i<dots.length-endindex;i++){ if(dots[index]){ var d =
dots[index]; d.globleDown = true; d.vx = Math.random()*100-50; }
index++; } } , 2000) } function endState(){ canvas.width = 600;
canvas.height = 100; canvas.style.display=”block”; canvas.style.top =
“50px”; canvas.style.left = (window.innerWidth-canvas.width)/2+”px”;
cube = new Cube(50); cube._initVector(50,50); } function
drawLogo(canvas , ctx){ ctx.textAlign = “center”; ctx.textBaseline =
“middle”; ctx.font=”65px 微软雅黑,行书 bold” ctx.fillStyle=”#E06D2F”
ctx.fillText(“DEMO” , 300 , canvas.height/2) ctx.font=”40px
微软雅黑,行草 bold” ctx.fillStyle=”#405159″ ctx.fillText(“吖猩的” , 160
, canvas.height/2) ctx.fillText(“小窝” , 420 , canvas.height/2) } var
num = 0; ap.update = function(time){ time = time/100;
if(this.state===”first”||this.state===”before”){ var completeNum = 0;
dots.forEach(function(dot){ if(dot.visible) dot.loop(time);
if(dot.jl<5){ completeNum++ } });
if(completeNum>=5*dots.length/6){ if(this.state===”before”){
this.state = “first”; dots.forEach(function(dot){ dot.setEnd(dot.nextox
, dot.nextoy); }); }else { this.state = “second”; this.changeState(); }
} }else if(this.state===”second”){ var completeNum = 0, allnum = 0;
dots.forEach(function(dot){ if(dot.visible) dot.loop(time);
if(dot.globleDown){ allnum++; if(Math.abs(dot.y-canvas.height)<2){
completeNum++ } } }); if(completeNum===allnum&&allnum!==0){ this.state =
“third”; part_2.animate(); endState(); } }else
if(this.state===”third”){ cube.update(); drawLogo(canvas , ctx); } }
return new animate(); })(window)

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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
var part_1 = (function(w){
    var dots = [],DOT_SIZE = 2,cube=null;
 
    var Dot = function(x,y,vx,vy,tox,toy,color){
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.nextox = tox;
        this.nextoy = toy;
        this.color = color;
        this.visible = true;
        this.globleDown = false;
        this.setEnd(tox , toy);
    }
 
    Dot.prototype = {
        paint:function(){
            ctx.fillStyle=this.color;
            ctx.fillRect(this.x-DOT_SIZE/2 , this.y-DOT_SIZE/2 , DOT_SIZE , DOT_SIZE);
        },
 
        setEnd:function(tox , toy){
            this.tox = tox;
            this.toy = toy;
            var yc = this.toy – this.y;
            var xc = this.tox – this.x;
            // this.initjl = Math.sqrt(xc*xc+yc*yc);
        },
 
        update:function(time){
            this.x += this.vx*time;
            this.y += this.vy*time;
 
            if(!this.globleDown&&this.y>0){
                var yc = this.toy – this.y;
                var xc = this.tox – this.x;
 
                this.jl = Math.sqrt(xc*xc+yc*yc);
 
                var za = 20;
 
                var ax = za*(xc/this.jl),
                    ay = za*(yc/this.jl),
                    vx = (this.vx+ax*time)*0.97,
                    vy = (this.vy+ay*time)*0.97;
 
                this.vx = vx;
                this.vy = vy;
 
                // if(Math.abs(this.vx)<1&&Math.abs(this.vy)<1){
                //     this.y = this.toy
                //     this.x = this.tox
                // }
            }else {
                var gravity = 9.8;
                var vy = this.vy+gravity*time;
 
                if(this.y>canvas.height){
                    vy = -vy*0.7;
                }
 
                this.vy = vy;
            }
        },
 
        loop:function(time){
            this.update(time);
            this.paint();
        }
    }
 
    var animate = function(){
        this.state = "before"
    }
 
    var ap = animate.prototype;
 
    ap.init = function(){
        this.osCanvas = document.createElement("canvas");
        var osCtx = this.osCanvas.getContext("2d");
 
        this.osCanvas.width = 1000;
        this.osCanvas.height = 150;
 
        osCtx.textAlign = "center";
        osCtx.textBaseline = "middle";
        osCtx.font="70px 微软雅黑,黑体 bold";
        osCtx.fillStyle = "#1D181F"
        osCtx.fillText("WelCome" , this.osCanvas.width/2 , this.osCanvas.height/2-40);
        osCtx.fillText("To wAxes’ HOME" , this.osCanvas.width/2 , this.osCanvas.height/2+40);
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        dots = [];
 
        for(var x=0;x<bigImageData.width;x+=2){
            for(var y=0;y<bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]>128){
                    var dot = new Dot(
                        Math.random()>0.5?Math.random()*20+10:Math.random()*20+canvas.width-40,
                        -Math.random()*canvas.height*2,
                        0,
                        0,
                        x+(canvas.width/2-this.osCanvas.width/2),
                        y+(canvas.height/2-this.osCanvas.height/2),
                        "rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]+","+bigImageData.data[i+2]+",1)"
                    );
                    dot.setEnd(canvas.width/2,canvas.height/2)
                    dots.push(dot);
                }
            }
        }
        console.log(dots.length)
    }
 
    ap.changeState = function(){
        var osCtx = this.osCanvas.getContext("2d");
        osCtx.clearRect(0,0,this.osCanvas.width,this.osCanvas.height);
        this.osCanvas.width = 460;
        this.osCanvas.height = 100;
 
        osCtx.fillStyle="#5C5656"
        osCtx.fillRect(20,20,60,60)
 
        drawLogo(this.osCanvas , osCtx);
 
        var bigImageData = osCtx.getImageData(0,0,this.osCanvas.width,this.osCanvas.height);
 
        var index=0;
        dots.sort(function(a , b){
            return Math.random()-Math.random();
        })
        for(var x=0;x<bigImageData.width;x+=2){
            for(var y=0;y<bigImageData.height;y+=2){
                var i = (y*bigImageData.width + x)*4;
                if(bigImageData.data[i+3]>128){
                        var d = dots[index];
                        if(d){
                            d.setEnd(x+(canvas.width/2-300) , y+50)
                            d.color = "rgba("+bigImageData.data[i]+","+bigImageData.data[i+1]+","+bigImageData.data[i+2]+",1)";
                            index++
                        }
                }
            }
        }
 
        setTimeout(function(){
            var endindex = index;
            for(var i=0;i<dots.length-endindex;i++){
                if(dots[index]){
                    var d = dots[index];
 
                    d.globleDown = true;
                    d.vx = Math.random()*100-50;
                }
                index++;
            }
        } , 2000)
    }
 
    function endState(){
        canvas.width = 600;
        canvas.height = 100;
        canvas.style.display="block";
        canvas.style.top = "50px";
        canvas.style.left = (window.innerWidth-canvas.width)/2+"px";
        cube = new Cube(50);
        cube._initVector(50,50);
    }
 
    function drawLogo(canvas , ctx){
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.font="65px 微软雅黑,黑体 bold"
        ctx.fillStyle="#E06D2F"
        ctx.fillText("DEMO" , 300 , canvas.height/2)
 
        ctx.font="40px 微软雅黑,黑体 bold"
        ctx.fillStyle="#405159"
        ctx.fillText("吖猩的" , 160 , canvas.height/2)
        ctx.fillText("小窝" , 420 , canvas.height/2)
    }
 
    var num = 0;
    ap.update = function(time){
        time = time/100;
        if(this.state==="first"||this.state==="before"){
            var completeNum = 0;
            dots.forEach(function(dot){
                if(dot.visible) dot.loop(time);
                if(dot.jl<5){
                    completeNum++
                }
            });
            if(completeNum>=5*dots.length/6){
 
                if(this.state==="before"){
                    this.state = "first";
                    dots.forEach(function(dot){
                        dot.setEnd(dot.nextox , dot.nextoy);
                    });
                }else {
                    this.state = "second";
                    this.changeState();
                }
            }
        }else if(this.state==="second"){
            var completeNum = 0,
                allnum = 0;
            dots.forEach(function(dot){
                if(dot.visible) dot.loop(time);
                if(dot.globleDown){
                    allnum++;
                    if(Math.abs(dot.y-canvas.height)<2){
                        completeNum++
                    }
                }
            });
 
            if(completeNum===allnum&&allnum!==0){
                this.state = "third";
                part_2.animate();
                endState();
            }
        }else if(this.state==="third"){
            cube.update();
            drawLogo(canvas , ctx);
        }
    }
 
    return new animate();
})(window)

赞 收藏 1
评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图