在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折叠效果(3D效果)整理
Dec 30 HTML / CSS
CSS3中的@keyframes关键帧动画的选择器绑定
Jun 13 HTML / CSS
CSS实现雨滴动画效果的实例代码
Oct 08 HTML / CSS
使用CSS3制作版头动画效果
Dec 24 HTML / CSS
利用简洁的图片预加载组件提升html5移动页面的用户体验
Mar 11 HTML / CSS
html5中如何将图片的绝对路径转换成文件对象
Jan 11 HTML / CSS
关于HTML5的22个初级技巧(图文教程)
Jun 21 HTML / CSS
使用html5+css3来实现slider切换效果告别javascript+css
Jan 08 HTML / CSS
HTML5、Select下拉框右边加图标的实现代码(增进用户体验)
Oct 16 HTML / CSS
HTML5 Canvas实现360度全景图的示例代码
Jan 29 HTML / CSS
浅谈Html5页面打开app的一些思考
Mar 30 HTML / CSS
详解如何使用rem或viewport进行移动端适配
Aug 14 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
MYSQL环境变量设置方法
2007/01/15 PHP
php AJAX实例根据邮编自动完成地址信息
2008/11/23 PHP
php中日期加减法运算实现代码
2011/12/08 PHP
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
初学Javascript的一些总结
2008/11/03 Javascript
JavaScript 字符串处理函数使用小结
2010/12/02 Javascript
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
js 3种归并操作的实例代码
2013/10/30 Javascript
js实现表格字段排序
2014/02/19 Javascript
究竟什么是Node.js?Node.js有什么好处?
2015/05/29 Javascript
AngularJS学习笔记之ng-options指令
2015/06/16 Javascript
nodejs加密Crypto的实例代码
2016/07/07 NodeJs
jQuery点击头像上传并预览图片
2017/02/23 Javascript
jqgrid实现简单的单行编辑功能
2017/09/30 Javascript
angularjs实现猜大小功能
2017/10/23 Javascript
基于 flexible 的 Vue 组件:Toast -- 显示框效果
2017/12/26 Javascript
JS引用传递与值传递的区别与用法分析
2018/06/01 Javascript
jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析
2019/03/06 jQuery
nodejs使用Sequelize框架操作数据库的实现
2020/10/21 NodeJs
Python模拟登录12306的方法
2014/12/30 Python
python使用正则表达式提取网页URL的方法
2015/05/26 Python
Python基于matplotlib实现绘制三维图形功能示例
2018/01/18 Python
对pandas进行数据预处理的实例讲解
2018/04/20 Python
Mansur Gavriel官网:纽约市的一个设计品牌
2019/05/02 全球购物
eBay爱尔兰站:eBay.ie
2019/08/09 全球购物
将时尚融入珠宝:Adornmonde
2019/10/17 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
应届护士推荐信
2013/11/16 职场文书
上班早退检讨书
2014/01/09 职场文书
销售业务员岗位职责
2014/01/29 职场文书
大学生素质拓展活动方案
2014/02/11 职场文书
入学申请自荐信范文
2014/02/26 职场文书
经典法律座右铭(50句)
2019/08/15 职场文书
MySQL主从切换的超详细步骤
2022/06/28 MySQL