博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【JavaScript】explode动画
阅读量:7080 次
发布时间:2019-06-28

本文共 4968 字,大约阅读时间需要 16 分钟。

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

 

转载于:https://www.cnblogs.com/yujihang/p/7002993.html

你可能感兴趣的文章
使用iscroll4可能会遇到的问题(转:记录)
查看>>
js 的全局对象、函数等
查看>>
前端周刊第53期:React 社区的撕逼
查看>>
SVG之ViewBox
查看>>
linux下的进程(1)
查看>>
Laravel核心——服务容器的细节特性
查看>>
HTML5 原生拖放
查看>>
[转] MySQL死锁问题分析及解决方法实例详解
查看>>
React Native CodePush实践小结
查看>>
怎么才算是高级工程师?
查看>>
JavaScript学习笔记 - 基本概念
查看>>
Angular 2 Change Detection - 1
查看>>
ReactJS新闻 #19 React Conf 2017将于3/13开始
查看>>
CI-CodeIgniter中“超级对象”:$CI =& get_instance()
查看>>
设计模式之单例模式
查看>>
Scrapy学习(四) 爬取微博数据
查看>>
LinkedIn庄振运:从国家部委公务员到硅谷系统性能专家,创新是唯一主旋律
查看>>
Vue性能优化:如何实现延迟加载和代码拆分?
查看>>
小米大数据:借助Apache Kylin打造高效、易用的一站式OLAP解决方案
查看>>
2019年Java和JVM生态系统预测:OpenJDK将成为Java运行时市场领导者
查看>>