在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选择器的研究(详解)
Sep 16 HTML / CSS
CSS3 clip-path 用法介绍详解
Mar 01 HTML / CSS
用CSS3来实现社交分享按钮
Nov 11 HTML / CSS
10分钟入门CSS3 Animation
Dec 25 HTML / CSS
浅谈HTML5新增及移除的元素
Jun 27 HTML / CSS
网页中的电话号码如何实现一键直呼效果_附示例
Mar 15 HTML / CSS
HTML5的hidden属性兼容老浏览器的方法
Apr 23 HTML / CSS
用HTML5 实现橡皮擦的涂抹效果的教程
May 11 HTML / CSS
详解html5 canvas 微信海报分享(个人爬坑)
Jan 12 HTML / CSS
详解Html5 监听拦截Android返回键方法
Apr 18 HTML / CSS
CSS 一行代码实现头像与国旗的融合
Oct 24 HTML / CSS
分享几个实用的CSS代码块
Jun 10 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 foreach 使用&(与运算符)引用赋值要注意的问题
2010/02/16 PHP
Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
2016/03/02 PHP
Laravel如何友好的修改.env配置文件详解
2017/06/07 PHP
Laravel实现通过blade模板引擎渲染视图
2019/10/25 PHP
javascript的函数
2007/01/31 Javascript
精解window.setTimeout()&window.setInterval()使用方式与参数传递问题!
2007/11/23 Javascript
JQuery切换显示的效果实例代码
2013/02/27 Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
2013/12/02 Javascript
使用jquery.qrcode生成彩色二维码实例
2014/08/08 Javascript
JavaScript中的异常捕捉介绍
2014/12/31 Javascript
jQuery中offset()方法用法实例
2015/01/16 Javascript
Jquery中offset()和position()的区别分析
2015/02/05 Javascript
javascript自定义in_array()函数实现方法
2015/08/03 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
js基于FileSaver.js 浏览器导出Excel文件的示例
2017/08/15 Javascript
AngularJS表单验证功能
2017/10/19 Javascript
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
jquery使用echarts实现有向图可视化功能示例
2019/11/25 jQuery
vue基于Echarts的拖拽数据可视化功能实现
2020/12/04 Vue.js
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
Python Xml文件添加字节属性的方法
2018/03/31 Python
django2用iframe标签完成网页内嵌播放b站视频功能
2018/06/20 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
Python selenium 加载并保存QQ群成员,去除其群主、管理员信息的示例代码
2020/05/28 Python
PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)的步骤详解
2020/11/02 Python
英国定做窗帘和纺织品面料一站式商店:Dekoria
2018/08/29 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
岗位职责的定义
2013/11/10 职场文书
工会换届选举方案
2014/05/21 职场文书
音乐节策划方案
2014/06/09 职场文书
七年级地理教学计划
2015/01/22 职场文书
求职自荐信该如何书写?
2019/06/24 职场文书
Ajax实现三级联动效果
2021/10/05 Javascript