如何平滑地动画渐变背景 [英] How to animate gradient background smoothly

查看:97
本文介绍了如何平滑地动画渐变背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现的效果比用户悬停在一个div,它的背景颜色变成一个渐变,从一个角落平滑地切换到另一个,重复使用纯CSS。



我想实现的效果,试图把它更多的话,是背景的较暗的部分(具有0.9不透明度的一个)从一个角滑动到另一个重复,只要光标保持



实际发生的是背景从一个状态跳到另一个状态。我在哪里错了?



这是我的代码:



  #test {width:200px; height:200px; background-color:rgba(215,54,92,0.7);} @keyframes test_hover {from {background:-webkit-linear-gradient(45deg,rgba(215,54,92,0.9),rgba(215, 92,0.5)); / *对于Safari 5.1到6.0 * / background:-o-linear-gradient(45deg,rgba(215,54,92,0.9),rgba(215,54,92,0.5)); / *对于Opera 11.1到12.0 * / background:-moz-linear-gradient(45deg,rgba(215,54,92,0.9),rgba(215,54,92,0.5)); / *对于Firefox 3.6到15 * /背景:线性梯度(45deg,rgba(215,54,92,0.9),rgba(215,54,92,0.5)); / *标准语法(必须是最后)* /}到{background:-webkit-linear-gradient(45deg,rgba(215,54,92,0.5),rgba(215,54,92, / *对于Safari 5.1到6.0 * / background:-o-linear-gradient(45deg,rgba(215,54,92,0.5),rgba(215,54,92,0.9)); / *对于Opera 11.1到12.0 * / background:-moz-linear-gradient(45deg,rgba(215,54,92,0.5),rgba(215,54,92,0.9)); / *对于Firefox 3.6到15 * /背景:线性梯度(45deg,rgba(215,54,92,0.5),rgba(215,54,92,0.9)); / *标准语法(必须是最后一个)* /}}#test:hover {cursor:pointer; animation-name:test_hover; animation-duration:4s; animation-delay:1s; animation-iteration-count:infinite;}  

 < div id =test>< / div>  



JSFiddle



此问题已引用是来自这里的重复,但我认为它不是。首先,在这个问题中没有代码,这使得它很难理解。此外,在这个问题的答案,他使用一个过渡,但我不想要一个过渡,因为它只应用一次,我想我的动画不断重复,而用户悬停在div。

解决方案

正如在注释中已经指出的,线性渐变不是可转换的或者动画不同于颜色( color ),因为它们被视为图像( background-image )。转换效应通常通过UA计算每个中间阶段的值,然后将该值应用于该元素来实现。如果是图片,则无法计算中间阶段的值,因此无法转换。



您需要转换位置( background-position )来实现效果。这可以通过使用其背景包含线性梯度并在 hover 上动画化其位置的伪元素来完成。渐变应该两种方式(即,它应该从 rgba(215,54,92,0.9) rgba(215,54, 92,0.5),然后到 rgba(215,54,92,0.9)),因为它需要适应动画的两个阶段及其 background-size 也需要为double(即 200%200%)。然后通过动画从 0%100% 100%0%的位置可以实现所需的效果。 p>

  #test {position:relative; width:200px; height:200px; background-color:rgba(215,54,92,0.7); transition:background-color .1s;}#test:hover {background-color:transparent; cursor:pointer;}#test:hover:after {position:absolute; content:'';高度:100%; width:100%;背景:线性梯度(45deg,rgba(215,54,92,0.9),rgba(215,54,92,0.5),rgba(215,54,92,0.9)); background-size:200%200%; background-position:0%100%; animation-name:test_hover; animation-duration:4s; animation-iteration-count:infinite;动画定时功能:线性; animation-direction:alternate;} @ keyframes test_hover {from {background-position:0%100%; }到{background-position:100%0%; }}  

 < script src =https:// cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js\"> ;</script> ;<div id =test>< / div>  






