作者:拍友2502883387 | 来源:互联网 | 2023-09-06 19:20
为什么会有这篇博文,因为昨天我的杯子碎了,同个办公室的人手机屏幕碎了……碎碎平安既然说的是碎裂效果,那什么是碎裂呢,看看生活中的总而言之就是完整的一块,碎成了好些块。进入正题,canv
为什么会有这篇博文,因为昨天我的杯子碎了,同个办公室的人手机屏幕碎了……碎碎平安
既然说的是碎裂效果,那什么是碎裂呢,看看生活中的
总而言之就是完整的一块,碎成了好些块。
进入正题,canvas对于图像处理很强,毕竟直接操作像素,马赛克,翻转,二值化都很方便。但是经过我的一番尝试,说实话,canvas分割图像这方面还真挺麻烦的……
当然可能我的实现思路有问题,绕了弯,如果有更好地方法请指教,万分感激
讲了这么多,先看看几张gif,这样才有兴趣继续往下看嘛
特地让其动了起来,录制gif有点卡,真实情况下还是很平滑的
什么,你问有什么用?
那么看下一个gif
能看出来了吧,对于canvas上面所画的元素,可以让其碎成几块,然后进行移动,最后一个gif是简单裂图的,抛砖引玉一下
好了效果看完了,如果感兴趣决定继续往下看那就继续吧~
————————————————————————————————————————————————————————————————————————
首先说原理,我实现的原理
核心是canvas中画布的clip方法,不知道的简单看一下w3school关于clip简短的介绍
http://www.w3school.com.cn/tags/canvas_clip.asp
其实这个很坑,怎么坑了?
这又要说canvas的绘图了,它不同于SVG,SVG画一个圆,是创建了一个circle的SVG标签,添加到DOM中,你可以获取到这个圆的DOM节点,可以用js去读它的信息和进行操作。而canvas不行,它画了一个圆,只是在其画布上进行了一个操作,画布还是整个画布,你若是想移动这个圆,必须通过一系列重绘这个圆的坐标实现,不过速度比SVG快,原因DOM的重新渲染很耗时间和内存。
把canvas这个特点带到clip中成了什么情况?还是拿圆来举例,画了一个圆
我们用下clip看一下结果,下面是代码
oGC.save();
oGC.beginPath();
oGC.fillStyle = 'red'; //注意红色
oGC.moveTo(0, 400);
oGC.lineTo(300, 200);
oGC.lineTo(0, 0);
oGC.fill(); //①
oGC.clip();
oGC.closePath();
oGC.restore();
呵呵,果然canvas并不是把这个圆给切割开(看代码这种面向过程一顺溜下来也知道不关乎圆的事……)
仅仅获取到一个单独的操作区域,为什么说是单独的呢,代码和结果来解释
oGC.save();
oGC.beginPath();
oGC.fillStyle = 'red';
oGC.moveTo(0, 400);
oGC.lineTo(300, 200);
oGC.lineTo(0, 0);
oGC.fill();
oGC.clip();
oGC.closePath();
oGC.fillStyle = 'green'; //注意这个绿色
oGC.fillRect(100, 100, 200, 200);
oGC.restore();
结果如下
画成了一个不完整的长方形出来,代表clip切割出来的仅仅是画布的一部分,后续的操作只在这片区域有效(restore之后还原)
所以我们在clip之后需要再画一个圆,这样才能得到被切割的部分
现在问题来了,请往上翻看第一个gif,如何实现这样的效果呢
先给大家看看失败的情况
失败情况之移动再次画的圆:
特地加了红线让大家看清楚
失败情况之移动clip区域:
此时是不是觉得胜利就在眼前了,如果同时移动圆和clip区域呢!!!
结果如下,Fail!
这个结果更加证明了canvas的clip原理是什么鬼
那该怎么办呢,我实现第一张gif的方法是预先用clip获取需要切割的区域,然后画圆将其填充底色遮住,后面第二次clip和画圆的坐标是一直变动的
所以说很蛋疼!
上传了最后那个gif栗子的代码到github
地址是:https://github.com/westAnHui/imageCut-canvas
代码虽然无注释,但是应该还挺好懂的。栗子很简单,不过可扩展性还是有的,我在一张图片上面只取了一个点,如果可以取多点呢?加上一些特别的动画呢?不过那么又会有很多麻烦,不过还是值得研究研究的。
这篇文章也就算结束了,排版的比较乱,请见谅……
标题上面是canvas篇,当然后面还有其他的实现,我自己最喜欢的是用CSS的clip-path,下次再说~