循环展示图片(画中画效果)CANVAS2.0版

循环展示图片(画中画效果)CANVAS2.0版
之前设计的一版在测试当中有点问题,PC端测试是没有问题的,但在手机上访问时,切屏时就出现闪屏(本就出现的大图没有出现,是之前的小图突然变大,一闪而过,然后再显示正常的大图)问题,总结原因,应该还是在移动端加载慢的问题
这一版做了优化,第一屏时加载三张图片,把下一屏的图预加载出来,到下一屏的时候,只需再预加载下一屏的一张图即可,经过测试,的确不会出现闪屏的问题啦
另外,在结束时将操作按钮隐藏了,另加了一个可回调的方法,根据调用时参数确定是否需要回调

包含JS文件CanvasCycleShowImg.2.0.js

/*
JS不断向CANVAS中画入两张图片(画入的图片src、画入的图片宽高、画入的的图片位置 等变化) 版循环展示图片(画中画效果)
author 羽筠
2017-07-06
*/
function CanvasCycleShowImg(){
	//所使用图片的实际尺寸
	this.imgMsg = {w:640,h:1138};
	//所有图片的位置、宽高信息设置(根据图片 的实际尺寸 设置的),inX , inY , inW , inH 中的值表示上一张图在本张图中(本张图片最终状态时全部显示时)的信息
	this.imgList = [
					{
						imgsrc:'1.jpg',
						inX:'',
						inY:'',
						inW:'',
						inH:''
					},
					{
						imgsrc:'2.jpg',
						inX:470,
						inY:50,
						inW:118,
						inH:210
					},
					{
						imgsrc:'3.jpg',
						inX:86,
						inY:561,
						inW:195,
						inH:346
					},
					{
						imgsrc:'4.jpg',
						inX:266,
						inY:472,
						inW:118,
						inH:210
					},
				];
	//多少步完成起始至最终 状态的变化
	this.step  = 300;
	//定时器间隔时间(单位毫秒)
	this.timerTime = 10;
	
	//添加配置样式及标签元素
	//移动端加此样式设置 : html{ min-width:320px; max-width:640px; margin:0 auto;}\
	this.headStyle = '<style>\
						*{ margin:0px; padding:0px; box-sizing:border-box; -webkit-tap-highlight-color:rgba(0,0,0,0);}\n\
						html{ min-width:320px; max-width:640px; margin:0 auto;}\n\
						html , body{ display:block; width:100%; height:100%;}\n\
						#btn{ width:50px; height:50px; line-height:50px; text-align:center; color:#fff; border-radius:50%; background-color:#f00; cursor:pointer; position:absolute; left:50%; margin-left:-25px; bottom:20px;}\
					</style>';
	this.showImgEle = '<div id="showImg" style=" width:100%; height:100%; overflow:hidden; position:relative;">\
						<canvas id="showImgCanvas" style=" width:100%; position:absolute; left:0; top:0;" />\
					</div>';
	this.showImgBtn = '<div id="btn"></div>';
}

