小tips: 在canvas上实现元素图片镜像翻转动画效果

这篇文章发布于 2018年03月18日,星期日,00:08,归类于 Canvas相关。 阅读 29228 次, 今日 4 次 8 条评论

 

一、Canvas图片水平镜像翻转效果预览

如下MP4视频:

您可以狠狠的点击这里: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默认的变化坐标系是左上角。

因此,如果水平scale1, 0.5, 0, -0.5, -1时候的最终位置如下图示意:

缩放和居中需要的偏移

于是可以得到应当偏移的水平距离公式:

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.jshttps://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这东西,玩的前端并不多,受众有限,不比流行技术。然,古语有云,不以善小而不为,希望以后有小伙伴搜索到相关问题的时候可以提供帮助。

以上,感谢阅读!

(本篇完)

分享到:


发表评论(目前8 条评论)

  1. 东元马达说道:

    多谢,正有需要

  2. harmsworth说道:

    厉害,学习了

  3. 小丹说道:

    一直很喜欢 看你的网站里面有很多可以学到的内容,有想投入广告 不知道你的邮箱多少

  4. codepen说道:

    用了那多次transform: scale,今天才知道可以设负值来翻转,然后默默去翻了mdn文档。受教了,大神。

  5. 小媒体说道:

    Canvas目前用的场景逐步变多了,尤其在移动端,只是webgl有些低端机器不支持,挺头痛。

  6. 杰兰特说道:

    先过一遍,建个索引