Как добиться, чтобы цветной градиент двигающейся полосы подсвечивал текст снизу

Вопрос инициирован ответом и комментарием на него

Например, что бы полоса была на одном уровне с надписью, и проходила через нее... По сути, полоса с градиентом доходя до границы надписи и исчезала, как бы входила в нее и выходила из нее в конце... было бы прикольно

Вот собственно код:

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 шт):

Автор решения: Alexandr_TT

Идея решения следующая:

  1. Необходимо скрыть часть трассы движения цветной полосы
  2. Буквы должны быть прозрачными, оставить только контур
  3. Применить текстовую маску 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>       

→ Ссылка