CanvasCycleShowImg.prototype.init = function (callback){
	//结束时是否有回调,根据参数确定
	var if_callback = false;
	if(arguments[0]){
		if_callback = true;
	}
	
	var headStyle = this.headStyle;
	$('head').append(headStyle);
	var showImgEle = this.showImgEle;
	$('body').prepend(showImgEle);
	var showImgBtn = this.showImgBtn;
	$('#showImg').after(showImgBtn);

	var imgMsg  = this.imgMsg;
	var imgList = this.imgList;
	//所有图片声明的数组下标起始
	var start = 0;
	//所有图片声明的数组下标结束
	var end   = imgList.length - 2;
	var step  = this.step;
	//第1步数
	var stepNum   = 1;
	var timerTime = this.timerTime;
	//页面交互时,用户始终只看见两张图,在下面的那一张图片大,在上面的那一张图片小 ,  以下方法设置两张图片的 起始、最终 显示状态的 位置、大小 信息
	function getPoint(start){
		/*
		start     ===> 第 1 张图(显示在上面的那一张图片)
		start + 1 ===> 第 2 张图(显示在下面的那一张图片)
		以下定义的 x , y , w , h  => 在以上数组(imgList)中有设置,为图片对应实际尺寸,表示第 1 张图在第 2 张图中显示的位置及宽高
		*/
		x = imgList[start + 1].inX;
		y = imgList[start + 1].inY;
		w = imgList[start + 1].inW;
		h = imgList[start + 1].inH;
		//第 2 张图的起始状态(放大)比例,也就是 第 1 张图 起始 与 最终 状态的比例 :图片实际宽 / 图片实际缩小后的宽
		var fdbl = imgMsg.w / w;
		//第 1 张图的最终状态(缩小)比例,也就是 第 1 张图 最终 与 起始 状态的比例 :图片实际缩小后的宽 / 图片实际宽
		var sxbl = w / imgMsg.w;
		
		/******第 1 张图的 最终 状态的定位信息与宽高设置******/
		var minToX = x;
		var minToY = y;
		var minToW = w;
		var minToH = h;
		/******第 2 张图的 起始 状态的定位信息与宽高设置******/
		var maxStartX = minToX  * fdbl * -1;
		var maxStartY = minToY  * fdbl * -1;
		var maxStartW = imgMsg.w  * fdbl;
		var maxStartH = imgMsg.h  * fdbl;
		var point = {
				minStartX : 0,
				minStartY : 0,
				minStartW : imgMsg.w,
				minStartH : imgMsg.h,
				
				minToX    : minToX,
				minToY    : minToY,
				minToW    : minToW,
				minToH    : minToH,
				
				minStepX  : minToX / step,
				minStepY  : minToY / step,
				minStepW  : (imgMsg.w - minToW) / step,
				minStepH  : (imgMsg.h - minToH) / step,
				
				
				maxStartX : maxStartX,
				maxStartY : maxStartY,
				maxStartW : maxStartW,
				maxStartH : maxStartH,
				
				maxToX    : 0,
				maxToY    : 0,
				maxToW    : imgMsg.w,
				maxToH    : imgMsg.h,
				
				maxStepX  : maxStartX / step,
				maxStepY  : maxStartY / step,
				maxStepW  : (maxStartW - imgMsg.w) / step,
				maxStepH  : (maxStartH - imgMsg.h) / step,
			};
		console.log(point);
		return point;
	}
	//画图
	var showImgCanvas = document.getElementById("showImgCanvas");
	var showImgCanvas_2d = showImgCanvas.getContext("2d");
	showImgCanvas.width  = imgMsg.w;
	showImgCanvas.height = imgMsg.h;
	var img1  = new Image();
	var img2  = new Image();
	var img3  = new Image();
	function drawImg(w1,h1,x1,y1,w2,h2,x2,y2){
		showImgCanvas_2d.clearRect(0,0,imgMsg.w,imgMsg.h);
		showImgCanvas_2d.drawImage(img2,x2,y2,w2,h2);
		showImgCanvas_2d.drawImage(img1,x1,y1,w1,h1);
	}
	//配置初始图片显示状态
	function setImgMsg(start){
		var ImgMsg = getPoint(start);
		if(start > 0){//第二屏及以后,当前屏的图在上一屏时已全加载好了,只需预加载下一屏的一张图
			img1 = img2;
			img2 = img3;
			drawImg(ImgMsg.minStartW , ImgMsg.minStartH , ImgMsg.minStartX , ImgMsg.minStartY , ImgMsg.maxStartW , ImgMsg.maxStartH , ImgMsg.maxStartX , ImgMsg.maxStartY);
			var byimg = new Image();
			if(start < end){//最后一屏时不用再预加载下一屏的图了
				byimg.src = imgList[start + 2].imgsrc;
				byimg.onload = function(){
					img3 = byimg;
					console.log(img1,img2,img3);
				}
			}
		}else{//第一屏时加载好前3张图(当前屏两张图及下一屏一张图)
			img2.src = imgList[start + 1].imgsrc;
			img2.onload = function(){
				img1.src = imgList[start].imgsrc;
				img1.onload = function(){
					drawImg(ImgMsg.minStartW , ImgMsg.minStartH , ImgMsg.minStartX , ImgMsg.minStartY , ImgMsg.maxStartW , ImgMsg.maxStartH , ImgMsg.maxStartX , ImgMsg.maxStartY);
					img3.src = imgList[start + 2].imgsrc;
					img3.onload = function(){
						console.log(img1,img2,img3);
					}
				}
			}
		}
		return ImgMsg;
	}

	var pointMsg = setImgMsg(start);
	var imgTimer;
	document.getElementById('btn').addEventListener('touchstart',touchStart,false);
	document.getElementById('btn').addEventListener('mousedown',touchStart,false);
	function touchStart(e){
		e.preventDefault();
		clearInterval(imgTimer);
		imgTimer = setInterval(showDh,timerTime);
	}
	document.getElementById('btn').addEventListener('touchend',touchEnd,false);
	document.getElementById('btn').addEventListener('mouseup',touchEnd,false);
	function touchEnd(e){
		clearInterval(imgTimer);
	}
	function showDh(){
		if(stepNum > step){
			if(start >= end){
				$('#btn').fadeOut('fast');
				clearInterval(imgTimer);
				//结束时回调方法
				if(if_callback){
					callback();
				}
				return;
			}else{
				start++;
				stepNum = 1;
				pointMsg = setImgMsg(start);
			}
			return;
		}
		//console.log(stepNum , start , end);
																		
		drawImg(pointMsg.minStartW - stepNum * pointMsg.minStepW , pointMsg.minStartH - stepNum * pointMsg.minStepH , pointMsg.minStartX + stepNum * pointMsg.minStepX , pointMsg.minStartY + stepNum * pointMsg.minStepY , pointMsg.maxStartW - stepNum * pointMsg.maxStepW , pointMsg.maxStartH - stepNum * pointMsg.maxStepH , pointMsg.maxStartX - stepNum * pointMsg.maxStepX , pointMsg.maxStartY - stepNum * pointMsg.maxStepY);
													
		stepNum ++;
	}
}

