html5中如何通过Canvas实现图片分割
本文小编为大家详细介绍“html5中如何通过Canvas实现图片分割”,内容详细,步骤清晰,细节处理妥当,希望这篇“html5中如何通过Canvas实现图片分割”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
分析
首先我们可以发现图片的内容被分成了一个个小矩形,并对每个矩形进行了随机平移。Canvas的drawImage函数可以对图片内容进行裁剪并绘制到Canvas画布中,所以该效果主要实现原理就是使用drawImage。主要效果有两个,一个是图片内容的打乱和复原,一个是和下张图片的切换,这两个效果都可以使用drawImage,只是移动的距离不一样。总体思路有了那么就可以去着手实现一下。
初始工作
首先我们要初始化一些变量,比如图片的宽高,矩形的个数,剪切的尺寸等,然后再计算每个矩形的坐标,使用一个二重循环将矩形坐标保存在data中。每个矩形有个随机位移,这个位移也需要保存起来,存在randoms中。其中x,y表示canvas画布的坐标,x1,y1表示图片裁剪的坐标。
init:function(context,width,height,area,img){this.context=context;this.img=img;this.imgWidth=img[0].width;//图片宽高this.imgHeight=img[0].height;this.index=0;//当前图片序号this.width=width;//画布宽高this.height=height;this.area=height/12;//小矩形长度this.countX=width/this.area;//水平和垂直方向小矩形个数this.countY=height/this.area;this.wx=this.imgWidth/this.countX;//图片在小矩形中的宽高this.wy=this.imgHeight/this.countY;this.state=true;//图片状态,true表示未拆分this.dataFlag=true;//小矩形坐标状态,true表示未加上随机值this.duration=1000;//动画时间this.duration2=1500;this.startTime=0;this.data=[];//小矩形坐标信息this.randoms=[];//位置随机值//初始化矩形坐标varx1=0,y1=0,x=0,y=0;for(vari=0;i<this.countY;i++){for(varj=0;j<this.countX;j++){context.drawImage(this.img[this.index],x1,y1,this.wx,this.wy,x,y,this.area,this.area);//储存矩形坐标this.data.push({x1:x1,y1:y1,x:x,y:y});//添加随机值this.randoms.push(random(-this.area,this.area));x1+=this.wx;x+=this.area;}x1=0;y1+=this.wy;x=0;y+=this.area;}this.checkMargin();}
检测边缘
在给矩形添加位移之前我们需要判断一下位移后的坐标是否超过图片界限,比如在顶部的矩形如果是y轴移动,那么只能够向上移,判断的条件为当前坐标加上位移值是否小于0或大于图片的宽高。如果更新后的坐标小于0,那么这个随机值一定是负数,需要把随机值改为正数,如果大于图片高度,那么改成负数即可。由于每个矩形的移动都是在一个方向上移动,所以我这里写成偶数位移动x轴,奇数位移动y轴。
//检测边缘checkMargin:function(){varself=this;this.data.forEach(function(item,index){if(index%2==0){//下标为2的倍数时移动x轴,否则移动y轴if(item.x1+self.randoms[index]<0)//改为正数self.randoms[index]=-self.randoms[index];if(item.x1+self.wx+self.randoms[index]>self.imgWidth)//改为负数self.randoms[index]=-Math.abs(self.randoms[index])}else{if(item.y1+self.randoms[index]<0)self.randoms[index]=-self.randoms[index];if(item.y1+self.randoms[index]+self.wy>self.imgHeight)self.randoms[index]=-Math.abs(self.randoms[index])}})}
分离和复原
动画的内容的分离和复原就是更新矩形坐标的值,打乱内容只要将data里的坐标加上随机值,而复原就是减去随机值,
//检测边缘checkMargin:function(){varself=this;this.data.forEach(function(item,index){if(index%2==0){//下标为2的倍数时移动x轴,否则移动y轴if(item.x1+self.randoms[index]<0)//改为正数self.randoms[index]=-self.randoms[index];if(item.x1+self.wx+self.randoms[index]>self.imgWidth)//改为负数self.randoms[index]=-Math.abs(self.randoms[index])}else{if(item.y1+self.randoms[index]<0)self.randoms[index]=-self.randoms[index];if(item.y1+self.randoms[index]+self.wy>self.imgHeight)self.randoms[index]=-Math.abs(self.randoms[index])}})}
在储存好坐标后就可以去实现平移动画了,移动的过程有一个平滑的过渡,我们可以使用Tween.js的缓动算法,该算法有4个参数分别是当前时间,初始位置,结束位置,动画时间。通过Tween.js可以算出每一帧要移动的距离,然后再使用requestAnimationFrame去更新坐标。
blockAnimation:function(){varflag=1;if(this.state){//判断是打乱图片还是还原图片this.update(true)}else{flag=-1;this.update(false);}varself=this;this.startTime=+newDate();//获取当前时间this.state=!this.state;(functionanimation(){vart=+newDate();if(t>=self.startTime+self.duration){//动画结束条件returnfalse;}self.data.forEach(function(item,index){if(index%2==0){varpos=Math.tween.Expo.easeInOut(t-self.startTime,0,self.randoms[index]*flag,self.duration);//计算出每帧移动的距离self.context.drawImage(self.img[self.index],item.x1+pos,item.y1,self.wx,self.wy,item.x,item.y,self.area,self.area);}else{varpos=Math.tween.Expo.easeInOut(t-self.startTime,0,self.randoms[index]*flag,self.duration);self.context.drawImage(self.img[self.index],item.x1,item.y1+pos,self.wx,self.wy,item.x,item.y,self.area,self.area);}});requestAnimationFrame(animation);})();}
到这里就已经实现了分离和复原的动画了
图片切换
接下来开始处理图片切换的部分,这里跟轮播图有点像,轮播图动画是将每个图片位置移动可视窗口宽度的距离,这里也是一样,只要将坐标加上图片高度就可以实现y轴上的切换。和轮播图不一样的是,我们这里只有一个canvas标签,在切换时只需要改变当前图和下一张图的坐标,当前图移动距离为y1 + pos,下张图移动距离为y1 + pos - imgHeight(为什么要减imgHeight就不用说了吧)。
//垂直滑动动画verticalAnimation:function(val){if(!this.time2){returnfalse;}this.checkTime(2);varself=this;val?val=1:val=-1;//判断上滑还是下滑if((this.index+val)<0||(this.index+val)>=(this.img.length)){//判断图片序号是否到底returnfalse;}this.state?this.update(true):this.update(false);this.startTime=+newDate();(functionanimation(){vart=+newDate();if(t>=self.startTime+self.duration2){val===1?self.index++:self.index--;//调整图片顺序self.index<0?self.index=self.img.length-1:self.index;self.index>=self.img.length?self.index=0:self.index;returnfalse;}self.data.forEach(function(item){varpos=Math.tween.Cubic.easeInOut(t-self.startTime,0,(self.imgHeight)*val,self.duration2);//更新当前图片坐标self.context.drawImage(self.img[self.index],item.x1,item.y1+pos,self.wx,self.wy,item.x,item.y,self.area,self.area);//更新下张图片坐标self.context.drawImage(self.img[self.index+val],item.x1,item.y1+pos-self.imgHeight*val,self.wx,self.wy,item.x,item.y,self.area,self.area);});requestAnimationFrame(animation);})()}
读到这里,这篇“html5中如何通过Canvas实现图片分割”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。