在过去的一周里,我一直在帮助一个朋友在浏览器中试验基于 SVG 的精灵表。我们想提出一个理想的工作流程来在浏览器中准备、发布和运行高质量的动画图形。因此,理想情况下,拥有适用于小型智能手机屏幕、平板电脑、视网膜显示器和桌面浏览器的单一动画数据源。
理论上,(基于矢量的)SVG 应该是理想的,但由于 SVG 通常不常用 - 我们决定对其进行测试。这个想法不是使用 SMIL SVG(因此没有基于 SVG 的动画),而是创建一个动画精灵表(就像您通常使用光栅数据 PNG/JPG 一样),而是使用纯矢量(即 SVG)来执行此操作。它有点大,但如果它可以工作 - 它甚至可以使用更优化的东西。
再加上逐帧矢量动画可以为我们的工作流程做很多事情——它允许我们使用 Flash 编辑器来制作动画,然后将它们导出到 SVG 精灵表。
无论如何,结果出奇地好,但在某些方面也失败了(请注意,出于测试目的,我们只使用基于 Webkit 的浏览器,即 Safari、Chrome、iOS 上的移动 Safari 和 Android ICS)。
在 CSS 中,为这样的精灵表触发硬件加速非常容易(至少在具有关键帧和步骤的现代浏览器中)——你只需这样做:
background-image: url(my.svg);
-webkit-animation: walk 1s steps(12, end) infinite;
调用此处显示的基于关键帧的动画:
@-webkit-keyframes walk {
from { -webkit-transform: translate3d(0, 0, 0); }
to { -webkit-transform: translate3d(-100%, 0, 0); }
}
在哪里使用 translate3d 应该让 GPU 启动,整个事情应该在 iOS 移动 Safari 和 Android ICS 浏览器中进行硬件加速。
考虑到它是一种蛮力技术和相当大的矢量动画(测试为 600x600px),这足以令人惊讶 - 整个事情都飞了。但它并不完美 - 它在起飞前会在 Safari 中闪烁。而且在 ICS 浏览器中它一直在闪烁,所以它不是真正可用的。
所以我们尝试了常用的技巧来消除闪烁,例如:
-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
但这没有用。因此,我们尝试在内存中动态光栅化 SVG,并将其用作纹理-webkit-transform: scale3d(1, 1, 0)但这对以太没有帮助。
最后,我们只是用相同大小的渲染出来的 PNG/JPG 精灵表替换了 SVG,认为复杂的矢量对浏览器来说太多了 - 但你猜怎么着?它是同样的问题 - 所以它根本不是 SVG 渲染 -它是一个浏览器绘图问题。进一步的证明是,如果我们将动画减慢到 1FPS - 闪烁仍然存在。
图像对于 GPU 来说太大了吗?我们是否已达到您能够在浏览器(尤其是移动设备)中轻松绘制/动画的性能极限?
我真的很感激关于如何潜在地摆脱闪烁的想法/黑客(特别是因为它的表现如此之快)。它只是一种有前途的技术——适应不同屏幕尺寸的高性能浏览器动画——HTML5 圣杯;)
通过一些优化,例如
<svg preserveAspectRatio="xMinYMax slice" viewBox="0 0 600 50">
还有一些 CSS 魔法,我们能够让 SVG 完美地适应它的容器,并从单个 CSS 类改变它的大小。它真的会创造奇迹 - 但可惜闪烁。
无论如何 - 请在此处阅读更多相关信息,您也可以尝试一下。