在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 简写animation
May 10 HTML / CSS
移动Web—CSS为Retina屏幕替换更高质量的图片
Dec 24 HTML / CSS
纯css3实现的动画按钮的实例教程
Nov 17 HTML / CSS
CSS3中使用RGBA设置透明度的示例
Aug 04 HTML / CSS
纯CSS3代码实现文字描边
Apr 25 HTML / CSS
详解CSS3弹性伸缩盒
Sep 21 HTML / CSS
HTML5中Canvas与SVG的画图原理比较
Jan 16 HTML / CSS
有关HTML5 Video对象的ontimeupdate事件(Chrome上无效)的问题
Jul 19 HTML / CSS
html5 利用重力感应实现摇一摇换颜色可用来做抽奖等等
May 07 HTML / CSS
实例讲解利用HTML5 Canvas API操作图形旋转的方法
Mar 22 HTML / CSS
html5 初试 indexedDB(推荐)
Jul 21 HTML / CSS
html网页引入svg图片的4种方式
Aug 05 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书写安全的脚本代码
2012/02/05 PHP
PHP.ini中配置屏蔽错误信息显示和保存错误日志的例子
2014/05/12 PHP
PHP反向代理类代码
2014/08/15 PHP
PHP不使用递归的无限级分类简单实例
2016/11/05 PHP
PHP两种实现无级递归分类的方法
2017/03/02 PHP
通过修改referer下载文件的方法
2008/05/11 Javascript
javascript multibox 全选
2009/03/22 Javascript
javascript OFFICE控件测试代码
2009/12/08 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
jquery控制display属性为none或block
2014/03/31 Javascript
JavaScript设计模式之工厂方法模式介绍
2014/12/28 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
2015/05/01 Javascript
jquery实现向下滑出的二级导航下滑菜单效果
2015/08/25 Javascript
js友好的时间返回函数
2016/08/24 Javascript
微信小程序 window_x64环境搭建
2016/09/30 Javascript
javascript实现右下角广告框效果
2017/02/01 Javascript
vue下的@change事件的实现
2019/10/25 Javascript
Node使用Nodemailer发送邮件的方法实现
2020/02/24 Javascript
Python中的getopt函数使用详解
2015/07/28 Python
浅谈五大Python Web框架
2017/03/20 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
python opencv旋转图像(保持图像不被裁减)
2018/07/26 Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
2018/10/14 Python
对django中render()与render_to_response()的区别详解
2018/10/16 Python
Python将文字转成语音并读出来的实例详解
2019/07/15 Python
python中从for循环延申到推导式的具体使用
2019/11/29 Python
很酷的HTML5电子书翻页动画特效
2016/02/25 HTML / CSS
详解html5 postMessage解决跨域通信的问题
2018/08/17 HTML / CSS
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
英文商务邀请信
2014/01/22 职场文书
扬尘污染防治方案
2014/06/15 职场文书
医药公司采购员岗位职责
2015/04/03 职场文书
科级干部培训心得体会
2016/01/06 职场文书
MySQL Threads_running飙升与慢查询的相关问题解决
2021/05/08 MySQL
使用redis生成唯一编号及原理示例详解
2021/09/15 Redis