canvas,让脆片飞一会儿


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;
			};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值