这是一个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();
}
}

最新文章

  1. {二逼小青年的记事簿}为什么treelist不会显示子节点的文字?
  2. sqlserver下调试sql语句
  3. Jmeter beanshell 生成手机号加密签名
  4. Windows PE3.0制作方法(从Win7中提取制作)
  5. 利用预渲染加速iOS设备的图像显示
  6. oracle的常见问题与解决
  7. CRM需要注意的一些事,修改字段类型
  8. Android ImageView(scaleType属性)图片按比例缩放
  9. Swift - 选择框(UIPickerView)的用法
  10. IceMx.Mvc 我的js MVC 框架 二、视图的数据绑定
  11. 关于Android SDK Manager更新速度慢的解决方法
  12. 树莓派安装tensorflow1.11
  13. ASM ClassReader failed to parse class file解决方法
  14. 【二次开发】shopxo商城
  15. Mac上安装pipenv时报错
  16. Dockerfile指令学习 (转)
  17. 为什么要在linux命令前加上 ./
  18. ubuntu遇到的问题
  19. 个人总结-9-session的使用,十天免登陆
  20. 自定义对象存入Redis

热门文章

  1. 六、yarn运行模式
  2. mac obs直播软件 无法输出音频解决办法
  3. springboot之内嵌tomcat修改端口号
  4. jquery怎么取得有好几个并且name是相同的值
  5. BZOJ3600:没有人的算术
  6. 多项式乘法,FFT与NTT
  7. 51Nod 算法马拉松23 开黑记
  8. 【js编程艺术】 之有用的函数
  9. Java 开源博客 Solo 1.6.0 发布 - 新后台
  10. 我所了解的关于JavaScript定义类和对象的几种方式