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

来源:互联网 发布:猎头工作怎么样 知乎 编辑:程序博客网 时间:2024/06/05 00:41
循环展示图片(画中画效果)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(){drawImg(ImgMsg.minStartW , ImgMsg.minStartH , ImgMsg.minStartX , ImgMsg.minStartY , ImgMsg.maxStartW , ImgMsg.maxStartH , ImgMsg.maxStartX , ImgMsg.maxStartY);img1.src = imgList[start].imgsrc;img1.onload = function(){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);}\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;var stepNum=1;var timerTime=this.timerTime;function getPoint(start){x=imgList[start+1].inX;y=imgList[start+1].inY;w=imgList[start+1].inW;h=imgList[start+1].inH;var fdbl=imgMsg.w/w;var sxbl=w/imgMsg.w;var minToX=x;var minToY=y;var minToW=w;var minToH=h;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{img2.src=imgList[start+1].imgsrc;img2.onload=function(){drawImg(ImgMsg.minStartW,ImgMsg.minStartH,ImgMsg.minStartX,ImgMsg.minStartY,ImgMsg.maxStartW,ImgMsg.maxStartH,ImgMsg.maxStartX,ImgMsg.maxStartY);img1.src=imgList[start].imgsrc;img1.onload=function(){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;}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-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}("b 1q(){a.6={w:1Z,h:1S};a.d=[{g:'1.Q',t:'',v:'',I:'',G:''},{g:'2.Q',t:1T,v:18,I:1A,G:1z},{g:'3.Q',t:2g,v:2f,I:22,G:2j},{g:'4.Q',t:2l,v:2e,I:1A,G:1z},];a.f=2a;a.15=10;a.T='<Y>*{ 19:1H; 29:1H; 1m-2b:1o-1m; -28-27-23-1a:24(0,0,0,0);}1r{ 25-p:26; 2k-p:2m; 19:0 2i;}1r , 1n{ 2h:2n; p:z%; F:z%;}#m{ p:1j; F:1j; 1Y-F:1j; 1R-21:20; 1a:#1U; 1o-1X:18%; 1V-1a:#1W; 2c:2t; 16:1p; 1l:18%; 19-1l:-2Q; 2O:2H;}</Y>';a.13='<12 1i=\"1s\"Y=\" p:z%; F:z%; 2J:2N; 16:2L;\">\\<2M 1i=\"s\"Y=\" p:z%; 16:1p; 1l:0; 2K:0;\"/>\\</12>';a.J='<12 1i=\"m\"></12>'}1q.2I.2S=b(1w){5 1d=D;r(2U[0]){1d=2T}5 T=a.T;$('2P').2R(T);5 13=a.13;$('1n').2G(13);5 J=a.J;$('#1s').2E(J);5 6=a.6;5 d=a.d;5 7=0;5 1c=d.2u-2;5 f=a.f;5 c=1;5 15=a.15;b 1v(7){x=d[7+1].t;y=d[7+1].v;w=d[7+1].I;h=d[7+1].G;5 E=6.w/w;5 2v=w/6.w;5 A=x;5 B=y;5 L=w;5 N=h;5 j=A*E*-1;5 q=B*E*-1;5 n=6.w*E;5 k=6.h*E;5 1h={X:0,Z:0,U:6.w,W:6.h,A:A,B:B,L:L,N:N,1E:A/f,1u:B/f,1C:(6.w-L)/f,1D:(6.h-N)/f,j:j,q:q,n:n,k:k,2o:0,2F:0,2s:6.w,2p:6.h,1Q:j/f,1P:q/f,1x:(n-6.w)/f,1I:(k-6.h)/f,};1f.1g(1h);11 1h}5 s=C.H(\"s\");5 M=s.2q(\"2d\");s.p=6.w;s.F=6.h;5 o=O P();5 i=O P();5 l=O P();b V(1y,1t,1G,1F,1M,1O,1K,1J){M.2r(0,0,6.w,6.h);M.1N(i,1K,1J,1M,1O);M.1N(o,1G,1F,1y,1t)}b 1k(7){5 9=1v(7);r(7>0){o=i;i=l;V(9.U,9.W,9.X,9.Z,9.n,9.k,9.j,9.q);5 R=O P();r(7<1c){R.K=d[7+2].g;R.S=b(){l=R;1f.1g(o,i,l)}}}1B{i.K=d[7+1].g;i.S=b(){V(9.U,9.W,9.X,9.Z,9.n,9.k,9.j,9.q);o.K=d[7].g;o.S=b(){l.K=d[7+2].g;l.S=b(){1f.1g(o,i,l)}}}}11 9}5 8=1k(7);5 u;C.H('m').14('2w',17,D);C.H('m').14('2x',17,D);b 17(e){e.2C();1e(u);u=2D(1L,15)}C.H('m').14('2B',1b,D);C.H('m').14('2A',1b,D);b 1b(e){1e(u)}b 1L(){r(c>f){r(7>=1c){$('#m').2y('2z');1e(u);r(1d){1w()}11}1B{7++;c=1;8=1k(7)}11}V(8.U-c*8.1C,8.W-c*8.1D,8.X+c*8.1E,8.Z+c*8.1u,8.n-c*8.1x,8.k-c*8.1I,8.j-c*8.1Q,8.q-c*8.1P);c++}}",62,181,"|||||var|imgMsg|start|pointMsg|ImgMsg|this|function|stepNum|imgList||step|imgsrc||img2|maxStartX|maxStartH|img3|btn|maxStartW|img1|width|maxStartY|if|showImgCanvas|inX|imgTimer|inY||||100|minToX|minToY|document|false|fdbl|height|inH|getElementById|inW|showImgBtn|src|minToW|showImgCanvas_2d|minToH|new|Image|jpg|byimg|onload|headStyle|minStartW|drawImg|minStartH|minStartX|style|minStartY||return|div|showImgEle|addEventListener|timerTime|position|touchStart|50|margin|color|touchEnd|end|if_callback|clearInterval|console|log|point|id|50px|setImgMsg|left|box|body|border|absolute|CanvasCycleShowImg|html|showImg|h1|minStepY|getPoint|callback|maxStepW|w1|210|118|else|minStepW|minStepH|minStepX|y1|x1|0px|maxStepH|y2|x2|showDh|w2|drawImage|h2|maxStepY|maxStepX|text|1138|470|fff|background|f00|radius|line|640|center|align|195|highlight|rgba|min|320px|tap|webkit|padding|300|sizing|cursor||472|561|86|display|auto|346|max|266|640px|block|maxToX|maxToH|getContext|clearRect|maxToW|pointer|length|sxbl|touchstart|mousedown|fadeOut|fast|mouseup|touchend|preventDefault|setInterval|after|maxToY|prepend|20px|prototype|overflow|top|relative|canvas|hidden|bottom|head|25px|append|init|true|arguments".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);
}