包含JS文件 CanvasCycleShowImg.2.0-min.js

/*
JS不断向CANVAS中画入两张图片(画入的图片src、画入的图片宽高、画入的的图片位置 等变化) 版循环展示图片(画中画效果)
author 羽筠
2017-07-06
*/
function CanvasCycleShowImg(){this.imgMsg={w:640,h:1138},this.imgList=[{imgsrc:"1.jpg",inX:"",inY:"",inW:"",inH:""},{imgsrc:"2.jpg",inX:470,inY:50,inW:118,inH:210},{imgsrc:"3.jpg",inX:86,inY:561,inW:195,inH:346},{imgsrc:"4.jpg",inX:266,inY:472,inW:118,inH:210}],this.step=300,this.timerTime=10,this.headStyle="<style>*{ margin:0px; padding:0px; box-sizing:border-box; -webkit-tap-highlight-color:rgba(0,0,0,0);}html{ min-width:320px; max-width:640px; margin:0 auto;}html , body{ display:block; width:100%; height:100%;}#btn{ width:50px; height:50px; line-height:50px; text-align:center; color:#fff; border-radius:50%; background-color:#f00; cursor:pointer; position:absolute; left:50%; margin-left:-25px; bottom:20px;}</style>",this.showImgEle='<div id="showImg" style=" width:100%; height:100%; overflow:hidden; position:relative;"><canvas id="showImgCanvas" style=" width:100%; position:absolute; left:0; top:0;" /></div>',this.showImgBtn='<div id="btn"></div>'}CanvasCycleShowImg.prototype.init=function(a){function n(a){var b,d,e,i,j,l,m,n,o,p;return x=g[a+1].inX,y=g[a+1].inY,w=g[a+1].inW,h=g[a+1].inH,b=f.w/w,w/f.w,d=x,e=y,i=w,j=h,l=-1*d*b,m=-1*e*b,n=f.w*b,o=f.h*b,p={minStartX:0,minStartY:0,minStartW:f.w,minStartH:f.h,minToX:d,minToY:e,minToW:i,minToH:j,minStepX:d/k,minStepY:e/k,minStepW:(f.w-i)/k,minStepH:(f.h-j)/k,maxStartX:l,maxStartY:m,maxStartW:n,maxStartH:o,maxToX:0,maxToY:0,maxToW:f.w,maxToH:f.h,maxStepX:l/k,maxStepY:m/k,maxStepW:(n-f.w)/k,maxStepH:(o-f.h)/k}}function t(a,b,c,d,e,g,h,i){p.clearRect(0,0,f.w,f.h),p.drawImage(r,h,i,e,g),p.drawImage(q,c,d,a,b)}function u(a){var c,b=n(a);return a>0?(q=r,r=s,t(b.minStartW,b.minStartH,b.minStartX,b.minStartY,b.maxStartW,b.maxStartH,b.maxStartX,b.maxStartY),c=new Image,j>a&&(c.src=g[a+2].imgsrc,c.onload=function(){s=c})):(r.src=g[a+1].imgsrc,r.onload=function(){q.src=g[a].imgsrc,q.onload=function(){t(b.minStartW,b.minStartH,b.minStartX,b.minStartY,b.maxStartW,b.maxStartH,b.maxStartX,b.maxStartY),s.src=g[a+2].imgsrc,s.onload=function(){}}}),b}function A(a){a.preventDefault(),clearInterval(z),z=setInterval(C,m)}function B(){clearInterval(z)}function C(){return l>k?i>=j?($("#btn").fadeOut("fast"),clearInterval(z),b&&a(),void 0):(i++,l=1,v=u(i),void 0):(t(v.minStartW-l*v.minStepW,v.minStartH-l*v.minStepH,v.minStartX+l*v.minStepX,v.minStartY+l*v.minStepY,v.maxStartW-l*v.maxStepW,v.maxStartH-l*v.maxStepH,v.maxStartX-l*v.maxStepX,v.maxStartY-l*v.maxStepY),l++,void 0)}var c,d,e,f,g,i,j,k,l,m,o,p,q,r,s,v,z,b=!1;arguments[0]&&(b=!0),c=this.headStyle,$("head").append(c),d=this.showImgEle,$("body").prepend(d),e=this.showImgBtn,$("#showImg").after(e),f=this.imgMsg,g=this.imgList,i=0,j=g.length-2,k=this.step,l=1,m=this.timerTime,o=document.getElementById("showImgCanvas"),p=o.getContext("2d"),o.width=f.w,o.height=f.h,q=new Image,r=new Image,s=new Image,v=u(i),document.getElementById("btn").addEventListener("touchstart",A,!1),document.getElementById("btn").addEventListener("mousedown",A,!1),document.getElementById("btn").addEventListener("touchend",B,!1),document.getElementById("btn").addEventListener("mouseup",B,!1)};

