在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实现表单验证效果(非常不错)
Jan 18 HTML / CSS
CSS3属性background-size使用指南
Dec 09 HTML / CSS
使用CSS3 制作一个material-design 风格登录界面实例
Dec 12 HTML / CSS
CSS3实现div从下往上滑入滑出效果示例
Apr 28 HTML / CSS
HTML5之SVG 2D入门13—svg对决canvas及长处和适用场景分析
Jan 30 HTML / CSS
基于IE10/HTML5 开发
Apr 22 HTML / CSS
整理HTML5移动端开发的常用触摸事件
Apr 15 HTML / CSS
HTML5之消息通知的使用(Web Notification)
Oct 30 HTML / CSS
Html5与App的通讯方式详解
Oct 24 HTML / CSS
浅谈Html5页面打开app的一些思考
Mar 30 HTML / CSS
解析CSS 提取图片主题色功能(小技巧)
May 12 HTML / CSS
详解盒子端CSS动画性能提升
May 24 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
对squid中refresh_pattern的一些理解和建议
2009/04/17 PHP
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
解析将多维数组转换为支持curl提交的一维数组格式
2013/07/08 PHP
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
Firefox outerHTML实现代码
2009/06/04 Javascript
JavaScript 自动完成脚本整理(33个)
2009/10/20 Javascript
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
2014/05/19 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
2017/01/10 Javascript
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
2019/09/18 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
jQuery实现鼠标拖动图片功能
2021/03/04 jQuery
Python3 入门教程 简单但比较不错
2009/11/29 Python
Python中subprocess模块用法实例详解
2015/05/20 Python
简单上手Python中装饰器的使用
2015/07/12 Python
Python 常用的安装Module方式汇总
2017/05/06 Python
Flask框架钩子函数功能与用法分析
2019/08/02 Python
Windows10下 python3.7 安装 facenet的教程
2019/09/10 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
幼师专业毕业生自荐信
2013/09/29 职场文书
工作时间上网检讨书
2014/02/03 职场文书
关于环保的建议书400字
2014/03/12 职场文书
《去年的树》教学反思
2014/04/11 职场文书
四风自我剖析材料思想汇报
2014/10/01 职场文书
给老师的一封感谢信
2015/01/20 职场文书
党内外群众意见范文
2015/06/02 职场文书
导游词之包公祠
2019/11/25 职场文书
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript