在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无js实现的Android Logo(有简单动画)
Jan 21 HTML / CSS
用CSS3实现背景渐变的方法
Jul 14 HTML / CSS
CSS3的RGBA中关于整数和百分比值的转换
Aug 04 HTML / CSS
CSS3不透明度实例讲解
Apr 26 HTML / CSS
CSS3实现3D翻书效果
Jun 20 HTML / CSS
关于 HTML5 的七个传说小结
Apr 12 HTML / CSS
详解HTML5中rel属性的prefetch预加载功能使用
May 06 HTML / CSS
canvas绘图按照contain或者cover方式适配并居中显示
Feb 18 HTML / CSS
使用html5实现表格实现标题合并的实例代码
May 13 HTML / CSS
5分钟实现Canvas鼠标跟随动画背景
Nov 18 HTML / CSS
html5手机键盘弹出收起的处理
Jan 20 HTML / CSS
Css预编语言及区别详解
Apr 25 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
新浪SAE搭建PHP项目教程
2015/01/28 PHP
PHP异常处理Exception类
2015/12/11 PHP
Zend Framework动作控制器用法示例
2016/12/09 PHP
php基于PDO实现功能强大的MYSQL封装类实例
2017/02/27 PHP
PHP错误处理函数register_shutdown_function使用示例
2017/07/03 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
PHP切割汉字的常用方法实例总结
2019/04/27 PHP
firefo xml 读写实现js代码
2009/06/11 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
jQuery插件开发汇总
2016/05/15 Javascript
省市联动效果的简单实现代码(推荐)
2016/06/06 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
Bootstrap的popover(弹出框)2秒后定时消失的实现代码
2017/02/27 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
2017/05/02 Javascript
使用yeoman构建angular应用的方法
2017/08/14 Javascript
微信小程序获取手机号授权用户登录功能
2017/11/09 Javascript
Javascript获取某个月的天数
2018/05/30 Javascript
vue根据条件不同显示不同按钮的操作
2020/08/04 Javascript
解决vue+webpack项目接口跨域出现的问题
2020/08/10 Javascript
[00:57]林俊杰助阵DOTA2亚洲邀请赛
2015/01/28 DOTA
Python 命令行非阻塞输入的小例子
2013/09/27 Python
Python中的hypot()方法使用简介
2015/05/18 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
Python XML转Json之XML2Dict的使用方法
2019/01/15 Python
python简单贪吃蛇开发
2019/01/28 Python
简单了解python数组的基本操作
2019/11/26 Python
Python生成器常见问题及解决方案
2020/03/21 Python
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
商业活动邀请函
2014/02/04 职场文书
计算机网络及管理学专业求职信
2014/06/05 职场文书
责任书范本
2014/08/25 职场文书
迎七一演讲稿
2014/09/12 职场文书
行政处罚告知书
2015/07/01 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
html+css实现文字折叠特效实例
2021/06/02 HTML / CSS
使用goaccess分析nginx日志的详细方法
2021/07/09 Servers