包含JS文件 CanvasCycleShowImg.2.0-jm.js

/*
JS不断向CANVAS中画入两张图片(画入的图片src、画入的图片宽高、画入的的图片位置 等变化) 版循环展示图片(画中画效果)
author 羽筠
2017-07-06
*/
eval(function(a,b,c,d,e,f){if(e=function(a){return(b>a?"":e(parseInt(a/b)))+((a%=b)>35?String.fromCharCode(a+29):a.toString(36))},!"".replace(/^/,String)){for(;c--;)f[e(c)]=d[c]||e(c);d=[function(a){return f[a]}],e=function(){return"\\w+"},c=1}for(;c--;)d[c]&&(a=a.replace(new RegExp("\\b"+e(c)+"\\b","g"),d[c]));return a}('32(2L(p,a,c,k,e,d){e=2L(c){2K(c<a?\'\':e(3C(c/a)))+((c=c%a)>35?2M.3B(c+29):c.3z(36))};2Q(!\'\'.2P(/^/,2M)){2N(c--){d[e(c)]=k[c]||e(c)}k=[2L(e){2K d[e]}];e=2L(){2K\'\\\\w+\'};c=1};2N(c--){2Q(k[c]){p=p.2P(2O 3A(\'\\\\b\'+e(c)+\'\\\\b\',\'g\'),k[c])}}2K p}(\'6 1g(){5.1y={w:1R,h:1Q},5.1s=[{7:"1.U",J:"",K:"",G:"",F:""},{7:"2.U",J:1O,K:16,G:1v,F:1w},{7:"3.U",J:1S,K:1T,G:1W,F:1N},{7:"4.U",J:1U,K:1X,G:1v,F:1w}],5.1q=1J,5.1t=10,5.1p="<Y>*{ 15:1x; 2j:1x; 1u-1Y:1e-1u; -2e-2f-28-1c:21(0,0,0,0);}1r{ 20-8:1Z; 23-8:24; 15:0 27;}1r , 1B{ 25:2b; 8:E%; D:E%;}#9{ 8:13; D:13; 26-D:13; 2a-1H:2h; 1c:#1F; 1e-2c:16%; 22-1c:#29; 2g:2i; 18:1d; 17:16%; 15-17:-1V; 1K:1L;}</Y>",5.1A=\\\'<O 19="1D" Y=" 8:E%; D:E%; 1I:1M; 18:1G;"><1E 19="1z" Y=" 8:E%; 18:1d; 17:0; 1P:0;" /></O>\\\',5.1C=\\\'<O 19="9"></O>\\\'}1g.2u.2D=6(a){6 b(a){12 b,c,d,e,f,g,i,j,k,n;1a x=m[a+1].J,y=m[a+1].K,w=m[a+1].G,h=m[a+1].F,b=l.w/w,w/l.w,c=x,d=y,e=w,f=h,g=-1*c*b,i=-1*d*b,j=l.w*b,k=l.h*b,n={M:0,P:0,Z:l.w,L:l.h,2B:c,2F:d,2z:e,2A:f,1j:c/p,1l:d/p,1n:(l.w-e)/p,1k:(l.h-f)/p,11:g,X:i,Q:j,T:k,2E:0,2I:0,2H:l.w,2G:l.h,1h:g/p,1f:i/p,1m:(j-l.w)/p,1o:(k-l.h)/p}}6 c(a,b,c,d,e,f,g,h){t.2J(0,0,l.w,l.h),t.1i(v,g,h,e,f),t.1i(u,c,d,a,b)}6 d(a){12 d,e=b(a);1a a>0?(u=v,v=z,c(e.Z,e.L,e.M,e.P,e.Q,e.T,e.11,e.X),d=S W,o>a&&(d.R=m[a+2].7,d.N=6(){z=d})):(v.R=m[a+1].7,v.N=6(){u.R=m[a].7,u.N=6(){c(e.Z,e.L,e.M,e.P,e.Q,e.T,e.11,e.X),z.R=m[a+2].7,z.N=6(){}}}),e}6 e(a){a.2k(),1b(B),B=2p(g,r)}6 f(){1b(B)}6 g(){1a q>p?n>=o?($("#9").2o("2n"),1b(B),C&&a(),14 0):(n++,q=1,A=d(n),14 0):(c(A.Z-q*A.1n,A.L-q*A.1k,A.M+q*A.1j,A.P+q*A.1l,A.Q-q*A.1m,A.T-q*A.1o,A.11-q*A.1h,A.X-q*A.1f),q++,14 0)}12 i,j,k,l,m,n,o,p,q,r,s,t,u,v,z,A,B,C=!1;2m[0]&&(C=!0),i=5.1p,$("2q").2r(i),j=5.1A,$("1B").2w(j),k=5.1C,$("#1D").2v(k),l=5.1y,m=5.1s,n=0,o=m.2s-2,p=5.1q,q=1,r=5.1t,s=H.I("1z"),t=s.2t("2d"),s.8=l.w,s.D=l.h,u=S W,v=S W,z=S W,A=d(n),H.I("9").V("2y",e,!1),H.I("9").V("2l",e,!1),H.I("9").V("2x",f,!1),H.I("9").V("2C",f,!1)};\',3E,3D,\'|||||3y|2L|3x|3s|3r||||||||||||||||||||||||||||||3q|3t|3u|3w|3v|3F|3G|3Q|3P|3R|3S|3U|3T|3O|3N|2O|3I|3W|3H|3J|3p|3M|3L||3V|3i|30|2Z|31|50|34|2Y|37|2K|2R|2S|2X|2W|2V|2T|2U|33|3o|3j|38|3k|3l|3n|3m|3h|3g|3b|3a|39|3c|3d|3f|3e|3K|4l|4K|4Q|4I|4L|4M|4O|4N|4H|4G|4A|4z|4y|4B|4C|4F|4E|4D|4P|54|53|51|55|56|57|52|4Y|4T|4S|4Z|4R|4U|4V|4X|4W|4J|4w|49|48||47|4a|4b|4d|4c|46|45|3Z|3Y|3X|40|41|44|43|42|4e|4x|4f|4r|4q|4p|4s|4t|4v|4u|4o|4n|4i|4h|4g|4j|4k\'.4m(\'|\'),0,{}))',62,318,"||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||return|function|String|while|new|replace|if|clearInterval|color|CanvasCycleShowImg|maxStepX|maxStepY|border|absolute|position|void|50px|margin|eval|drawImage|left|||id|minStepY|box|timerTime|imgList|118|210|imgMsg|0px|html|step|var|minStepH|maxStepW|minStepW|headStyle|maxStepH|minStepX|maxStartY|height|btn|width|100|inH|document|inW|imgsrc|this|toString|RegExp|fromCharCode|parseInt|170|62|getElementById|inX|addEventListener|maxStartH|Image|showImgCanvas|minStartW|style|src|maxStartW|minStartH|inY|minStartX|onload|minStartY|div|maxStartX|jpg|fast|arguments|mousedown|fadeOut|setInterval|length|append|head|preventDefault|padding|webkit|radius|block|tap|cursor|pointer|center|getContext|after|maxToW|maxToH|minToY|maxToY|clearRect|showImgEle|split|maxToX|init|touchstart|touchend|prepend|minToW|minToH|mouseup|minToX|text|prototype|hidden|20px|bottom|346|470|640|1138|top|300|overflow|showImg|f00|body|canvas|fff|align|relative|86|showImgBtn|640px|background|rgba|display|line|highlight|auto|min|max||25px|320px|266|561|195|472|sizing".split("|"),0,{}));

