您现在的位置是:网站首页> 编程资料编程资料
Canvas图片分割效果的实现基于Html5 canvas实现裁剪图片和马赛克功能及又拍云上传图片 功能利用canvas实现图片下载功能来实现浏览器兼容问题canvas压缩图片以及卡片制作的方法示例Canvas实现保存图片到本地的示例代码html2canvas 将html代码转为图片的使用方法详解canvas绘图时遇到的跨域问题canvas 下载二维码和图片加水印的方法在canvas上实现元素图片镜像翻转动画效果的方法
2021-08-31
1283人已围观
简介 这篇文章主要介绍了Canvas图片分割效果的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
之前在逛cssdesignawards时发现了一个把图片内容分割的效果(网址:https://weareludwig.com),大家可以点进去看看,感觉挺炫酷的,于是自己试着实现了一下,效果还不错。效果查看https://codepen.io/geeknoble/pen/OQaOVG
分析
首先我们可以发现图片的内容被分成了一个个小矩形,并对每个矩形进行了随机平移。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 = []; //位置随机值 //初始化矩形坐标 var x1 = 0, y1 = 0, x = 0, y = 0; for (var i = 0; i < this.countY; i++) { for (var j = 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 () { var self = 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 () { var self = 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个参数分别是当前时间,初始位置,结束位置,动画时间。详细内容可以参考张鑫旭的这篇文章https://www.zhangxinxu.com/wordpress/2016/12/how-use-tween-js-animation-easing/ 。通过Tween.js可以算出每一帧要移动的距离,然后再使用requestAnimationFrame去更新坐标。
blockAnimation: function () { var flag = 1; if (this.state) { // 判断是打乱图片还是还原图片 this.update(true) } else { flag = -1; this.update(false); } var self = this; this.startTime = +new Date(); // 获取当前时间 this.state = !this.state; (function animation() { var t = +new Date(); if (t >= self.startTime + self.duration) { // 动画结束条件 return false; } self.data.forEach(function (item, index) { if (index % 2 == 0) { var pos = 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 { var pos = 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) { return false; } this.checkTime(2); var self = this; val ? val = 1 : val = -1; //判断上滑还是下滑 if ((this.index + val) < 0 || (this.index + val) >= (this.img.length)) { //判断图片序号是否到底 return false; } this.state ? this.update(true) : this.update(false); this.startTime = +new Date(); (function animation() { var t = +new Date(); 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; return false; } self.data.forEach(function (item) { var pos = 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); })() }x轴的切换也是同理,现在所有功能都差不多完成了,完整代码可以在codepen里查看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
相关内容
- HTML5中的Web Notification桌面通知功能的实现方法Html5中的桌面通知Notification的实现HTML5实现桌面通知 提示功能HTML5实现Notification API桌面通知功能 html5桌面通知(Web Notifications)实例解析突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面
- html5视频媒体标签video的使用方法及完整参数说明详解html5用video标签流式加载的实现Html5 video标签视频的最佳实践html5自定义video标签的海报与播放按钮功能详解Html5中video标签那些属性和方法解决html5中的video标签ios系统中无法播放使用的问题
- Html5实现首页动态视频背景的示例代码html5视频媒体标签video的使用方法及完整参数说明详解HTML5实现视频弹幕功能HTML5 视频播放(video),JavaScript控制视频的实例代码HTML5视频播放插件 video.js介绍 HTML5自定义视频播放器源码
- HTML5自定义元素播放焦点图动画的实现HTML5语义化元素你真的用对了吗Html5新增标签与样式及让元素水平垂直居中浅谈HTML5中dialog元素尝鲜HTML5 source标签:媒介元素定义媒介资源HTML5新表单元素_动力节点Java学院整理 html5文本内容_动力节点Java学院整理 html5 input元素新特性_动力节点Java学院整理详解HTML5表单新增属性Html5元素及基本语法详解html5表单及新增的改良元素详解
- 使用Html5中的cavas画一面国旗HTML5 Canvas 破碎重组的视频特效的示例代码前端实现打印图像功能html5 canvas绘制网络字体的常用方法导出HTML5 Canvas图片并上传服务器功能
- 关于canvas绘制模糊问题的解决方法高清屏中使用Canvas绘图出现模糊的问题及解决方法深入了解canvas在移动端绘制模糊的问题解决HTML5 Canvas图像模糊完美解决办法html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
- html svg生成环形进度条的实现方法HTML5超炫酷粒子效果的进度条的实现示例HTML5触摸事件实现移动端简易进度条的实现方法HTML5实现自带进度条和滑块滑杆效果网页加载进度条详解(推荐)HTML页面缩小后显示滚动条的示例代码
- html2 canvas生成清晰的图片实现打印功能html2canvas生成的图片偏移不完整的解决方法html2canvas截图空白问题的解决使用html2canvas实现将html内容写入到canvas中生成图片html2canvas.js 实现页面截图html2 canvas svg不能识别的解决方案
- 将SVG图引入到HTML页面的实现HTML5如何使用SVG的方法示例Html5之svg可缩放矢量图形_动力节点Java学院整理使用HTML5进行SVG矢量图形绘制的入门教程深入浅析HTML5中的SVGhtml5+svg学习指南之SVG基础知识html5中svg canvas和图片之间相互转化思路代码HTML中使用SVG与SVG预定义形状元素介绍
- 解析浏览器的一些“滚动”行为鉴赏 CSS3改变浏览器滚动条样式纯css修改浏览器scrollbar滚动条样式示例纯CSS改变webkit内核浏览器的滚动条样式强制显示、隐藏(IE\Mozilla)浏览器的滚动条实现代码CSS自定义WebKit内核浏览器滚动条实现代码JS+CSS实现侧边栏跟随浏览器滚动效果FireFox火狐浏览器与IE兼容问题 - 透明滤镜 DIV滚动条
