【JavaScript】explode动画

这是一个js实现的粒子聚合文字或图片的动画特效

部分程序如下

        n.container = n.container[0] || n.container;   /*有且仅有一个container*/

        var width = n.params.width;
        var height = n.params.height;
        var wWidth = document.body.clientWidth;
        var wHeight = document.body.clientHeight;

        n.container.width = width;
        n.container.height = height;
        var ctx = n.container.getContext(‘2d‘);
        var c = document.createElement(‘canvas‘);
        var ct = c.getContext(‘2d‘);   /*用于绘制图片或文字*/
        var items = [];
        var picture = null;
        var requestId = null;
        var total = 0;
        var getRandom = function(max, min) {
            min = arguments[1] || 0;
            return Math.floor(Math.random() * (max - min + 1) + min); /*取min和max之间的随机数*/
        };

        function cutSlice() {/*cutSlice()方法,实现粒子动画,让其往最终位置运动*/
            ctx.clearRect(0, 0, n.container.width, n.container.height);
            for(var i = 0; i < c.width * c.height; i++) {
                var item = items[i];
                var targetX = item.targetX;
                var targetY = item.targetY;
                var currentX = item.currentX;
                var currentY = item.currentY;
                var ax = false;
                var ay = false;
                if(!item.isLock) {
                    if(Math.abs(targetX - currentX) <= .5) {
                        item.currentX = targetX;
                        ax = true;
                    } else {
                        item.currentX += (targetX - currentX) * item.ax;
                    };
                    if(Math.abs(targetY - currentY) <= .5) {
                        item.currentY = targetY;
                        ay = true;
                    } else {
                        item.currentY += (targetY - currentY) * item.ay;
                    };
                    if(ax && ay) {/*只有ax和ay同时到达终点时,total才会减1*/
                        total--;
                        item.isLock = true;
                    }
                };
                var ix = item.currentX;
                var iy = item.currentY;
                ctx.putImageData(item.data, ix, iy); /*putImageData() 方法将图像数据(从指定的 ImageData 对象)放回画布上。*/
            };
            if(total > 0) {
                requestId = requestAnimationFrame(cutSlice); /*不用设置间隔,反复调用*/
            } else {
                cancelAnimationFrame(requestId);

            };
        }

        function Item(data, targetX, targetY, currentX, currentY) {/*创建一个Item构造函数,用来放置每一个粒子*/
            this.data = data;
            this.targetX = targetX; /*聚合的最终位置*/
            this.targetY = targetY;
            this.currentX = currentX;/*当前位置*/
            this.currentY = currentY;
            this.ax = .13 - Math.random() * .06;  /*ax和ay分别表示运动速度*/
            this.ay = .16 - Math.random() * .08;
        }

        function drawCanvas() {
            if(n.params.type == 2) {  /*针对图片*/
                picture = new Image();
                picture.crossOrigin = "";
                picture.onload = function() {
                    var pw = picture.width;
                    var ph = picture.height;
                    c.width = pw;   /*设置canvas的宽度*/
                    c.height = ph;
                    ct.drawImage(picture, 0, 0, pw, ph, 0, 0, pw, ph);  /*把图像中的某个区域绘制到上下文中,源图像(起点和宽高),上下文中的起点和宽高*/
                    draw(pw, ph);
                };
                picture.src = n.params.img;
            } else {  /*针对文字*/
                var word = n.params.text;
                ct.font = ‘60px Arial‘;   /*这里指定用于测文本宽度*/
                var w = ct.measureText(word).width;   /*测文本宽度*/
                var h = 100;
                c.width = w;
                c.height = h;
                ct.fillStyle = ‘deepskyblue‘;
                ct.font = ‘60px Arial‘;   /*这里指定用于绘制文本,应与之前设置保持一致*/
//                ct.textAlign = ‘center‘;
                ct.textBaseline = ‘middle‘;
                ct.fillText(word, 0, 50);  /*绘制文本,这里为什么没有直接绘制上去?而要调用draw???*/
                draw(w, h);
            }

            function draw(pw, ph) {/*draw 方法用来分解粒子,先分成cols 列和rows 行,每一个粒子高度都为1,然后用
getImageData() 来获取ImageData对象,然后创建新的Item实例,然后添加到items数组中。*/
                var w = 1;
                var h = 1;
                var cols = Math.floor(pw / w);/*图片或文字的宽度高度*/
                var rows = Math.floor(ph / h);
                for(var i = 0; i < c.width * c.height; i++) {
                    var x = Math.floor(i % cols); /*通过xy找到每一行的所有元素(0,0)(1,0)...(0,1)(1,1)(2,1)*/
                    var y = Math.floor(i / cols);
                    var data = ct.getImageData(x * w, y * h, w, h);/* 文字也能获取??拷贝!取得原始图像数据,要取得取数据的画面区域的xy坐标以及该区域的像素宽度和高度,这里每次取1*1像素*/
                    var vx = getRandom(300, -300);
                    var vy = getRandom(500, -500); /*扩大范围,使图片周围也有粒子*/
                    var item = new Item(data, x, y, x + vx, y + vy);
                    items.push(item);
                };
                total = items.length;
                cutSlice();
            }
        }
