在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教程(5):网页背景图片
Apr 02 HTML / CSS
CSS3五个技巧给你的网站带来出色的效果
Apr 02 HTML / CSS
结合CSS3的布局新特征谈谈常见布局方法
Jan 22 HTML / CSS
CSS3 :not()选择器实现最后一行li去除某种css样式
Oct 19 HTML / CSS
CSS3 Flex 弹性布局实例代码详解
Nov 01 HTML / CSS
纯css3实现思维导图样式示例
Nov 01 HTML / CSS
HTML5 与 XHTML2
Oct 17 HTML / CSS
html5 worker 实例(二) 图片变换效果
Jun 24 HTML / CSS
HTML5手机端弹出遮罩菜单特效代码
Jan 27 HTML / CSS
canvas画图被放大且模糊的解决方法
Aug 11 HTML / CSS
使用css样式设计一个简单的html登陆界面的实现
Mar 30 HTML / CSS
浅谈由position属性引申的css进阶讨论
May 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
两种php调用Java对象的方法
2006/10/09 PHP
优化使用mysql存储session的php代码
2008/01/10 PHP
PDO防注入原理分析以及注意事项
2015/02/25 PHP
使用正则去除php代码中的注释方法
2016/11/03 PHP
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
jQuery中校验时间格式的正则表达式小结
2013/09/22 Javascript
查找页面中所有类为test的结点的方法
2014/03/28 Javascript
javascript中判断json的方法总结
2015/08/27 Javascript
AngularJS身份验证的方法
2016/02/17 Javascript
Bootstrap和Java分页实例第一篇
2016/12/23 Javascript
微信小程序 图片上传实例详解
2017/05/05 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
React-Native中props具体使用详解
2017/09/04 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
2019/04/10 jQuery
Vue多选列表组件深入详解
2021/03/02 Vue.js
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python文件处理
2016/02/29 Python
Python用threading实现多线程详解
2017/02/03 Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
2017/09/18 Python
Python中用post、get方式提交数据的方法示例
2017/09/22 Python
在keras中model.fit_generator()和model.fit()的区别说明
2020/06/17 Python
Django URL参数Template反向解析
2020/11/24 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
HTML5实现移动端弹幕动画效果
2019/08/01 HTML / CSS
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
如何判断计算机可能已经中马
2013/03/22 面试题
顶撞老师检讨书
2014/02/07 职场文书
房地产开盘策划方案
2014/02/10 职场文书
选秀节目策划方案
2014/06/06 职场文书
思想纪律作风整顿剖析材料
2014/10/11 职场文书
三方股份合作协议书
2014/10/13 职场文书
群众路线党员个人整改措施
2014/10/27 职场文书
用人单位聘用意向书
2015/05/11 职场文书
预备党员党支部意见
2015/06/02 职场文书
会计入职心得体会
2016/01/22 职场文书