Как добиться, чтобы цветной градиент двигающейся полосы подсвечивал текст снизу
Вопрос инициирован ответом и комментарием на него
Например, что бы полоса была на одном уровне с надписью, и проходила через нее... По сути, полоса с градиентом доходя до границы надписи и исчезала, как бы входила в нее и выходила из нее в конце... было бы прикольно
Вот собственно код:
body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400" >
<defs>
<!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0.05" />
<stop offset="0.8" stop-color="red" />
</linearGradient>
<!-- Линейный градиент для окраски текста -->
<linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
<stop offset="5%" stop-color="orangered" >
<animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" />
</stop>
<stop offset="95%" stop-color="#DEB887" >
<animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" />
</stop>
</linearGradient>
<mask id="mask">
<rect width="100%" height="100%" fill="white"/>
<g fill="black">
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" fill="black" stroke="none" />
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" stroke="black" >
<textPath href="#textPath" startOffset="2">
<tspan dy="-1.3em">Loading . . .</tspan>
</textPath>
</text>
</g>
</mask>
</defs>
<!-- Дуга, на которой расположены буквы -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" />
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" fill="url(#LgText)" stroke="#DEB887" >
<textPath href="#textPath" startOffset="2">
<tspan dy="-1.3em">Loading . . .</tspan>
</textPath>
</text>
<!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" mask="url(#mask)" stroke="url(#Lg)" stroke-width="42" stroke-dashoffset="942" stroke-dasharray="471" fill="none" stroke-linecap="round" >
<animate
attributeName="stroke-dashoffset"
begin="0s" dur="1s"
values="942;471;235;0"
keyTimes="0;0.75;0.9;1"
calcMode="linear"
repeatCount="indefinite" />
</circle>
</svg>
</div>
По коду видно, что градиентная полоса проходит под текстом Loading . . . и буквы имеют свой динамический градиент, но всё это работает немного не так, как описано в комментарии автора вопроса
Нет синхронизации градиента полосы и букв. Полосу видно, когда она проходит под буквами.
Как добиться выполнения условий, изложенных в комментарии см. ваше
Ответы (1 шт):
Идея решения следующая:
- Необходимо скрыть часть трассы движения цветной полосы
- Буквы должны быть прозрачными, оставить только контур
- Применить текстовую маску Loading ..., которая бы прорезала закрытый (экранированный) участок трассы движения цветной полосы, тем самым сквозь прозрачные буквы будет видна цветная полоса и на буквах будет виден динамический градиент.
#1. Экранирование части трассы движения цветной полосы
Для этого добавляем поверх трассы движения цветного бегунка экранирующий сегмент
body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400" >
<defs>
<!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0.05" />
<stop offset="0.8" stop-color="red" />
</linearGradient>
</defs>
<!-- Вращающаяся дуга с градиентом -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="45" stroke-dashoffset="942" stroke-dasharray="471" fill="none" stroke-linecap="round" >
<animate
attributeName="stroke-dashoffset"
begin="0s" dur="1s"
values="942;471;235;0"
keyTimes="0;0.75;0.9;1"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<!-- Поверх трассы цветного бегунка -->
<path id="textPath" d="M200 50a150 150 0 0 1 0 300" fill="none" stroke="#383838" stroke-width="45" stroke-linecap="round" opacity="0.9"/>
</svg>
</div>
#2. Добавляем надпись сверху экранирующей полосы
Чтобы буквы были прозрачными fill="none" и был только контур stroke="gold"
body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400" >
<defs>
<!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0.05" />
<stop offset="0.8" stop-color="red" />
</linearGradient>
</defs>
<!-- Вращающаяся дуга с градиентом -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="45" stroke-dashoffset="942" stroke-dasharray="471" fill="none" stroke-linecap="round" >
<animate
attributeName="stroke-dashoffset"
begin="0s" dur="1s"
values="942;471;235;0"
keyTimes="0;0.75;0.9;1"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<!-- Экранирующая полоса поверх трассы цветного бегунка -->
<path id="textPath" d="M200 50a150 150 0 0 1 0 300" fill="none" stroke="#383838" stroke-width="45" stroke-linecap="round" opacity="0.9"/>
<path id="textPath1" d="M200 50a150 150 0 0 1 0 300" fill="none" />
<!-- Будущая текстовая маска -->
<text class="txt1" font-size="38px" font-weight="bold" letter-spacing="0.5em" stroke="gold" stroke-width="2" >
<textPath href="#textPath1" startOffset="1">
<tspan dy="0.35em">Loading . . .</tspan>
</textPath>
</text>
</svg>
</div>
#3. Применяем текстовую маску Loading ...,
которая прорезает закрытый (экранированный) участок трассы движения цветной полосы и становится виден динамический градиент
<mask id="mask">
<rect width="100%" height="100%" fill="white"/>
<g fill="black">
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" fill="black" stroke="none" />
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" stroke="black" >
<textPath href="#textPath" startOffset="2">
<tspan dy="-1.3em">Loading . . .</tspan>
</textPath>
</text>
</g>
</mask>
Для текстовой маски закраска <g fill="black"> при этом значении она прорезает экранирующую полосу
подробней как работает маска тут
Применяем маску mask="url(#mask)"
body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400" >
<defs>
<!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0.05" />
<stop offset="0.8" stop-color="red" />
</linearGradient>
<!-- Линейный градиент для окраски текста -->
<linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
<stop offset="5%" stop-color="orangered" >
<animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" />
</stop>
<stop offset="95%" stop-color="#DEB887" >
<animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" />
</stop>
</linearGradient>
<mask id="mask">
<rect width="100%" height="100%" fill="white"/>
<g fill="black">
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" fill="black" stroke="none" />
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" stroke="black" >
<textPath href="#textPath" startOffset="2">
<tspan dy="-1.3em">Loading . . .</tspan>
</textPath>
</text>
</g>
</mask>
</defs>
<!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="42" stroke-dashoffset="942" stroke-dasharray="471" fill="none" stroke-linecap="round" >
<animate
attributeName="stroke-dashoffset"
begin="0s" dur="1s"
values="942;471;235;0"
keyTimes="0;0.75;0.9;1"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<!-- Экранирующая полоса применяем к ней маску -->
<path id="textPath" mask="url(#mask)" d="M200 50a150 150 0 0 1 0 300" fill="none" stroke="#383838" stroke-width="45" stroke-linecap="round" />
</svg>
</div>
Маска неожиданно подрезала края, хотя она была применена только к буквам
Устраняем этот дефект путем добавления maskUnits="objectBoundingBox" и расширяем регион действия маски x="0%" y="-10%" width="120%" height="150%"
body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400" >
<defs>
<!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0.05" />
<stop offset="0.8" stop-color="red" />
</linearGradient>
<mask id="mask" maskUnits="objectBoundingBox"
x="0%" y="-10%" width="120%" height="150%">
<rect width="100%" height="100%" fill="white"/>
<g fill="black">
<path id="textPath1" d="M200 50a150 150 0 0 1 0 300" fill="none" />
<!-- текстовая маска -->
<text class="txt1" font-size="38px" font-weight="bold" letter-spacing="0.5em" stroke="gold" >
<textPath href="#textPath1" startOffset="1">
<tspan dy="0.35em">Loading . . .</tspan>
</textPath>
</text>
</g>
</mask>
</defs>
<!-- Вращающаяся дуга с градиентом -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="45" stroke-dashoffset="942" stroke-dasharray="471" fill="none" stroke-linecap="round" >
<animate
attributeName="stroke-dashoffset"
begin="0s" dur="1s"
values="942;471;235;0"
keyTimes="0;0.75;0.9;1"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<!-- Поверх дуги Эту дугу прорезает текстовая маска и -->
<!-- становится видно цветную полосу с градиентом-->
<path id="textPath" mask="url(#mask)" d="M200 50a150 150 0 0 1 0 300" fill="none" stroke="#383838" stroke-width="45" stroke-linecap="round" />
</svg>
</div>