Как анимировать css или svg градиент в SVG?
Нужно сделать эффект заполнения цветом одной буквы, как на гифке.
Кроме, как заполнить градиентом, я не придумал, как это сделать, но проблема в том, что transition не работает на linear-gradient, keyframes тоже не делает анимацию с градиентом, я решил использовать SVG анимацию, но если туда просто прописать значения градиента то он не работает, как это реализовать?
https://jsfiddle.net/morskaya_ulitochka/1k7bjwzs/17/
Ответы (1 шт):
Эффект достигается анимацией атрибута offset линейного градиента:
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
Заполнение цветом сверху-вниз
Анимация начнется после клика
#txt {
stroke:white;
stroke-width:4px;
font-size:100px;
font-weight:bold;
font-family:verdana;
text-anchor:middle;
alignment-baseline:central;
fill:url(#top_bottom);
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300" viewBox="0 0 300 300" style="background-color:#111111" >
<defs>
<linearGradient id="top_bottom" x1="0" y1="0" x2="0" y2="100%">
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="white">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<text id="txt" x="50%" y="50%">TEXT </text>
</svg>
Заполнение цветом слева-направо
#txt {
stroke:white;
stroke-width:4px;
font-size:100px;
font-weight:bold;
font-family:verdana;
text-anchor:middle;
alignment-baseline:central;
fill:url(#left_right);
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300" viewBox="0 0 300 300" style="background-color:#111111" >
<defs>
<linearGradient id="left_right" x1="0" y1="0" x2="100%" y2="0">
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="white">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<text id="txt" x="50%" y="50%">TEXT </text>
</svg>
Анимация заполнением градиентом только одной буквы
Используется теги <tspan>X</tspan>, чтобы разбить слово на буквы и применить анимацию только к одной букве
#txt {
stroke:white;
fill:white;
stroke-width:4px;
font-size:90px;
font-weight:bold;
font-family:verdana;
/*fill:url(#top_bottom);*/
}
tspan#x {
fill:url(#top_bottom);
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300" viewBox="0 0 300 300" style="background-color:#111111" >
<defs>
<linearGradient id="top_bottom" x1="0" y1="0" x2="0" y2="100%">
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="white">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<text id="txt" x="10" y="180">
<tspan >TE</tspan>
<tspan id="x" dx="-20">X </taspan>
<tspan dx="-20" fill="white">T</tspan>
</text>
</svg>
Бесконечное повторение repeatCount="indefinite"
#txt {
stroke:white;
fill:white;
stroke-width:4px;
font-size:90px;
font-weight:bold;
font-family:verdana;
}
tspan#x {
fill:url(#top_bottom);
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300" viewBox="0 0 300 300" style="background-color:#111111" >
<defs>
<linearGradient id="top_bottom" x1="0" y1="0" x2="0" y2="100%">
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" repeatCount="indefinite" />
</stop>
<stop offset="0" stop-color="white">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" repeatCount="indefinite" />
</stop>
</linearGradient>
</defs>
<text id="txt" x="10" y="180">
<tspan >TE</tspan>
<tspan id="x" dx="-20">X </taspan>
<tspan dx="-20" fill="white">T</tspan>
</text>
</svg>
Вариант интересного эффекта
#txt {
stroke:white;
fill:white;
stroke-width:4px;
font-size:90px;
font-weight:bold;
font-family:verdana;
}
tspan#x {
fill:url(#top_bottom);
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300" viewBox="0 0 300 300" style="background-color:#111111" >
<defs>
<linearGradient id="top_bottom" x1="0" y1="0" x2="0" y2="100%">
<stop offset="0" stop-color="black">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" repeatCount="indefinite" />
</stop>
<stop offset="0" stop-color="white">
<animate begin="svg1.click" dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<text id="txt" x="10" y="180">
<tspan >TE</tspan>
<tspan id="x" dx="-20">X </taspan>
<tspan dx="-20" fill="white">T</tspan>
</text>
</svg>
