在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轻松实现清新 Loading 效果的简单实例
Jun 06 HTML / CSS
用CSS3实现瀑布流布局的示例代码
Nov 10 HTML / CSS
CSS3移动端vw+rem不依赖JS实现响应式布局的方法
Jan 23 HTML / CSS
详解CSS3:overflow属性
Nov 17 HTML / CSS
websocket+sockjs+stompjs详解及实例代码
Nov 30 HTML / CSS
一张图片能隐含千言万语之隐藏你的程序代码
Dec 13 HTML / CSS
HTML5之WebGL 3D概述(上)—WebGL原生开发开启网页3D渲染新时代
Jan 31 HTML / CSS
HTML5 中新的全局属性(整理)
Jul 31 HTML / CSS
HTML5 自动聚焦(autofocus)属性使用介绍
Aug 07 HTML / CSS
html5教程画矩形代码分享
Dec 04 HTML / CSS
HTML5添加禁止缩放功能
Nov 03 HTML / CSS
做一个能自适应高度的textarea的示例代码
Sep 06 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+JS三级菜单联动菜单实现方法
2016/02/24 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
php curl中gzip的压缩性能测试实例分析
2016/11/08 PHP
PHP中串行化用法示例
2016/11/16 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
PHP+jQuery实现双击修改table表格功能示例
2019/02/21 PHP
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
js压缩工具 yuicompressor 使用教程
2010/03/31 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
2014/09/22 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
JavaScript中ES6 Babel正确安装过程
2016/07/18 Javascript
canvas时钟效果
2017/02/16 Javascript
利用imgareaselect辅助后台实现图片上传裁剪
2017/03/02 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
ES6解构赋值实例详解
2017/10/31 Javascript
基于angular6.0实现的一个组件懒加载功能示例
2018/04/12 Javascript
layui table 获取分页 limit的方法
2019/09/20 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
Python中的探索性数据分析(功能式)
2017/12/22 Python
python破解bilibili滑动验证码登录功能
2019/09/11 Python
Pycharm安装并配置jupyter notebook的实现
2020/05/18 Python
Keras使用ImageNet上预训练的模型方式
2020/05/23 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
2020/08/17 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
Banana Republic欧盟:美国都市简约风格的代表品牌
2018/05/09 全球购物
成人大专自我鉴定范文
2013/10/19 职场文书
测试工程师岗位职责
2013/11/28 职场文书
学校安全教育制度
2014/01/31 职场文书
运动会闭幕式解说词
2014/02/21 职场文书
暑期培训随笔感言
2014/03/10 职场文书
小学教师读书活动总结
2014/07/08 职场文书
写字楼租赁意向书
2014/07/30 职场文书
五四演讲稿范文
2014/09/03 职场文书
幼儿园安全教育月活动总结
2015/05/08 职场文书
病假条格式范文
2015/08/17 职场文书