5

无意间看到了我仍旧在这里《每天一点canvas动画》的系列文章(表示感谢),"粒子文字" 这节感觉很不错,研究了一下,因为原作者加入了几个与用户交互的属性可动态改变粒子文字动画的样式,且代码也抽离的比较彻底比较散,对于学习者我感觉理解山学习起来挺费劲。所以呢这里我把核心的代码整理了出来希望对这个感兴趣同学可以看看,只是把核心的代码抽离了出来放在一个文件中,这样方便理解和查看;然后再关键部分加入了一些注释我自己的理解,有不对或不妥的地方的大家一定指出。先看效果图(图也是从[我仍旧在这里]大神那拷贝来的,原谅我)。图中左侧的滑动tab的功能我这里给去掉了以方便理解粒子动画的核心:

3828864218-575e3934c9205_articlex

源码以下:

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

idgq
575 声望13 粉丝