有没有办法使用 CSS 在动画 SVG 上创建静态渐变?



我尝试了几种不同的东西来使SVG具有渐变背景,当我对SVG进行动画处理时不会移动。

我的第一次尝试

#container {
width: 200px;
height: 200px;

/* Temporary - Used to see the box */
background-color: #1e1e1e;
/* Temporary - Used to see the box */
}
#container svg {
transform: rotate(180deg);
}
.parallax > use {
animation: wave 25s cubic-bezier(.55, .5, .45, .5) infinite;
}
.parallax > use:nth-child(1) {
animation-delay: -2s;
animation-duration: 7s;
}
.parallax > use:nth-child(2) {
animation-delay: -3s;
animation-duration: 10s;
}
.parallax > use:nth-child(3) {
animation-delay: -4s;
animation-duration: 13s;
}
.parallax > use:nth-child(4) {
animation-delay: -5s;
animation-duration: 20s;
}
@keyframes wave {
0% {
transform: translate3d(-90px, 0, 0);
}
100% {
transform: translate3d(85px, 0, 0);
}
}
<div id='container'>
<svg class='waves' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 24 150 28' preserveAspectRatio='none' shape-rendering='auto'>
<defs>
<path id='wave' d='M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z' />
<linearGradient id='waveGradient' gradientTransform='rotate(45)'>
<stop offset='0%'  stop-color='red' />
<stop offset='100%' stop-color='green' />
</linearGradient>
</defs>
<g class='parallax'>
<use xlink:href='#wave' x='48' y='0' fill="url('#waveGradient')" opacity='0.7' />
<use xlink:href='#wave' x='48' y='3' fill="url('#waveGradient')" opacity='0.5' />
<use xlink:href='#wave' x='48' y='5' fill="url('#waveGradient')" opacity='0.3' />
<use xlink:href='#wave' x='48' y='7' fill="url('#waveGradient')" />
</g>
</svg>
</div>

如您所见,渐变随波浪移动。

我第二次尝试使用clipPath创建它。

#container {
width: 200px;
height: 200px;

/* Temporary - Used to see the box */
background-image: linear-gradient(45deg, red 0%, green 100%);
/* Temporary - Used to see the box */

clip-path: url(#wavePath);
}
<div id='container'>

</div>
<svg>
<defs>
<clipPath id="wavePath">
<path d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</clipPath>
</defs>
</svg>

但是,这会导致不使用 viewBox 值,并且不会创建正确的形状。

在这一点上,我对如何做到这一点感到迷茫,可以使用一些帮助来弄清楚。

以下是基本的 SVG 代码:

<svg>
<path d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</svg>

我们可以通过同时但方向相反的渐变和容器进行动画处理来创建效果。

下面是一个基本示例:

#container  {
width:100px;
height:200px;
overflow:hidden;
}
#container > div {
width: 200%;
height: 100%;  
clip-path: url(#wavePath);
animation:move 2s linear infinite alternate;
}
#container > div::before {
content:"";
display:block;
width:100%;
height:100%;
background-image: linear-gradient(to right,red,yellow, blue);
animation:move 2s linear infinite alternate-reverse;
}
@keyframes move {
to {
transform:translateX(-50%);
}
}
<div id='container'>
<div></div>
</div>
<svg>
<defs>
<clipPath id="wavePath">
<path d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</clipPath>
</defs>
</svg>

或者干脆让纯色的波浪在渐变上方移动:

#container  {
width:100px;
height:85px;
overflow:hidden;
background-image: linear-gradient(to right,red,yellow, blue);
}
#container > div {
width: 200%;
height: 100%;  
clip-path: url(#wavePath);
background:#fff;
animation:move 2s linear infinite alternate;
}
@keyframes move {
to {
transform:translateX(-45%);
}
}
<div id='container'>
<div></div>
</div>
<svg>
<defs>
<clipPath id="wavePath">
<path d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</clipPath>
</defs>
</svg>

最新更新