首页 专题 H5案例 前端导航 UI框架

简单的粒子动画

作者:TG 日期: 2016-08-19 字数: 6278 阅读: 3347
在这篇文章中,我将分享我的个人介绍(http://laixiazheteng.cn/about)里的粒子动画是如何实现的。
这里是第二种动画,不过调用只是改变一个参数而已:

var particle = new Particle('#particles', {});

而在我的个人介绍中的粒子动画:

var particle = new Particle('#particles', {   

  effect: 'line'   

});

全部代码:

(function() { window.Particle = function(container, params) { params = params || {}; var options = { point: 300, minDis: 100, mouseDis: 200, effect: 'zoom' }; var originParams = {}; for(var param in params) { if(typeof params[param] === 'object') { originParams[param] = {}; for(var defPa in params[param]) { originParams[param][defPa] = params[param][defPa]; }; } else { originParams[param] = params[param]; }; }; for(var opt in options) { if(typeof params[opt] === 'object') { for(var depOpt in options[opt]) { if(typeof params[opt][depOpt] === 'undefined') { params[opt][depOpt] = options[opt][depOpt]; }; }; } else if(typeof params[opt] === 'undefined') { params[opt] = options[opt]; }; }; var p = this; p.originParams = originParams; p.params = params; p.innerWidth = window.innerWidth; p.innerHeight = window.innerHeight; p.points = []; p.pageXY = {pageX:p.innerWidth/2,pageY:p.innerHeight/2}; if(container[0] === '#') { p.container = container.split('#')[1]; }; p.canvas = document.getElementById(p.container); p.ctx = p.canvas.getContext('2d'); p.init = function() { p.canvas.width = p.innerWidth; p.canvas.height = p.innerHeight; p.drawBackground(); p.addOverlap(); p.initDrawPoint(); p.animation(); p.mouseEvent(); p.windowResize(); }; p.addOverlap=function(){ p.overlap=document.createElement('div'); p.overlap.style.width=p.innerWidth+'px'; p.overlap.style.height=p.innerHeight+'px'; p.overlap.style.position='absolute'; p.overlap.style.top='0px'; p.overlap.style.left='0px'; p.overlap.style.zIndex='100'; if(p.canvas.nextElementSibling){ p.canvas.parentNode.insertBefore(p.overlap,p.canvas.nextElementSibling); }else{ p.canvas.parentNode.appendChild(p.overlap); }; }; //背景绘制 p.color = function() { function random() { return Math.round(Math.random() * 255); }; this.r = random(); this.g = random(); this.b = random(); this.a = random(1, 0.8); this.rgba = 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + this.a + ')'; return this; }; p.random = function(max, min) { var min = arguments[1] || 0; return Math.floor(Math.random() * (max - min + 1) + min); }; p.drawBackground = function() { if(!p.canvas) return; p.ctx.fillStyle = '#000'; p.ctx.fillRect(0, 0, p.innerWidth, p.innerHeight); }; p.point = function() { this.color = new p.color(); this.x = Math.random() * p.innerWidth; this.y = Math.random() * p.innerHeight; this.xv = p.random(10, -10) / 40; this.yv = p.random(10, -10) / 40; this.r = p.random(3, 1); this.scale = 1; }; p.initDrawPoint = function() { for(var i = 0; i < p.params.point; i++) { var point = new p.point(); p.points.push(point); p.ctx.beginPath(); p.ctx.fillStyle = point.color.rgba; p.ctx.arc(point.x, point.y, point.r * point.scale, 0, Math.PI * 2, true); p.ctx.fill(); }; p.ctx.closePath(); }; p.connect = function() { function lineColor(p1, p2) { var linear = p.ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y); linear.addColorStop(0, p1.color.rgba); linear.addColorStop(1, p2.color.rgba); return linear; }; for(var i = 0; i < p.params.point; i++) { for(var j = 0; j < p.params.point; j++) { var p1 = p.points[i]; var p2 = p.points[j]; if(Math.abs(p2.x - p1.x) < p.params.minDis && Math.abs(p2.y - p1.y) < p.params.minDis) { p.ctx.beginPath(); p.ctx.lineWidth = 0.2; p.ctx.strokeStyle = lineColor(p1, p2); p.ctx.moveTo(p1.x, p1.y); p.ctx.lineTo(p2.x, p2.y); p.ctx.stroke(); p.ctx.closePath(); }; }; }; }; p.lineto = function() { function isInView(point) { return Math.abs(point.x - p.pageXY.pageX) < p.params.mouseDis && Math.abs(point.y - p.pageXY.pageY) < p.params.mouseDis; }; (function line() { function lineColor(p1, p2) { var linear = p.ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y); linear.addColorStop(0, p1.color.rgba); linear.addColorStop(1, p2.color.rgba); return linear; }; for(var i = 0; i < p.params.point; i++) { for(var j = 0; j < p.params.point; j++) { if(i != j) { var p1 = p.points[i]; var p2 = p.points[j]; if(isInView(p1) && isInView(p2)) { if(Math.abs(p2.x - p1.x) < p.params.minDis && Math.abs(p2.y - p1.y) < p.params.minDis) { p.ctx.beginPath(); p.ctx.lineWidth = 0.2; p.ctx.strokeStyle = lineColor(p1, p2); p.ctx.moveTo(p1.x, p1.y); p.ctx.lineTo(p2.x, p2.y); p.ctx.stroke(); p.ctx.closePath(); }; }; }; }; }; })(); }; p.animation = function() { p.ctx.clearRect(0, 0, p.innerWidth, p.innerHeight); p.drawBackground(); for(var i = 0; i < p.params.point; i++) { var point = p.points[i]; if(point.x < 0 || point.x > p.innerWidth) { point.xv = -point.xv; }; if(point.y < 0 || point.y > p.innerHeight) { point.yv = -point.yv; }; p.ctx.beginPath(); p.ctx.fillStyle = point.color.rgba; point.x += point.xv; point.y += point.yv; p.ctx.arc(point.x, point.y, point.r * point.scale, 0, Math.PI * 2, true); p.ctx.fill(); }; if(p.params.effect == 'zoom') { p.connect(); } else if(p.params.effect == 'line') { p.lineto(); }; requestAnimationFrame(p.animation); }; p.mouseEvent = function() { p.overlap.addEventListener('mousemove', function(e) { var e = e || window.event; var pageX = (e.clientX + document.body.scrollLeft || e.pageX) - this.offsetLeft; var pageY = (e.clientY + document.body.scrollTop || e.pageY) - this.offsetTop; if(p.params.effect == 'zoom'){ for(var t = 0; t < p.params.point; t++) { var point = p.points[t]; if(Math.abs(point.x - p.pageXY.pageX) < p.params.minDis && Math.abs(point.y - p.pageXY.pageY) < p.params.minDis) { point.scale = 5; } else { point.scale = 1; }; }; }; p.pageXY.pageX = pageX; p.pageXY.pageY = pageY; }); p.overlap.addEventListener('mouseout', function(e) { if(p.params.effect == 'zoom'){ for(var i = 0; i < p.params.point; i++) { var point = p.points[i]; if(point.scale != 1) { point.scale = 1; }; }; }else{ p.pageXY.pageX=p.innerWidth/2; p.pageXY.pageY=p.innerHeight/2; }; }); }; p.windowResize = function() { window.addEventListener('resize', p.init); }; p.init(); return p; }; //兼容requestAnimFrame window.requestAnimationFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; })(); })();

后续还会加上更多动画,敬请期待!

如有不好之处,也请指正...


目录