在canvas上实现元素图片镜像翻转动画效果的方法


Posted in HTML / CSS onMarch 20, 2018

一、Canvas图片水平镜像翻转效果预览

您可以狠狠的点击这里:canvas图片水平镜像翻转动画demo

demo页面中点击图片动画效果可见。

二、Canvas上实现图片镜像翻转的实现

CSS中要想实现元素的翻转效果,比较简单,例如我们希望某一张图片水平镜像翻转,只需要一行CSS就可以了:

img {
    transform: scaleX(-1);
}

或者:

img {
    transform: scale(-1, 1);
}

但是在canvas中,则要麻烦一些,麻烦的并不是无法翻转,而是坐标系的定位。

在Canvas中,如下代码可以实现资源的水平镜像翻转(假设 context 是Canvas的 2d 上下文):

context.scale(-1, 1);

或者使用 setTransform API直接矩阵变换:

context.setTransform(-1, 0, 0, 1, 0, 0);

然而,翻转虽然实现了,但是Canvas中元素定位就出了很大的问题。这是因为Canvas的坐标变换系和CSS不一样,因此,如果我们想实现居中翻转效果,需要在翻转之前将目标元素的中心点移动到变换轴上。

拿水平翻转距离,在 scale 之前先 translate 位移变换后的水平偏移,然后就能看到一直居中翻转的效果了。

语言苍白,拿图示意一下。

canvas默认的变化坐标系是左上角。

因此,如果水平 scale 为 1 , 0.5 , 0 , -0.5 , -1 时候的最终位置如下图示意:

在canvas上实现元素图片镜像翻转动画效果的方法

于是可以得到应当偏移的水平距离公式:

distance = (canvas.width – image.width * scale) / 2;

于是,最终镜像绘制图片的关键代码变成这样(假设水平缩放大小是 scale ):

// 坐标参考调整
context.translate((canvas.width - image.width * scale) / 2, 0);
context.scale(scale, 1);
context.drawImage(image, 0, 0);
// 坐标参考还原
context.setTransform(1, 0, 0, 1, 0, 0);

如何增加动画效果呢?

我们可以借助Tween.js , https://github.com/zhangxinxu/tween

里面有各种缓动算法,借助方便调用的 Math.animation() 方法,就能轻松实现我们想要的效果啦!

Math.animation(form, to, duration, easing, callback);

动画JS如下:

var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
// 动画进行
Math.animation(1, -1, 600, 'Quad.easeInOut', function (value, isEnding) {
    // 清除画布内容
    context.clearRect(0, 0, canvas.width, canvas.height);
    // 调整坐标
    context.translate((canvas.width - canvas.width * value) / 2, 0);
    // 调整缩放
    context.scale(value, 1);
    // 绘制此时图片
    context.drawImage(eleImg, 0, 0);
    // 坐标参考还原
    context.setTransform(1, 0, 0, 1, 0, 0);
});

三、结束语

又是一篇冷文,canvas这东西,玩的前端并不多,受众有限,不比流行技术。然,古语有云,不以善小而不为,希望以后有小伙伴搜索到相关问题的时候可以提供帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
css3实现信纸/同学录效果的示例代码
Dec 11 HTML / CSS
HTML5 Plus 实现手机APP拍照或相册选择图片上传功能
Jul 13 HTML / CSS
HTML5标签小集
Aug 02 HTML / CSS
html5的新增的标签和废除的标签简要概述
Feb 20 HTML / CSS
HTML5 虚拟键盘出现挡住输入框的解决办法
Feb 14 HTML / CSS
使用phonegap获取设备的一些信息方法
Mar 31 HTML / CSS
HTML5实现可缩放时钟代码
Aug 28 HTML / CSS
详解canvas多边形(蜘蛛图)的画法示例
Jan 29 HTML / CSS
Html5页面中的返回实现的方法
Feb 26 HTML / CSS
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
May 14 HTML / CSS
纯html+css实现打字效果
Aug 02 HTML / CSS
CSS 实现Chrome标签栏的技巧
Aug 04 HTML / CSS
HTML5 新表单类型示例代码
Mar 20 #HTML / CSS
浅谈基于Canvas的手绘风格图形库Rough.js
Mar 19 #HTML / CSS
基于HTML5 WebGL的3D机房的示例
Mar 16 #HTML / CSS
Html5 APP中监听返回事件处理的方法示例
Mar 15 #HTML / CSS
html5实现多图片预览上传及点击可拖拽控件
Mar 15 #HTML / CSS
微信html5页面调用第三方位置导航的示例
Mar 14 #HTML / CSS
微信端html5页面调用分享接口示例
Mar 14 #HTML / CSS
You might like
PHP中的str_repeat函数在JavaScript中的实现
2013/09/16 PHP
PHP连接MySQL的2种方法小结以及防止乱码
2014/03/11 PHP
php时间戳转换的示例
2014/03/31 PHP
thinkPHP实现基于ajax的评论回复功能
2018/06/22 PHP
网页中可关闭的漂浮窗口实现可自行调节
2013/08/20 Javascript
往光标所在位置插入值的js代码
2013/09/22 Javascript
使用jQuery的attr方法来修改onclick值
2014/07/07 Javascript
javascript实现的闭包简单实例
2015/07/17 Javascript
在javascript中使用com组件的简单实现方法
2016/08/17 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
jQuery实现页面滚动时智能浮动定位
2017/01/08 Javascript
js仿QQ邮箱收件人选择与搜索功能
2017/02/10 Javascript
JavaScript定时器setTimeout()和setInterval()详解
2017/08/18 Javascript
bootstrap-Treeview实现级联勾选
2017/11/23 Javascript
echarts实现地图定时切换散点与多图表级联联动详解
2018/08/07 Javascript
从vue源码解析Vue.set()和this.$set()
2018/08/30 Javascript
Node.js创建一个Express服务的方法详解
2020/01/06 Javascript
[05:00]第二届DOTA2亚洲邀请赛主赛事第三天比赛集锦.mp4
2017/04/04 DOTA
Python的动态重新封装的教程
2015/04/11 Python
Python字符串匹配算法KMP实例
2015/07/18 Python
Python基于ThreadingTCPServer创建多线程代理的方法示例
2018/01/11 Python
python如何压缩新文件到已有ZIP文件
2018/03/14 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
使用Python实现Wake On Lan远程开机功能
2020/01/22 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
董事长秘书岗位职责
2013/11/29 职场文书
关于旷工的检讨书
2014/02/02 职场文书
文案策划专业自荐信
2014/07/07 职场文书
医院反腐倡廉演讲稿
2014/09/16 职场文书
搞笑老公保证书
2015/02/26 职场文书
个性发展自我评价2015
2015/03/09 职场文书
2015年音乐教师个人工作总结
2015/05/20 职场文书
被告答辩状范文
2015/05/22 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python