干货 | React 中的 Canvas 动画

作者简介

 

掺水的酱油,携程软件技术专家,关注大前端及移动端相关技术。

移动端硬件性能越来越好的今天,页面的交互也越来越丰富,Web 体验在不断向原生应用靠拢,加入了越来越多的手势与动画。除了常见的 CSS 动画外,有时候我们还会使用到 Canvas 或者 SVG 进行动画内容表现。

由于 React 在平日的开发中依旧拥有不少使用者,分享一个在 React 开发中使用 Canvas 动画的方法及其性能优化。

一、动画的基本原理

人的眼睛对图像有短暂的记忆效应,当眼睛看到多张图片连续快速切换时,就会认为是一段连续播放的动画了,而一秒内切换多少张,便是所说的帧率(FPS),它也常被用作动画流畅度的重要指标。虽然帧率是越高越好,但一般达到30帧后,便基本可以觉得是流畅的。

日本动漫的手绘(EVA、进击的巨人等)、粘土动画或者 3D 渲染等不同创作方式都能制作动画,但原理都是一样的。

二、Web中的动画

当聊到 Web 的动画时,我们的第一反应可能是 CSS,通过 CSS 来实现各种各样的效果——位移、旋转、透明等等。其实,除了这些特效以外,Web 也有很多其他的动画手段,其中比较主要的载体便是 SVG、Canvas、WebGL。通过这些载体除了可以实现上述 CSS 的效果以外,还可以实现更复杂的内容(比如游戏动画)。

由于有些动画较为细腻且复杂,无法通过简单的位移或变形来实现(例如人物的行走、跳跃),我们便会使用到帧动画。“帧动画”是一种常见的动画形式,是将某时间轴拆分成若干个连续的关键帧,并在的每一帧上分解动画动作、绘制不同内容,使之连续播放变为动画。帧动画也被称为“序列帧动画”、“定格动画”、“逐帧动画”。

归结起来,也就是下面这张图片要表达的意思。

cd03d3f69415cb75c103a74cb5f50cff.gif

实现帧动画的手段

实现帧动画的手段也有很多种,比较常用的有下面三种:

GIF 图片

  • 优点:成本较低、使用方便

  • 缺点:GIF动画支持颜色少(最大256色)、Alpha 透明度支持差,图像锯齿毛边比较严重,灵活性较差

CSS

  • 优点:使用方便,支持所有图片种类(可以通过background-position, transform 属性以切换图片的方式实现),translate3d 属性也能充分使用 GPU

  • 缺点:实现较为复杂,多个动画间的同步可能会产生问题

JavaScript

利用 JavaScript 将内容绘制到 Canvas 等载体上,并通过实时计算来决定绘制的图像、位置、变形、透明度等等,也是本篇的主要介绍方法。

  • 优点:支持所有图片类型,可以实现复杂的动画控制

  • 缺点:实现较为复杂,需要使用到较多的 CPU 运算

当然,本篇还是着重介绍使用 JavaScript 的方式实现动画,进而迁移到 React。

三、使用 JavaScript 实现动画

如果计划使用 JavaScript 来进行动画的渲染,基本上都会选用一个渲染框架来将动画内容渲染,来简化我们的渲染操作、提高编码效率,当然也可以直接使用原生 API 来进行操作,不过这样会比较烦琐。

JavaScript 的渲染框架有很多,包括 Lottie, Pixijs, Threejs, Createjs, Konva 等等。这些框架本身都很成熟,而且也有针对不同的场景,可以根据业务特点来进行选择。因为本文并不牵涉复杂场景,这里选用比较简单的 Konva 来作为示例进行讲解,如果读者有兴趣,也可以去了解一下其他的框架。

下面我们通过一些代码片段来看下如何从一个基本的 Canvas 动画,逐步的迁移到 React 中,并融合进 react-dom 中。使用 Canvas 来实现动画的实现并不复杂,可以简单地用 4 个字来概括:定时重绘

3.1 定时

我们先来看下定时,JavaScript 中可以实现定时的手段有好几种,优先级排序上:requestAnimationFrame > setTimeout > setInterval,因此我们首选 requestAnimationFrame API。原因主要是在执行优先级上,这部分内容超出本文范围,有兴趣或者不太了解的读者可以自行查阅。

通过定时任务,就可以实现动画中最基本的“tick 机制”了。

function tick() {
    // 绘制动画内容至载体上
   
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值