时间: 2024-10-19 15:12:28

【JavaScript】explode动画的相关文章

&quot;Javascript高性能动画与页面渲染&quot;笔记

前言:好久没翻阅我的gmail邮箱了,午休时就打开看了一下,看到InfoQ推荐的一篇名为“Javascript高性能动画与页面渲染”文章,粗略的看了一下,很赞!讲的很详细,对好些细节讲的都很好,很通俗易懂.so……笔记诞生 1.fps -frame per second 帧 页面是每一帧变化都是系统绘制出来的(GPU或者CPU).但这种绘制又和PC游戏的绘制不同,它的最高绘制频率受限于显示器的刷新频率(而非显卡),所以大多数情况下最高的绘制频率只能是每秒60帧(frame per second,

Javascript高性能动画与页面渲染

转自:http://www.infoq.com/cn/articles/javascript-high-performance-animation-and-page-rendering No setTimeout, No setInterval 如果你不得不使用setTimeout或者setInterval来实现动画,那么原因只能是你需要精确的控制动画.但我认为至少在现在这个时间点,高级浏览器.甚至手机浏览器的普及程度足够让你有理由有条件在实现动画时使用更高效的方式. 什么是高效 页面是每一帧变

JavaScript实现动画插件

在这之前,大家应该了解了缓动函数(Easing Functions)的概念: 动画的每一帧需要计算一次元素样式,如果样式改变则需要重绘屏幕.细一点讲,当我们每调用一次计时器函数,需要通过向缓动函数传入一些动画上下文变量,从而获取到元素的某个样式在当前帧合理的值. 我所了解的缓动函数实现方式有两种,一种是tbcd方式(Robert Penner's Easing Functons) function(t,b,c,d){ return c*t/d + b; } t: timestamp 以毫秒(ms

JavaScript之动画2

在JavaScript动画中,我们调用setInterval函数(setInterval动作的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象),值得注意的是:setInterval它设置的时间间隔小于动画帧速(如每秒10帧,相当于100毫秒). 举个栗子: function show1(){ alert("每隔1秒显示一次"); } function show2(str){ alert(str); } setInterval(show1,1000); setInterval(

[转]Javascript高性能动画与页面渲染

No setTimeout, No setInterval 作者 李光毅 发布于 2014年4月30日 如果你不得不使用setTimeout或者setInterval来实现动画,那么原因只能是你需要精确的控制动画.但我认为至少在现在这个时间点,高级浏览器.甚至手机浏览器的普及程度足够让你有理由有条件在实现动画时使用更高效的方式. 什么是高效 页面是每一帧变化都是系统绘制出来的(GPU或者CPU).但这种绘制又和PC游戏的绘制不同,它的最高绘制频率受限于显示器的刷新频率(而非显卡),所以大多数情况

&lt;JavaScript&gt;自定义动画

animate() 方法执行 CSS 属性集的自定义动画. 该方法通过CSS样式将元素从一个状态改变为另一个状态.CSS属性值是逐渐改变的,这样就可以创建动画效果. 只有数字值可创建动画(比如 "margin:30px").字符串值无法创建动画(比如 "background-color:red"). 示例代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Cont

javascript图形动画设计--画简单正弦波

<!doctype html> <html> <head> <meta charset="utf-8"> <title>Rotate to Mouse</title> <link rel="stylesheet" href="../include/style.css"> <style type="text/css"> .dot{ p

javascript图形动画设计--以简单正弦波轨迹移动

<!doctype html> <html> <head> <meta charset="utf-8"> <title>Wave 1</title> <link rel="stylesheet" href="../include/style.css"> </head> <body> <header> Example from &

JavaScript封装动画函数

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } div { margin-top: 10px; width: 100px; height: 50px; background-color: purple;