Firefox CSS Animation Smoothing(亚像素平滑)
Posted
技术标签:
【中文标题】Firefox CSS Animation Smoothing(亚像素平滑)【英文标题】:Firefox CSS Animation Smoothing (sub-pixel smoothing) 【发布时间】:2015-03-09 00:42:16 【问题描述】:我正在创建一个 CSS 关键帧动画,让一个元素看起来好像是随意/缓慢地浮动一点。它嵌套在双亲中,一个使用 translateX() 缓慢地左右移动,一个使用 translateY() 缓慢独立地上下移动。
Chrome 和 Safari 完美地呈现了这一点,使其具有逐渐摇摆的运动。它使动画平滑(也许使用亚像素平滑?),使一切看起来都非常平滑。然而,Firefox 会逐个像素地对其进行动画处理,因此您可以看到它在每个像素处跳跃,而不是平滑地摇摆。
在 Chrome 和 FireFox 中查看 JSFiddle 以查看差异:http://jsfiddle.net/gonygdfz/6/
有没有什么方法可以让 FireFox 平滑渲染,而不是让它逐个像素地跳跃?这在实际应用中非常明显。
标记:
<div id="parent">
<div id="move-x">
<div id="move-y">
<div id="child"></div>
</div>
</div>
</div>
CSS:
#parent
width: 400px;
height: 326px;
background-color: yellow;
background: url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png) top center repeat;
#child
position: absolute;
top: 75px;
left: 150px;
width: 100px;
height: 100px;
background-color: black;
animation: range-y 10s infinite ease;
#move-x
animation: range-x 10s infinite ease;
-webkit-animation: range-x 10s infinite ease;
#move-y
animation: range-y 15s infinite ease;
-webkit-animation: range-y 15s infinite ease;
@keyframes range-x
0%
transform: translateX(0);
30%
transform: translateX(-8px);
50%
transform: translateX(1px);
65%
transform: translateX(6px);
80%
transform: translateX(0px);
89%
transform: translateX(-3px);
100%
transform: translateX(0);
@keyframes range-y
0%
transform: translateY(0);
20%
transform: translateY(13px);
35%
transform: translateY(-1px);
70%
transform: translateY(-14px);
90%
transform: translateY(2px);
100%
transform: translateY(0);
@-webkit-keyframes range-x
0%
transform: translateX(0);
30%
transform: translateX(-8px);
50%
transform: translateX(1px);
65%
transform: translateX(6px);
80%
transform: translateX(0px);
89%
transform: translateX(-3px);
100%
transform: translateX(0);
@-webkit-keyframes range-y
0%
transform: translateY(0);
20%
transform: translateY(13px);
35%
transform: translateY(-1px);
70%
transform: translateY(-14px);
90%
transform: translateY(2px);
100%
transform: translateY(0);
【问题讨论】:
虽然这不能解决您的亚像素平滑问题,但您可以使用transition
属性来帮助平滑定位。 transition: all 2s ease 0s;
【参考方案1】:
每个浏览器的渲染引擎明显不同。 Firefox 没有对 CSS 动画实现抗锯齿效果。这本身并不会使它变得更好或更糟,它仅取决于您制作动画的内容。例如,在 Chrome 中,线性过渡可能会出现令人不快的模糊。
看来您想要实现的是抗锯齿/亚像素平滑过渡。我们无法更改引擎的渲染方式,但我们可以操纵动画让最终用户看起来更柔和。
一切都不会丢失
我已经修改了您的答案,并在您的原始答案旁边呈现了一个更流畅的版本。在 Firefox 中查看时,它应该看起来更柔和。
CLICK FOR COMPARISON
用于此效果的技术:
线性过渡而不是缓动。 动画对象上的盒子阴影。 (软化边缘有助于创建假 AA 效果)。 旋转对象。添加最小旋转有助于更好地利用渲染引擎。CSS
#parent
width: 50%;
float:left;
height: 326px;
background-color: yellow;
background: url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png) top center repeat;
#child
position: absolute;
top: 75px;
left: 150px;
width: 100px;
height: 100px;
background-color: black;
box-shadow:0 0 1px rgba(0,0,0,0.7);
animation: range-y 10s infinite linear;
-webkit-animation: range-y 10s infinite linear;
#move-x
animation: range-x 10s infinite linear;
-webkit-animation: range-x 10s infinite linear;
#move-y
animation: range-y 15s infinite linear;
-webkit-animation: range-y 15s infinite linear;
@keyframes range-x
0% transform: translateX(0);
30% transform: translateX(-8px) rotate(0.02deg);
50% transform: translateX(1px) rotate(0deg);
65% transform: translateX(6px) rotate(0.02deg);
80% transform: translateX(0px) rotate(0deg);
89% transform: translateX(-3px) rotate(0.02deg);
100% transform: translateX(0) rotate(0deg);
@keyframes range-y
0% transform: translateY(0);
20% transform: translateY(13px) rotate(0.02deg);
35% transform: translateY(-1px) rotate(0deg);
70% transform: translateY(-14px) rotate(0.02deg);
90% transform: translateY(2px) rotate(0deg);
100% transform: translateY(0) rotate(0.02deg);
@-webkit-keyframes range-x
0% transform: translateX(0);
30% transform: translateX(-8px) rotate(0.02deg);
50% transform: translateX(1px) rotate(0deg);
65% transform: translateX(6px) rotate(0.02deg);
80% transform: translateX(0px) rotate(0deg);
89% transform: translateX(-3px) rotate(0.02deg);
100% transform: translateX(0) rotate(0deg);
@-webkit-keyframes range-y
0% transform: translateY(0);
20% transform: translateY(13px) rotate(0.02deg);
35% transform: translateY(-1px) rotate(0deg);
70% transform: translateY(-14px) rotate(0.02deg);
90% transform: translateY(2px) rotate(0deg);
100% transform: translateY(0) rotate(0.02deg);
最后一句话
您仍然可以稍微调整效果以满足您的要求。 它并不完美,但我希望它有助于软化您实际动画的最终效果。
【讨论】:
它确实变软了,但对我来说,盒子的形状似乎发生了变化。随着盒子向下移动,它的高度变小。当它向侧面移动时,它的宽度似乎发生了变化。 你只是从here复制了rotate(0.002deg)
,并没有注明出处。
@ThePragmatick 至少可以说是一个疯狂的假设。我已经使用这种技术几年了。这是否是我最初从那里学到的,我不能说,那是很久以前的事了。然而,是我花了两个小时试图为操作提出一个工作演示,没有其他人愿意提供帮助。
太棒了!那成功了。令人惊讶的是,在我的实际实现中,我实际上有第三个外部容器进行旋转。我把它拿出来用于演示目的。分别旋转 x 和 y 容器并不能解决问题,但是向单个 x 和 y 容器添加旋转肯定可以解决问题。谢谢!
添加 rotate(0.05deg) 挽救了我的生命,以防止动态缩放的精灵动画跳跃。【参考方案2】:
对变换使用少量旋转。这迫使 Firefox 避免优化并在每一帧上重新采样图像。
@keyframes optimized
0%
transform: translateX(0%);
100%
transform: translateX(200px);
@keyframes subpixel
0%
transform: translateX(0%) rotate(0.1deg);
100%
transform: translateX(200px) rotate(0.1deg);
div
width:5px;
height:50px;
background-color: red;
animation-duration:30s;
animation-iteration-count: infinite;
animation-direction:alternate;
animation-timing-function:linear;
.optimized
animation-name: optimized;
margin-bottom:1px;
.subpixel
animation-name: subpixel;
<div class="optimized">
</div>
<div class="subpixel">
</div>
【讨论】:
效果很好。以上是关于Firefox CSS Animation Smoothing(亚像素平滑)的主要内容,如果未能解决你的问题,请参考以下文章
CSS3 TransformsTransitions和Animation属性总结