画布驱动的背景图片

Eric Bidelman

以编程方式为背景图片添加动画效果

为背景图片添加动画效果的主要方式有两种:

  1. 使用 CSS 精灵更新 JS 中的 background-position
  2. .toDataURL() 小窍门。

如果您提前准备好图片,第一种方法可以有效运行,但是如果您的来源需要以编程方式生成(例如由 <canvas> 生成),该怎么办?第一种解决方法是在画布上使用 .toDataURL(),并将背景设置为生成的网址:

while(1) {
    var url = canvas.toDataURL('image/jpeg');
    el.style.background = 'url(' + url + ')';
}

这样做存在两个问题:

  1. data: 网址会导致生成的图片大小增加约 33% 的开销。
  2. 大量 DOM 操作 (el.style)。

这两种方法的效率都很低,对于始终丝滑流畅的 60fps 的 Web 应用而言,这是不可接受的。

使用 2D 画布作为背景

使用画布作为背景演示
演示

事实证明,WebKit 多年一直在使用一个非标准 API,该 API 可以将画布作为背景的来源。但很抱歉,此功能没有已发布的规范

首先,不为返回指定网址:

.bg {
    background: url(bg.png) no-repeat 50% 50%;
}

使用 -webkit-canvas(),将字符串标识符引用到画布上下文:

.canvas-bg {
    background: -webkit-canvas(animation) no-repeat 50% 50%;
}

接下来,我们需要使用特殊版本的 .getContext() 创建 2D 上下文:

var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);

来自 Dave Hyatt 的更多信息

动画

如演示所示,我们可以重复使用 requestAnimationFrame() 来驱动动画。这非常有用,因为当内容连接起来后,CSS 和画布元素之间的关联就会保留。您无需处理 DOM。

在 Chrome 中的演示没有添加动画效果?

Chrome 的当前稳定版(版本 23)包含 crbug.com/161699,这会阻止 requestAnimationFrame() 动画正确更新背景。此问题已在 Chrome 25(目前为 Canary 版)中修复。该演示在当前的 Safari 中应该也能正常运行。

性能优势

我们讨论的是画布。硬件加速动画现在可以完全播放(至少对于支持此功能的浏览器而言)。重申一下,无需从 JS 中骚扰 DOM

使用 webgl 作为背景

请稍候。这是不是表示我们可以使用 webgl 支持 CSS 背景?当然有!WebGL 只是画布的 3D 上下文。直接用“experimental-webgl”代替“2d”,就大功告成了。

var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);

下面是一个概念验证,其中包含一个使用顶点和 fragment 着色器绘制背景的 div:演示

其他方法

值得注意的是,Mozilla 已经有相当一段时间使用的是 -moz-element() (MDN)。这是 CSS 图片值和替换内容模块第 4 级规范的一部分,可让您创建由任意 HTML(视频、画布、DOM 内容等)生成的图片。不过,如果拥有对 DOM 快照图像的完整访问权限,会存在安全问题。这主要是其他浏览器尚未采用相应功能的原因。