程序化地为背景图片添加动画效果
用户以两种主要方式为背景图片添加动画效果:
- 使用 CSS 精灵在 JS 中更新
background-position
。 - 使用
.toDataURL()
的黑客攻击。
如果您已提前准备好图片,则第一种方法非常适用,但如果您的来源需要通过程序化方式生成(例如通过 <canvas>
),该怎么办?第 1 个问题的解决方案是在画布上使用 .toDataURL()
,并将背景设置为生成的网址:
while(1) {
var url = canvas.toDataURL('image/jpeg');
el.style.background = 'url(' + url + ')';
}
这存在两个问题:
data:
网址会使生成的图片增加约 33% 的大小开销。- 大量 DOM 触摸 (
el.style
)。
这两种方法都效率不高,对于始终流畅的 60fps 网站应用来说,是不可接受的。
使用 2D 画布作为背景
事实证明,WebKit 多年来一直有一个非标准 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 只是 Canvas 的 3D 上下文。只需将“experimental-webgl”替换为“2d”,即可解决问题。
var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);
以下概念验证包含一个 div,其背景使用顶点着色器和片段着色器绘制:演示
其他方法
值得注意的是,Mozilla 已经推出 -moz-element()
(MDN) 很长一段时间了。这属于 CSS 图片值和替换内容模块级别 4 规范的一部分,可让您创建由任意 HTML 生成的图片:视频、画布、DOM 内容等。不过,完全访问 DOM 的快照图片存在安全问题。这正是其他浏览器尚未采用该功能的主要原因。