如何使用CSS为径向渐变设置动画?

时间:2019-07-26 10:46:19

标签: css css-animations radial-gradients

我正在尝试为div框创建放射状渐变光泽效果,但我不确定这样做的最佳方法是什么。我找不到实现我想要实现的目标的资源。我发现的示例只是光泽效果,看起来就像是覆盖。

我发现的大多数示例都是这样的Parallelize these nested for loops in python

下面,我显示了我要创建的内容。

#shine-div {
  height: 30vh;
  width: 60vw;
  margin-right: auto;
  margin-left: auto;
  border-radius: 10px;
  /*background: radial-gradient(ellipse farthest-corner at right top, #FFFFFF 0%, #ffb3ff 8%, #ff33ff 25%, #800080 62.5%, #b300b3 100%);*/
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-weight: bold;
  animation: colorChange 5s infinite;
}

@keyframes colorChange {
  0% {
    background: radial-gradient(ellipse farthest-corner at left top, #FFFFFF 0%, #ffb3ff 8%, #ff33ff 25%, #800080 62.5%, #b300b3 100%)
  }
  50% {
    background: radial-gradient(ellipse farthest-corner at top, #FFFFFF 0%, #ffb3ff 8%, #ff33ff 25%, #800080 62.5%, #b300b3 100%)
  }
  100% {
    background: radial-gradient(ellipse farthest-corner at right top, #FFFFFF 0%, #ffb3ff 8%, #ff33ff 25%, #800080 62.5%, #b300b3 100%)
  }
  /*0% { transform: translateY(-20vh) translateX(-7vw) ; opacity: 0;  }*/
  /*10% { transform: translateY(-20vh) translateX(-7vw) ; opacity: 1;  }*/
  /*40% { transform: translateY(-20vh) translateX(17vw) ; opacity: 1; }*/
  /*50% { transform: translateY(-20vh) translateX(17vw) ; opacity: 0; }*/
  /*60% { transform: translateY(-20vh) translateX(17vw) ; opacity: 1; }*/
  /*90% { transform: translateY(-20vh) translateX(-7vw) ; opacity: 1; }*/
  /*100% { transform: translateY(-20vh) translateX(-7vw) ; opacity: 0; }*/
}
<div id="shine-div">
  Shine
</div>

是否有可能以及如何使顶部的白色光泽从左向右平滑地移动?我的尝试是否在正确的轨道上?感谢您的任何建议或进一步的参考。

3 个答案:

答案 0 :(得分:7)

您可以不同地进行渐变并为位置设置动画。诀窍是将渐变的大小加倍,并使色标的值停止为实际值的一半,以便保持相同的视觉渐变,然后可以从左到右对其进行动画处理。

由于计算了最远的角,它看上去与动画中定义的渐变完全不一样。

#shine-div {
  height: 30vh;
  width: 60vw;
  margin-right: auto;
  margin-left: auto;
  border-radius: 10px;
  background: radial-gradient(farthest-corner at top, #FFFFFF 0%, #ffb3ff 4%, #ff33ff 12.25%, #800080 31.25%, #b300b3 50%) top right/200% 200%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-weight: bold;
  animation: colorChange 5s infinite alternate;
}

@keyframes colorChange {
  to {
    background-position:top left;
  }
 }
<div id="shine-div">
  Shine
</div>


要更接近渐变,还可以设置大小的动画:

#shine-div {
  height: 30vh;
  width: 60vw;
  margin-right: auto;
  margin-left: auto;
  border-radius: 10px;
  background: radial-gradient(farthest-corner at top, #FFFFFF 0%, #ffb3ff 4%, #ff33ff 12.25%, #800080 31.25%, #b300b3 50%) top right/400% 200%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-weight: bold;
  animation: colorChange 5s infinite alternate linear;
}

@keyframes colorChange {
  from {
    background-position:top 0 left 33%;
    background-size:400% 200%;
  
  }
  50% {
    background-position:top center;
    background-size:200% 200%;
  }
  to {
    background-position:top 0 right 33%;
    background-size:400% 200%;
  }
 }
<div id="shine-div">
  Shine
</div>

有关计算值的更多详细信息,请参见:Using percentage values with background-position on a linear gradient


您还可以在考虑伪元素的情况下制作相同的动画,并进行变换以提高性能:

#shine-div {
  height: 30vh;
  width: 60vw;
  margin-right: auto;
  margin-left: auto;
  border-radius: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-weight: bold;
  overflow:hidden;
  position:relative;
  z-index:0;
}
#shine-div:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  width:400%;
  height:200%;
  background: radial-gradient(farthest-corner at top, #FFFFFF 0%, #ffb3ff 4%, #ff33ff 12.25%, #800080 31.25%, #b300b3 50%);
  animation: colorChange 5s infinite alternate linear;
}

@keyframes colorChange {
  from {
    transform:translateX(-50%);
  }
  50% {
    transform:scaleX(0.75) translateX(-50%)
  }
  to {
    transform:translateX(-25%);
  }
 }
<div id="shine-div">
  Shine
</div>

答案 1 :(得分:3)

使用 CSS 变量和新的 @property,我们可以轻松地为 radial-gradient(或任何类型的渐变)设置动画。 The support 目前仅涵盖 Chrome 和 Edge。

@property --x {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

#shine-div {
  height: 30vh;
  width: 60vw;
  margin: auto;
  border-radius: 10px;
  background: radial-gradient(ellipse farthest-corner at var(--x) 0%, #FFFFFF 0%, #ffb3ff 8%, #ff33ff 25%, #800080 62.5%, #b300b3 100%);
  animation: colorChange 5s infinite alternate;
}

@keyframes colorChange {
  0% {
    --x:0%;
  }
  50% {
    --x:50%;
  }
  100% {
    --x:100%;
  }
}
<div id="shine-div"></div>

我们所要做的就是使用变量 --x 定义位置,该变量将使用百分比值,然后我们对该变量进行动画处理。就这么简单!

答案 2 :(得分:1)

SVG解决方案

作者没有使用SVG寻求解决方案。但是以多种方式解决一个问题可能很有用。
渐变属性值来自@Temani Afif响应。
此问题的SVG径向梯度公式:

<radialGradient id="radGrad"  fx="0%" fy="5%" r="200%">
     <stop offset="0%" stop-color ="#FFFFFF" />
      <stop offset="4%" stop-color ="#ffb3ff" />
       <stop offset="12.25%" stop-color ="#ff33ff" />
        <stop offset="31.25%" stop-color ="#800080" />
          <stop offset="50%" stop-color ="#b300b3" /> 

   </radialGradient>

要设置渐变动画,可以使用公式中包含的任何属性。
以下示例将使用属性fxfy

  • 水平梯度运动的动画

单击矩形后动画开始

svg {
 width:50%;
 height:50%;
 }
 .txt {
 font-family:sans-serif;
 font-size:28px;
 font-weight:bold;
 text-anchor:middle;
 fill:#FFDD00;
  }
<div id="shine-div">
   <svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 100">
   <defs>
  <radialGradient id="radGrad"  fx="0%" fy="0%" r="200%">
      <stop offset="0%" stop-color ="#FFFFFF" />
	    <stop offset="4%" stop-color ="#ffb3ff" />
	    <stop offset="12.25%" stop-color ="#ff33ff" />
	    <stop offset="31.25%" stop-color ="#800080" />
	    <stop offset="50%" stop-color ="#b300b3" /> 		 
  </radialGradient>
   </defs> 
    <g id="gr1" > 
      <rect id="rect1" fill="url(#radGrad)" x="5%" y="5%" width="95%" height="95%" rx="10%"/> 
       <text class="txt" x="50%" y="60%"> Sun shine </text>
	</g>  
    <animate xlink:href="#radGrad"
	  attributeName="fx"
	  dur="2s"begin="gr1.click"
	  values="0%;50%;50%;100%;50%;50%;0%"
	  keyTimes="0;0.1;0.5;0.6;0.7;0.9;1"
	  repeatCount="1"
	  restart="whenNotActive" />
  </svg>
</div>

  • 垂直渐变运动的动画。

svg {
 width:50%;
 height:50%;
 }
 .txt {
 font-family:sans-serif;
 font-size:28px;
 font-weight:bold;
 text-anchor:middle;
 fill:#FFDD00;
  }
<div id="shine-div">
   <svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 100">
   <defs>
  <radialGradient id="radGrad"  fx="48%" fy="0%" r="200%">
        <stop offset="0%" stop-color ="#FFFFFF" />
	    <stop offset="4%" stop-color ="#ffb3ff" />
	    <stop offset="12.25%" stop-color ="#ff33ff" />
	    <stop offset="31.25%" stop-color ="#800080" />
	    <stop offset="50%" stop-color ="#b300b3" /> 		 
  </radialGradient>
   </defs> 
    <g id="gr1" > 
      <rect id="rect1" fill="url(#radGrad)" x="5%" y="5%" width="95%" height="95%" rx="10%"/> 
       <text class="txt" x="50%" y="60%"> Sun shine </text>
	</g>  
    <animate xlink:href="#radGrad"
	  attributeName="fy"
	  dur="2s"begin="gr1.click"
	  values="0%;50%;50%;100%;50%;50%;0%"
	  keyTimes="0;0.1;0.5;0.6;0.7;0.9;1"
	  repeatCount="1"
	  restart="whenNotActive" />
  </svg>
</div>

  • 对角移动梯度

同时激活两个属性:fxfy

svg {
 width:50%;
 height:50%;
 }
 .txt {
 font-family:sans-serif;
 font-size:28px;
 font-weight:bold;
 text-anchor:middle;
 fill:#FFDD00;
  }
<div id="shine-div">
   <svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 100">
   <defs>
  <radialGradient id="radGrad"  fx="0%" fy="0%" r="200%">
        <stop offset="0%" stop-color ="#FFFFFF" />
	    <stop offset="4%" stop-color ="#ffb3ff" />
	    <stop offset="12.25%" stop-color ="#ff33ff" />
	    <stop offset="31.25%" stop-color ="#800080" />
	    <stop offset="50%" stop-color ="#b300b3" /> 		 
  </radialGradient>
   </defs> 
    <g id="gr1" > 
      <rect id="rect1" fill="url(#radGrad)" x="5%" y="5%" width="95%" height="95%" rx="10%"/> 
       <text class="txt" x="50%" y="60%"> Sun shine </text>
	</g>  
    <animate xlink:href="#radGrad"
	  attributeName="fy"
	  dur="2s"begin="gr1.click"
	  values="0%;50%;50%;100%;0%"
	  keyTimes="0;0.1;0.5;0.9;1"
	  repeatCount="1"
	  restart="whenNotActive" />
	  
	     <animate xlink:href="#radGrad"
			  attributeName="fx"
			  dur="2s"begin="gr1.click"
			  values="0%;50%;50%;100%;0%"
			  keyTimes="0;0.1;0.5;0.9;1"
			  repeatCount="1"
			  restart="whenNotActive" />
  </svg>
</div>