Web 帧动画解决方案 - WebGL实现透明视频动画

5,721 阅读4分钟

前言

作为前端同学,或多或少都会接到动画需求。目前动画效果越来越酷炫,动画的绘制难度也逐渐增大。

前段时间主要学习了 APNGLottieVideo 三种动画方案。其中 APNG、Lottie 篇主要分享如下:

在上述两篇文章中都各自讲述了 APNG、Lottie 的原理、优缺点等,今天要讲的主题是 Video 实现动画。也就是通过播放一段视频来实现动画。

Video

HTML 元素 用于在HTML或者XHTML文档中嵌入媒体播放器,用于支持文档内的视频播放。

笔者在一次需求中与设计同学讨论时,发现一段 AE 制作的动画,无损导出后的大小如下:

  • APNG 大小 27M
  • Video 仅有 400K

然而在网上查找资料,发现 Video 各种各样的坑,可以看下这篇复杂帧动画之移动端video采坑实现

除了常见的播放等问题,还有一个最大的问题就是,Video 没有 Alpha 通道,也就是如下效果所示,视频背景是黑乎乎的。

image-20210303134335118

然而我们平时的动画场景基本都是需要透明度的,所以这种方案夭折。继续查找资料发现,可以通过 WebGl 来绘制透明视频。

WebGl + Animation

WebGl 概念:

WebGL(Web图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点,该 API可以在 HTML5 canvas 元素中使用。 这种一致性使 API 可以利用用户设备提供的硬件图形加速。

再来回顾下动画的概念:

动画(英语:Animation)是一种通过定时拍摄一系列多个静止的固态 图像)以一定频率连续变化、运动(播放)的速度(如每秒16张)而导致肉眼的视觉残象产生的错觉,而误以为图画或物体(画面)活动的作品及其视频技术。

由于 WebGL 需要一定的入门才能理解代码,所以接下来只会讲下思路,具体代码细节可以实战时再去学习。所以遇到不懂的代码不要过于纠结,理解思路才是最重要的。

WebGl 实现透明视频绘制的主要思路为:

  • 解析 Video 视频播放过程的每一帧
  • 识别每一帧需要透明的区域,并设置为透明
  • 通过 WebGl 绘制处理后的每一帧
  • 以上过程重复至视频播放结束,快速绘制过程产生连续变化,为新的带有透明度的动画

WebGl 实现透明视频绘制

解析 Video 视频播放过程的每一帧和绘制每一帧其实都是由 WebGL 的 API 就可以轻松完成。所以重点是了解如何识别每一帧需要透明的区域,并设置为透明。

针对以下视频,最简单的方案就是识别下黑色,然后绘制成透明。但是如果动画也有黑色元素,那么就会误杀。所以这个方案初步不行。

image-20210303134335118

第二个方案就是需要设计同学导出左右对称视频 查看视频 如下:

image-20210303134311354

这个视频中是左右对称的。左面是纯白色的动画,右面是有色彩的也是我们所需要的动画。那我们的绘制思路就可以为:

image-20210304134053802

  1. 真正绘制的动画宽为原视频的 50%,也就是一半,高和视频一致
  2. 解析左侧像素点,白色就代表是动画,黑色就代表需要透明
  3. 解析右侧像素点的 rgb
  4. 绘制时色值变为 rgba,那么 a 的值就是左侧的白色 1 (该像素颜色不变)或是黑色 0(该像素颜色变为透明)
precision lowp float;
varying vec2 v_texCoord;
uniform sampler2D u_sampler;
void main(void) {
  	gl_FragColor = vec4( // vec4代表4维变量,因为rgba是4个值
        texture2D(u_sampler, v_texCoord).rgb, // 右侧的rgb
        texture2D(u_sampler, v_texCoord + vec2(-0.5, 0)).r // -0.5代表画布左侧,取值是rgb中的r值
   	);
}

上述 WebGl 代码就是透明度的核心代码,当然第一次接触 WebGl 的人肯定就懵了(我也是)。所以我们主要是理解思路即可,理解这个思路,完全可以用 canvas 实现同样的效果。

实现代码及效果可以直接看 Demo,代码不做过多讲解了。

本方案依赖视频自动播放,所以兼容性问题不是很好解决,适合 APP 内的一些场景(比如直播礼物等)。

总结

将之前的学习做了一个简单的总结

下面是每种方案的一些情况总结和对比。 image-20210304135454297

讲解不对的地方欢迎指正,多多探讨~

参考资料