如何更流畅地动画元素内背景渐变的旋转?

Yod*_*oda 1 html css animation

我有一个按钮,我想通过旋转它来为其背景设置动画:

.gradient-button {
  animation: rotate-gradient 1s infinite;
  background-image: linear-gradient(0deg, red, yellow, green);
}

@keyframes rotate-gradient {
  0% {
    background-image: linear-gradient(0deg, red, yellow, green);
  }
  /* Adding a step in the middle */
  20% {
    background-image: linear-gradient(60deg, red, yellow, green);
  }
  40% {
    background-image: linear-gradient(120deg, red, yellow, green);
  }
  60% {
    background-image: linear-gradient(180deg, red, yellow, green);
  }
  80% {
    background-image: linear-gradient(240deg, red, yellow, green);
  }
  100% {
    background-image: linear-gradient(300deg, red, yellow, green);
  }
}
Run Code Online (Sandbox Code Playgroud)
<button id="fill" class="gradient-button">Fill Form</button>
Run Code Online (Sandbox Code Playgroud)

但只有6步,动画不流畅,手动添加24帧适得其反。

或者我尝试了 JS:

$(document).ready(function () {
    AnimateRotate(360);
});


function AnimateRotate(d){
    var elem = $("#mybutton");

    $({deg: 0}).animate({deg: d}, {
        duration: 2000,
        step: function(now){
            elem.css({
                 "background-image":"linear-gradient("+now+"deg, red, yellow, green);"
            });
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

但这没有任何作用。问:如何让这个动画流畅?运行代码: https: //codepen.io/anon/pen/OaojNP

Chr*_* W. 11

如果是我,我可能会采取不同的路线,因为线性渐变将很难在不逐步完成每个属性更改的情况下实现平滑的关键帧动画。相反,作为替代方法,也许对伪元素进行转换可以给出相同的期望结果?

像这样;

.gradient-button {
  position: relative;
  overflow: hidden;
  background-color: transparent;
}

.gradient-button:after {
  content: '';
  display: block;
  z-index: -1;
  position: absolute;
  top: -2rem; right: 0; bottom: -2rem; left: 0;
  background-image: linear-gradient(red, yellow, green);
  animation: rotate-gradient linear 1s infinite;
}

@keyframes rotate-gradient {
  to { transform: rotate(360deg) }
}
Run Code Online (Sandbox Code Playgroud)
<button id="fill" class="gradient-button">Fill Form</button>
Run Code Online (Sandbox Code Playgroud)


And*_*hiu 6

background-image是不可动画的。您可以添加一个绝对定位(伪)元素并使用变换来旋转它,只要您隐藏溢出并确保限制永远不可见。

但如果你真的想要一个旋转背景(因为它很酷,而且你可以),你可以使用 as<svg>背景和 SMIL 动画来旋转渐变方向:

<svg width="240" height="60" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <linearGradient id="Gradient" x1="0" x2="0" y1="0" y2="1">
        <animate attributeName="x1" values="0;0;1;1;0" keyTimes="0;.25;.5;.75;1" dur="1s" repeatCount="indefinite" />
        <animate attributeName="y1" values="0;1;1;0;0" keyTimes="0;.25;.5;.75;1" dur="1s" repeatCount="indefinite" />
        <animate attributeName="x2" values="1;1;0;0;1" keyTimes="0;.25;.5;.75;1" dur="1s" repeatCount="indefinite" />
        <animate attributeName="y2" values="1;0;0;1;1" keyTimes="0;.25;.5;.75;1" dur="1s" repeatCount="indefinite" />
        <stop offset="0%" stop-color="red"/>
        <stop offset="50%" stop-color="yellow"/>
        <stop offset="100%" stop-color="green"/>
      </linearGradient>
  </defs>
  <rect x="0" y="-90" width="240" height="240" fill="url(#Gradient)"/>
  
</svg>
Run Code Online (Sandbox Code Playgroud)

澄清:我发布这个答案是因为这是(我知道的)实际旋转渐变背景方向而不旋转元素本身的唯一方法。在某些边缘情况下,它可能会很有用,在这些情况下,人们需要对其他元素进行元素转换,或者他们不想对其进行转换。
可能的用例:复杂的容器形状(思考路径)或需要溢出的元素。

正如 ChrisW 在评论中指出的,IE 和 Edge 仍然没有添加对 SMIL 动画的支持。然而,它有一个polyfill

也就是说,仅仅因为它在技术上可行,并不一定意味着它应该优于transform. 我的直觉是 SMIL 有点贵(就计算而言),但我还没有进行任何测试来支持这一点。
而且,transform更简洁,因此更实用。