无心间看到了我仍旧在这里的《天天一点canvas动画》的系列文章(表示感谢),"粒子文字" 这节感受很不错,研究了一下,由于原做者加入了几个与用户交互的属性可动态改变粒子文字动画的样式,且代码也抽离的比较完全比较散,对于学习者我感受理解山学习起来挺费劲。因此呢这里我把核心的代码整理了出来但愿对这个感兴趣同窗能够看看,只是把核心的代码抽离了出来放在一个文件中,这样方便理解和查看;而后再关键部分加入了一些注释我本身的理解,有不对或不妥的地方的你们必定指出。先看效果图(图也是从[我仍旧在这里]大神那拷贝来的,原谅我)。图中左侧的滑动tab的功能我这里给去掉了以方便理解粒子动画的核心:javascript
源码如下:html
<!DOCTYPE html> <html lang="len"> <head> <meta charset="utf-8"/> <title>文字粒子</title> </head> <body> <canvas id="canvas" width="1200" height="500" style="background: #ccc"></canvas> <script type="text/javascript"> window.onload = function(){ var canvas = document.getElementById("canvas") var context = canvas.getContext("2d"); var W = canvas.width = window.innerWidth, H = canvas.height = window.innerHeight, gridX = 7, gridY = 7, colors = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722'], durVal = 0.1; // 粒子 function Particle(x, y){ this.x = x; this.y = y; this.color = colors[Math.floor(Math.random() * colors.length)]; this.futurRadius = randomInt(1.1, 5.1); this.radius = 1.1; this.dying = false; this.base = [x, y]; this.drawParticle = function(){ // 当前粒子变小到必定程度以后,每次将它的半径+0.1,使其慢慢变大 if(this.radius < this.futurRadius && this.dying === false){ this.radius += durVal; }else{//粒子已经到达最大状态 this.dying = true; //表示粒子还处于show状态 } //每次-0.1 if(this.dying){ this.radius -= durVal; } context.save(); context.fillStyle = this.color; context.beginPath(); context.arc(this.x, this.y, this.radius, Math.PI * 2, false); context.closePath(); context.fill(); context.restore(); //将消失的粒子重置最初的状态 if (this.y < 0 || this.radius < 1) { this.x = this.base[0]; this.y = this.base[1]; this.dying = false; } } } // 文本对像 function Shape(text, size, x, y){ this.text = text; this.size = size; this.x = x; this.y = y; this.placement = []; //文字的数据的位置信息 } Shape.prototype.getValue = function(){ context.textAlign = "center"; context.font = this.size+"px arial"; context.fillText(this.text, this.x, this.y); // 复制画布上指定矩形的像素数据 var idata = context.getImageData(0, 0, W, H); // data 属性返回一个对象,是一个8位无符号整数的数组Uint8ClampedArray var buffer = new Uint32Array(idata.data.buffer); // 抽样获取图像数据使用particle对象记录下当前像素下数据的位置信息 for(var i = 0; i < H; i += gridY){ for(var j = 0; j < W; j += gridX){ if(buffer[i * W + j]){ var particle = new Particle(j, i); this.placement.push(particle); } } } } // 建立模型数据对象 var word = new Shape("`(*∩_∩*)′", 200, W/2, H/2); // 调用getValue方法,获取数据位置信息 word.getValue(); (function drawFrame(){ window.requestAnimationFrame(drawFrame); context.clearRect(0, 0, W, H); for (var i = 0; i < word.placement.length; i++){ //调用particle对像的drawParticle方法,开始画布上画 word.placement[i].drawParticle(); } }()) function randomInt(min, max) { return min + Math.random() * (max - min + 1); } } </script> </body> </html>