canvas,让脆片飞一会儿
2015-10-18 18:20
288 查看
http://www.hui12.com/nbin/csdn/canvasBg/demo.html https://nbin2008.github.io/demo/canvasBg/index.html
代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="CanvasBg.js"></script> </head> <body> <canvas id="mycanvas" width="400" height="400" style="border: 1px solid #000;"></canvas> <canvas id="mycanvas2" width="400" height="400" style="border: 1px solid #000;"></canvas> <script type="text/javascript"> var mycanvas = document.getElementById("mycanvas"); var mycanvas2 = document.getElementById("mycanvas2"); var bg = "bg.png" var c = new CanvasBg({ mycanvas: mycanvas, bg: bg, bgNum: 8 }); var c2 = new CanvasBg({ mycanvas: mycanvas2 }) </script> </body> </html>
<pre name="code" class="javascript">(function(window){ function CanvasBg(e){ this.init(e); }; var proto = { init: function(e){ this.before(e); this.ddraw(); }, before: function(e){ var This = this; this.mycanvas = e.mycanvas; this.width = this.mycanvas.width; this.height = this.mycanvas.height; this.bgNum = e.bgNum || 0; this.cache = []; var mycanvas = this.mycanvas; var myc = mycanvas.getContext('2d'); var bg = e.bg; if( bg ){ var img = new Image(); img.src = bg; this.bg = img; img.onload = function(){ This.create(); }; }else{ this.bg = false; this.create(); }; }, create: function(){ var This = this, width = this.width, height = this.height, distance = Math.sqrt((width/2)*(width/2)+(height/2)*(height/2)), cache = this.cache; this.distance = Math.round(distance); setInterval(function(){ var length = This.cache.length; if( length < 300 ){ fnCreate(); }; },100); function fnCreate(){ var angle = getAngle(), speed = getSpeed(), sScale = scale12(), bgIndex = getBg(This.bgNum); cache.push({ angle: angle, distanceNow: Math.round(distance), speed: speed, sScale: sScale, bgIndex: bgIndex }); }; function getBg(n){ return Math.round(Math.random()*(n-1)); }; function getSpeed(){ return Math.round(Math.random()*8+1)/1; }; function scale12(){ return (Math.random()+1); // return 1; } function getAngle(){ var n = Math.round(Math.random()*360); /*var a = Math.atan(height/width)*180/Math.PI; while( (n>=a && n<=180-a) || (n>=a+180 && n<360-a) ){ n = Math.round(Math.random()*360); max = Math.atan(height/width); };*/ return n; }; }, ddraw: function(){ var This = this, bg = this.bg, width = this.width, height = this.height, mycanvas = this.mycanvas, myc = mycanvas.getContext('2d'), cache = this.cache; setInterval(draw, 100); function draw(){ myc.clearRect(0,0,width,height); myc.globalCompositeOperation = 'lighter'; var i = cache.length-1; var distance = This.distance; while(i>= 0){ var mycbg = createBg(i); var distanceNow = cache[i]["distanceNow"]; var angle = cache[i]["angle"]; myc.save(); myc.translate(width/2, height/2); myc.rotate(angle*Math.PI/180); myc.drawImage(mycbg,distanceNow,0); myc.restore(); i--; }; }; function createBg(i){ var bgCanvas = document.createElement('canvas'); bgCanvas.width = 100; bgCanvas.height = 100; smyc = bgCanvas.getContext('2d'), distance = This.distance, mScale = cache[i]["distanceNow"]/distance smyc.scale(cache[i]['sScale'],cache[i]['sScale']); smyc.scale(mScale,mScale); mScale *= 1.2; mScale = mScale<=0.2?0.2:mScale; smyc.globalAlpha = mScale; if( bg ){ smyc.drawImage(bg, 50*cache[i]['bgIndex'], 0, 50, 50, 0, 0, 50, 50 ); }else{ if( cache[i]['crisp'] ){ cache[i]['crisp'](smyc); }else{ cache[i]['crisp'] = createCrisp(smyc); }; }; return bgCanvas; }; function createCrisp(smyc){ var tmpArr = [], i = 0, n = gShape(); smyc.beginPath() while( i<=n ){ tmpArr.push([gCoord(), gCoord()]) i++; }; tmpArr.push([gColor(),gColor(),gColor()]); function gShape(){ return Math.round(Math.random()*1+3); }; function gCoord(){ return Math.round(Math.random()*50); }; function gColor(){ return Math.round(Math.random()*255); }; var tmpFn = function(smyc){ for( var z=0,l=tmpArr.length; z<l; z++ ){ var tmp = tmpArr[z]; if( tmp.length == 2 ){ if(z==0){ smyc.beginPath(); smyc.moveTo(tmp[0], tmp[1]); }else{ smyc.lineTo(tmp[0], tmp[1]); }; if( z==l-2 ){ smyc.closePath(); } }else{ smyc.fillStyle = "rgb("+ tmp[0] +","+ tmp[1] +","+ tmp[2] +")"; smyc.fill(); } }; }; tmpFn(smyc); return tmpFn; }; setInterval(change,100); function change(){ var i=cache.length-1; while( i>=0 ){ cache[i]["distanceNow"] -= cache[i]['speed']; if( cache[i]['distanceNow']<=0 ){ cache.splice(i,1); }; i--; }; }; } }; CanvasBg.prototype = proto; window.CanvasBg = CanvasBg; })(window);
使用方法:
var c = new CanvasBg({mycanvas: mycanvas,bg: bg,bgNum: 8});
var c2 = new CanvasBg({mycanvas: mycanvas2})
new CanvasBg对象,接受一个json数据。
mycanvas:canvas元素
bg:使用自己的图片,可选参数
bgNum:自己图片上脆片的个数,和bg同时使用。
如果使用自己的图片,则图片有规范:以50*50像素,从左往右
效果逻辑部分:
before: function(e){ var This = this; this.mycanvas = e.mycanvas; this.width = this.mycanvas.width; this.height = this.mycanvas.height; this.bgNum = e.bgNum || 0; this.cache = []; var mycanvas = this.mycanvas; var myc = mycanvas.getContext('2d'); var bg = e.bg; if( bg ){ var img = new Image(); img.src = bg; this.bg = img; img.onload = function(){ This.create(); }; }else{ this.bg = false; this.create(); }; }这个方法是判断有没有图片参数,最后都是运行create()方法。cache为数组,放脆片数据用
create: function(){ var This = this, width = this.width, height = this.height, distance = Math.sqrt((width/2)*(width/2)+(height/2)*(height/2)), cache = this.cache; this.distance = Math.round(distance); setInterval(function(){ <pre name="code" class="javascript"><span style="white-space:pre"> </span>var length = This.cache.length; if( length < 300 ){ fnCreate(); };},100);function fnCreate(){var angle = getAngle(),<span style="white-space:pre"> </span>//脆片出现的角度speed = getSpeed(),<span style="white-space:pre"> </span>//脆皮运行的速度sScale = scale12(),<span style="white-space:pre"> </span>//图片开始位置时的大小,使用1-2之间的随机数缩放bgIndex
= getBg(This.bgNum);<span style="white-space:pre"> </span>//图片上面有多少个脆片,取随机位置cache.push({angle: angle,distanceNow: Math.round(distance),<span style="white-space:pre"> </span>//这个是脆片对应的位置,一直会变化,初始值与distance相等。speed: speed,sScale: sScale,bgIndex: bgIndex});};function
getBg(n){return Math.round(Math.random()*(n-1));};function getSpeed(){return Math.round(Math.random()*8+1)/1;};function scale12(){return (Math.random()+1);}function getAngle(){var n = Math.round(Math.random()*360);/*var a = Math.atan(height/width)*180/Math.PI;while(
(n>=a && n<=180-a) || (n>=a+180 && n<360-a) ){n = Math.round(Math.random()*360);max = Math.atan(height/width);};*/return n;};}
这个方法为cache数据构造。diatance:以canvas的中心为中点(width/2,height/2),中点到canvas原点(0,0)的距离,因为图片都是从外往里汇聚的。这个数值不做更改,为固定值。
getAngle():脆片出现的轨迹,默认是全屏,返回的是0-360的数字。修改这里的返回值,可以设置脆片出现的范围。以canvas的中心为中点,顺时针方向为对应角度的出现范围。
ddraw: function(){ var This = this, bg = this.bg, width = this.width, height = this.height, mycanvas = this.mycanvas, myc = mycanvas.getContext('2d'), cache = this.cache; setInterval(draw, 100); function draw(){ myc.clearRect(0,0,width,height); myc.globalCompositeOperation = 'lighter'; var i = cache.length-1; var distance = This.distance; while(i>= 0){ var mycbg = createBg(i); var distanceNow = cache[i]["distanceNow"];<span style="white-space:pre"> </span>//与diatance的值做比列,这个很重要 var angle = cache[i]["angle"];<span style="white-space:pre"> </span>//脆片的接口 myc.save(); myc.translate(width/2, height/2);<span style="white-space:pre"> </span>//位移到canvas中点,距离 myc.rotate(angle*Math.PI/180);<span style="white-space:pre"> </span>//位移到canvas中点,角度 myc.drawImage(mycbg,distanceNow,0);<span style="white-space:pre"> </span>//渲染 myc.restore(); i--; }; }; function createBg(i){ var bgCanvas = document.createElement('canvas'); bgCanvas.width = 100; bgCanvas.height = 100; smyc = bgCanvas.getContext('2d'), distance = This.distance, mScale = cache[i]["distanceNow"]/distance smyc.scale(cache[i]['sScale'],cache[i]['sScale']);<span style="white-space:pre"> </span>//默认构建脆片的大小,1-2之间 smyc.scale(mScale,mScale);<span style="white-space:pre"> </span>//脆片运动就是根据这个比列,很重要 mScale *= 1.2;<span style="white-space:pre"> </span>//乘以1.2,脆片在往中点汇聚的过程中,有时候还比较远就消失了,所以做了这个方法 mScale = mScale<=0.2?0.2:mScale; smyc.globalAlpha = mScale; if( bg ){<span style="white-space:pre"> </span>//以雪碧图为脆片 smyc.drawImage(bg, 50*cache[i]['bgIndex'], 0, 50, 50, 0, 0, 50, 50 ); }else{<span style="white-space:pre"> </span>//随机脆片 if( cache[i]['crisp'] ){ cache[i]['crisp'](smyc); }else{ cache[i]['crisp'] = createCrisp(smyc); }; }; return bgCanvas; }; function createCrisp(smyc){ var tmpArr = [], i = 0, n = gShape(); smyc.beginPath() while( i<=n ){ tmpArr.push([gCoord(), gCoord()]) i++; }; tmpArr.push([gColor(),gColor(),gColor()]); function gShape(){ return Math.round(Math.random()*1+3); }; function gCoord(){ return Math.round(Math.random()*50); }; function gColor(){ return Math.round(Math.random()*255); }; var tmpFn = function(smyc){ for( var z=0,l=tmpArr.length; z<l; z++ ){ var tmp = tmpArr[z]; if( tmp.length == 2 ){ if(z==0){ smyc.beginPath(); smyc.moveTo(tmp[0], tmp[1]); }else{ smyc.lineTo(tmp[0], tmp[1]); }; if( z==l-2 ){ smyc.closePath(); } }else{ smyc.fillStyle = "rgb("+ tmp[0] +","+ tmp[1] +","+ tmp[2] +")"; smyc.fill(); } }; }; tmpFn(smyc); return tmpFn; }; setInterval(change,100); function change(){ var i=cache.length-1; while( i>=0 ){ cache[i]["distanceNow"] -= cache[i]['speed']; if( cache[i]['distanceNow']<=0 ){ cache.splice(i,1); }; i--; }; }; }绘制canvas效果的主要部分。
draw()方法:实时渲染,一直根据cache中的数据做渲染
createBg():创建bgcanvas给draw方法使用
createCrisp():如果没有传入图片,则为createBg实时创建bg
主要使用的canvasAPI:
translate() 脆片的位置/距离
rotate() 脆片的位置/角度
scale() 脆片的大小和透明度
drawImage() 背景构建
function change(){ var i=cache.length-1; while( i>=0 ){ cache[i]["distanceNow"] -= cache[i]['speed']; if( cache[i]['distanceNow']<=0 ){ cache.splice(i,1); }; i--; }; };因为脆片是不停的在运动的,所以肯定对应的数据在变化,这个方法是更改distanceNow的值,同时设定临界点,满足临界点则从cache中删除这个数据。
=================追加修改======================
优化1:
setInterval(function(){ fnCreate(); },50); function fnCreate(){ var angle = getAngle(), speed = getSpeed(), sScale = scale12(), bgIndex = getBg(This.bgNum); for( var i=0, len=cache.length; i<len; i++){ if( cache[i]["isEnd"] ){ cache[i] = { angle: angle, distanceNow: Math.round(distance), speed: speed, sScale: sScale, bgIndex: bgIndex, isEnd: false, }; return; }; }; cache.push({ angle: angle, distanceNow: Math.round(distance), speed: speed, sScale: sScale, bgIndex: bgIndex, isEnd: false, }); };
function change(){ var i=cache.length-1; while( i>=0 ){ cache[i]["distanceNow"] -= cache[i]['speed']; if( cache[i]['distanceNow']<=0 ){ cache[i]["isEnd"] = true; }; i--; }; };
优化2:
function createBg(i){ var bgCanvas; if( bgCanvasJson[i] ){ bgCanvas = bgCanvasJson[i] }else{ var c = document.createElement('canvas'); c.width = 100; c.height = 100; bgCanvasJson[i] = c; bgCanvas = bgCanvasJson[i]; }; var smyc = bgCanvas.getContext('2d'); smyc.save(); smyc.clearRect(0,0,100,100); distance = This.distance, mScale = cache[i]["distanceNow"]/distance smyc.scale(cache[i]['sScale'],cache[i]['sScale']); smyc.scale(mScale,mScale); mScale *= 1.2; mScale = mScale<=0.2?0.2:mScale; smyc.globalAlpha = mScale; if( bg ){ smyc.drawImage(bg, 50*cache[i]['bgIndex'], 0, 50, 50, 0, 0, 50, 50 ); }else{ if( cache[i]['crisp'] ){ cache[i]['crisp'](smyc); }else{ cache[i]['crisp'] = createCrisp(smyc); }; }; smyc.restore(); return bgCanvas; };
相关文章推荐
- Extjs4.0 最新最全视频教程
- Javascript中toFixed方法的改进
- 5个常见可用性错误和解决方案
- Canvas 在高清屏下绘制图片变模糊的解决方法
- js可突破windows弹退效果代码
- JSP脚本漏洞面面观
- 使用BAT一句话命令实现快速合并JS、CSS
- js显示当前星期的起止日期的脚本
- 爆炸式的JS圆形浮动菜单特效代码
- js select常用操作控制代码
- 超级经典一套鼠标控制左右滚动图片带自动翻滚
- 从jsp发送动态图像
- 原生js结合html5制作小飞龙的简易跳球
- js 页面模块自由拖动实例
- js实现小鱼吐泡泡在页面游动特效
- js 提交和设置表单的值
- PHP VBS JS 函数 对照表
- PHP+JS实现大规模数据提交的方法
- 仿51JOB的地区选择效果(可选择多个地区)
- js身份证验证超强脚本