实例化: var CanvasCycleShowImg = new CanvasCycleShowImg();

以下参数是 可选择性的,不设置会使用默认参数值
CanvasCycleShowImg.imgMsg = {w:640,h:1138};//所使用图片的实际尺寸,如果使用的图片不是些尺寸,请重新设置
CanvasCycleShowImg.step  = 300;//多少步完成起始至最终 状态的变化
CanvasCycleShowImg.timerTime = 10;//定时器间隔时间(单位毫秒)
//以下一般要重新定义“按”的按钮样式时重新设置
CanvasCycleShowImg.headStyle = '<style>\
*{ margin:0px; padding:0px; box-sizing:border-box; -webkit-tap-highlight-color:rgba(0,0,0,0);}\n\
html{ min-width:320px; max-width:640px; margin:0 auto;}\n\
html , body{ display:block; width:100%; height:100%;}\n\
#btn{ width:50px; height:50px; line-height:50px; text-align:center; color:#fff; border-radius:50%; background-color:#f00; cursor:pointer; position:absolute; left:50%; margin-left:-25px; bottom:20px;}\
</style>';

以下参数 必须重新设置参数,imgList是所有要展示在页面中的图片(所有图片的位置、宽高信息设置(根据图片 的实际尺寸 设置的),inX , inY , inW , inH 中的值表示上一张图在本张图中(本张图片最终状态时全部显示时)的信息)
CanvasCycleShowImg.imgList = [
{
imgsrc:'test/1.jpg',
inX:'',
inY:'',
inW:'',
inH:''
},
{
imgsrc:'test/2.jpg',
inX:470,
inY:50,
inW:118,
inH:210
},
{
imgsrc:'test/3.jpg',
inX:86,
inY:561,
inW:195,
inH:346
},
{
imgsrc:'test/4.jpg',
inX:266,
inY:472,
inW:118,
inH:210
},
];
//执行以下方法实现功能
//最后一屏时 不 需要回调
CanvasCycleShowImg.init();
//最后一屏时     需要回调
// CanvasCycleShowImg.init(theEnd);
function theEnd(){
setTimeout(function(){
alert('已到最后一屏啦~~~');
},1000);
}



猜你喜欢

转载自blog.csdn.net/qq_16494241/article/details/74639857