是添加两个伪元素,每个具有一个动画梯度的阶段,然后对它们的 opacity 进行动画处理,使得在任何时间点只有其中一个将是可见的。这也会产生类似的效果。



  #test {position:absolute; width:200px; height:200px; background-color:rgba(215,54,92,0.7); transition:background-color .1s;}#test:before,#test:after {position:absolute; content:'';高度:100%; width:100%; z-index:1;}#test:before {background:linear-gradient(45deg,rgba(215,54,92,0.9),rgba(215,54,92,0.5));不透明度:0;}#test:在{background:linear-gradient(45deg,rgba(215,54,92,0.5),rgba(215,54,92,0.9) opacity:0;} @ keyframes test_hover {0%,100%{opacity:0; } 50%{opacity:1; }}#test:hover:before,#test:hover:after {cursor:pointer; animation-name:test_hover; animation-duration:4s; animation-iteration-count:infinite; animation-fill-mode:backwards;}#test:hover:before {animation-delay:1s;}#test:hover:after {animation-delay:3s;}#test:hover {background- transition:background-color 2s 1s;}  

 < script src =https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js>< / script>< div id =test>< / div> ;  


I want to achieve an effect than when the user hovers over a div, it's background color turns into a gradient that smoothly switches from one corner to the other, repeatedly, using purely CSS.

The effect I want to achieve, trying to put it more into words, is that the darker part of the background (the one with 0.9 opacity) slides from one corner to the other repeatedly as long as the cursor remains above the element.

What is actually happening is that the background jumps from one state to the other. Where am I going wrong? How can I get this to be an animated, smooth effect?

Here is my code:

#test {
  width: 200px;
  height: 200px;
  background-color: rgba(215, 54, 92, 0.7);
}
@keyframes test_hover {
  from {
    background: -webkit-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5));    /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5));    /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5));    /* For Firefox 3.6 to 15 */
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5));    /* Standard syntax (must be last) */
  }
  to {
    background: -webkit-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));    /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));    /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));    /* For Firefox 3.6 to 15 */
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));    /* Standard syntax (must be last) */
  }
}
#test:hover {
  cursor: pointer;
  animation-name: test_hover;
  animation-duration: 4s;
  animation-delay: 1s;
  animation-iteration-count: infinite;
}

<div id="test"></div>

Here is the JSFiddle

This question have been referenced to be a duplicate from here, but I think it is not. For a start, there is no code in that question which makes it difficult to understand. Also, in the answer to that question he uses a transition, but I do not want a transition because it is only applied once, I want my animation to be constantly repeated while the user is hovering the div.

解决方案

As already pointed out in comments, linear gradients are not transitionable or animatable unlike colors (background-color) because they are considered as image (background-image). Transitions effects are generally achieved by the UA calculating the value at each intermediate stage and then applying that value to the element. In case of an image, it is not possible to calculate the values at intermediate stages and hence they cannot be transitioned.

You need to transition the position (background-position) instead to achieve the effect. This can be done by using a pseudo-element whose background contains the linear-gradient and animating its position on hover. The gradient should go both ways (that is, it should go from rgba(215,54,92,0.9) to rgba(215,54,92,0.5) and then to rgba(215,54,92,0.9)) because it needs to accommodate both phases of the animation and its background-size also needs to be double (that is 200% 200%). Then by animating the positon from 0% 100% to 100% 0% the required effect can be achieved.

#test {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: rgba(215, 54, 92, 0.7);
  transition: background-color .1s;
}
#test:hover {
  background-color: transparent;
  cursor: pointer;
}
#test:hover:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));
  background-size: 200% 200%;
  background-position: 0% 100%;
  animation-name: test_hover;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-direction: alternate;
}
@keyframes test_hover {
  from {
    background-position: 0% 100%;
  }
  to {
    background-position: 100% 0%;
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="test"></div>


Another slightly different approach that can be used is to add two pseudo-elements with each having one stage of animation's gradient and then animate their opacity such that at any point of time only one of them will be visible. This would also produce a similar effect.

#test {
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: rgba(215, 54, 92, 0.7);
  transition: background-color .1s;
}
#test:before,
#test:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  z-index: 1;
}
#test:before {
  background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5));
  opacity: 0;
}
#test:after {
  background: linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9));
  opacity: 0;
}
@keyframes test_hover {
  0%, 100% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
}
#test:hover:before,
#test:hover:after {
  cursor: pointer;
  animation-name: test_hover;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-fill-mode: backwards;
}
#test:hover:before {
  animation-delay: 1s;
}
#test:hover:after {
  animation-delay: 3s;
}
#test:hover {
  background-color: transparent;
  transition: background-color 2s 1s;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="test"></div>

这篇关于如何平滑地动画渐变背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