Firefox CSS 动画平滑(子像素平滑) [英] Firefox CSS Animation Smoothing (sub-pixel smoothing)

查看:34
本文介绍了Firefox CSS 动画平滑(子像素平滑)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 CSS 关键帧动画,让元素看起来好像是随意/缓慢地漂浮着一点.它嵌套在parents中,一个使用translateX()缓慢左右移动,一个使用translateY()缓慢独立上下移动.

Chrome 和 Safari 完美地呈现了这一点,使其具有逐渐摇摆的运动.它平滑动画(也许使用子像素平滑?),使一切看起来非常平滑.然而,Firefox 会逐个像素地对其进行动画处理,因此您可以看到它在每个像素处跳跃,而不是平滑地摇晃.

在Chrome和FireFox中查看JSFiddle查看区别:http://jsfiddle.net/gonygdfz/6/

有什么办法可以让 FireFox 平滑渲染而不是让它逐个像素地跳跃?这在实际应用中非常明显.

标记:

<div id="move-x"><div id="move-y"><div id="孩子"></div>

CSS:

#parent {宽度:400px;高度:326px;背景颜色:黄色;背景:url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png)顶部中心重复;}#孩子 {位置:绝对;顶部:75px;左:150px;宽度:100px;高度:100px;背景颜色:黑色;动画:range-y 10s 无限轻松;}#move-x {动画:range-x 10s 无限轻松;-webkit-animation: range-x 10s 无限轻松;}#move-y {动画:range-y 15s 无限轻松;-webkit-animation: range-y 15s 无限轻松;}@关键帧范围-x {0% {变换:translateX(0);}30%{变换:translateX(-8px);}50%{变换:translateX(1px);}65%{变换:translateX(6px);}80%{变换:translateX(0px);}89% {变换:translateX(-3px);}100% {变换:translateX(0);}}@keyframes 范围-y {0% {变换:translateY(0);}20%{变换:translateY(13px);}35%{变换:translateY(-1px);}70%{变换:translateY(-14px);}90%{变换:translateY(2px);}100% {变换:translateY(0);}}@-webkit-keyframes 范围-x {0% {变换:translateX(0);}30%{变换:translateX(-8px);}50%{变换:translateX(1px);}65%{变换:translateX(6px);}80%{变换:translateX(0px);}89% {变换:translateX(-3px);}100% {变换:translateX(0);}}@-webkit-keyframes range-y {0% {变换:translateY(0);}20%{变换:translateY(13px);}35%{变换:translateY(-1px);}70%{变换:translateY(-14px);}90%{变换:translateY(2px);}100% {变换:translateY(0);}}

解决方案

每个浏览器的渲染引擎明显不同.Firefox 没有对 CSS 动画实现抗锯齿效果.这本身并不会使它变得更好或更糟,它只取决于您正在制作动画的内容.例如,线性过渡在 Chrome 中可能会出现令人不快的模糊.

看来您想要实现的是具有抗锯齿/子像素平滑过渡.我们无法改变引擎渲染的方式,但我们可以操纵动画,让最终用户看起来更柔和.


一切都没有丢失

我已经修改了您的答案,并在您的原始答案旁边呈现了一个更流畅的版本.在 Firefox 中查看时,这应该看起来更柔和.

点击比较

用于此效果的技术:

  • 线性过渡而不是轻松.
  • 动画对象上的框阴影.(软化的边缘有助于产生假 AA 效果).
  • 旋转对象.添加最小的旋转有助于更好地利用渲染引擎.

CSS

#parent {宽度:50%;向左飘浮;高度:326px;背景颜色:黄色;背景:url(http://paint.net.amihotornot.com.au/Features/Effects/Plugins/Render/Grid_CheckerBoard_Maker/Grid_CheckerBoard_Maker.Paint.NET.001.png)顶部中心重复;}#孩子 {位置:绝对;顶部:75px;左:150px;宽度:100px;高度:100px;背景颜色:黑色;box-shadow:0 0 1px rgba(0,0,0,0.7);动画:range-y 10s 无限线性;-webkit-animation: range-y 10s 无限线性;}#move-x {动画:range-x 10s 无限线性;-webkit-animation: range-x 10s 无限线性;}#move-y {动画:range-y 15s 无限线性;-webkit-animation: range-y 15s 无限线性;}@关键帧范围-x {0% {变换:translateX(0);}30% {transform: translateX(-8px)rotate(0.02deg);}50% {变换:translateX(1px)rotate(0deg);}65% {变换:translateX(6px)rotate(0.02deg);}80% {变换:translateX(0px)rotate(0deg);}89% {transform: translateX(-3px)rotate(0.02deg);}100% {变换:translateX(0)rotate(0deg);}}@keyframes 范围-y {0% {变换: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 范围-x {0% {变换:translateX(0);}30% {transform: translateX(-8px)rotate(0.02deg);}50% {变换:translateX(1px)rotate(0deg);}65% {变换:translateX(6px)rotate(0.02deg);}80% {变换:translateX(0px)rotate(0deg);}89% {transform: translateX(-3px)rotate(0.02deg);}100% {变换:translateX(0)rotate(0deg);}}@-webkit-keyframes range-y {0% {变换: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);}}

最后一句话

您仍然可以稍微调整效果以满足您的要求.它并不完美,但我希望它有助于柔化您实际动画的最终效果.

I'm creating a CSS keyframe animation to have an element appear as if it is casually/slowly floating around a bit. It's nested in parents, one which uses translateX() to slowly move it left and right, and one which uses translateY() to slowly and independently move it up and down.

Chrome and Safari render this perfectly, giving it a gradual swaying movement. It smooths the animation (perhaps using sub-pixel smoothing?) so that everything appears very smooth. Firefox however, animates it pixel by pixel, so rather than smoothly swaying about, you can see it jump at every pixel.

View the JSFiddle in Chrome and FireFox to view the difference: http://jsfiddle.net/gonygdfz/6/

Is there any way to make FireFox render this smoothly rather than having it jumping pixel by pixel? It's extremely noticeable in the actual application for this.

The Markup:

<div id="parent">
    <div id="move-x">
        <div id="move-y">
            <div id="child"></div>
        </div>
    </div>
</div>

The 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); 
  }
}

解决方案

The rendering engines for each browser is obviously different. Firefox does not implement an anti-aliasing effect on CSS animations. This does not inherently make it better or worse, it just depends on what you are animating. Linear transitions can appear undesirably blurred in Chrome for example.

It appears what you would like to achieve is to have an anti-aliased/sub-pixel smoothed transitions. We can't change the way the engine renders but we can manipulate the animation to appear softer to the end user.


ALL IS NOT LOST

I have modified your answer and rendered a smoother version next to your original. This should appear softer when viewed in Firefox.

CLICK FOR COMPARISON

Techniques used for this effect:

  • Linear transitions instead of ease.
  • Box-shadow on animated object. (Softened edge helps create fake AA effect).
  • Rotate object. Adding the smallest rotate helps to better utilised the rendering engine.

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);}
}

FINAL WORD

You can still tweak the effects a little either way to fit your requirements. It's not perfect but I hope it helps soften the end effect for your actual animation.

这篇关于Firefox CSS 动画平滑(子像素平滑)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