Необычный лоадер из падающих капель

248
14 апреля 2022, 14:50

Идея инспирирована ответом

<svg xmlns="http://www.w3.org/2000/svg" width="332" height="412" viewBox="0 0 1238 1648" >
<defs>
 <radialGradient id="rg" r="1" fx="0.25" fy="0.5">
              <stop offset="0%" stop-color="white"></stop>
              <stop offset="75%" stop-color="#1B7FE4"></stop>
             
  </defs>
<polyline points="615,85 1238,30" stroke="#0F4982" stroke-width="36" stroke-linecap="round" />
<g transform="translate(450,0)">
<path  fill="url(#rg)" id="pathX" >
  <!-- Анимация изменения формы капли -->
<animate id="an1"
  attributeName="d"
  begin="0s;an2.end+0.5s"
  dur="3s"
  repeatCount="1"
  values="
     m 228.82,126.17 c 0,0 -11.21426,-24.27631 -54.17763,-36.049322 -6.26889,-1.717829 -34.05856,-0.314692 -40.44915,0.872881 C 106.06884,96.219957 84.38,126.17 84.38,126.17 c -43.19,59.62 0.65,142 74,141.33 71.09,-1.56 113.12,-82.46 70.47,-141.33;
   
   m 228.82,126.17 c 0,0 -36.96426,-56.572924 -62.47,-86.24 -4.23749,-4.928853 -15.48617,-5.112646 -19.5,0 -21.57777,27.484873 -62.47,86.24 -62.47,86.24 -43.19,59.62 0.65,142 74,141.33 71.09,-1.56 113.12,-82.46 70.47,-141.33;" />  
   <!-- Анимация падения капли -->
 <animateTransform id="an2" attributeName="transform" type="translate" dur="3s" begin="an1.begin" values="0,0;0,60;0,1680" keyTimes="0;0.85;1" />   
</path>
</g> 
</svg>

Равномерность падения каплей навеяла мысль, - а что если заполнять постепенно какой-то сосуд водой и выводить проценты заполнения

Что будет напоминает визуальный эффект работы лоадеров, которые в свою очередь символизируют загрузку веб страницы, файлов и т.д.

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

<linearGradient id="water" x1="0" y1="1" x2="0" y2="0" >
      <stop offset="0" stop-color="#8FBAE4" >
        <!-- анимация градиента для наполнения сосуда водой         -->
        <animate id="OP" dur="60s" attributeName="offset" fill="freeze" values="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;1" calcMode="discrete" /> 
      </stop>
      <stop offset="0" stop-color="transparent">
         <animate  begin="0s" dur="60s" attributeName="offset" fill="freeze" values="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;1" calcMode="discrete"/> 
      </stop>
      
    </linearGradient>

Как синхронизировать вместе процессы падения капли, заполнения сосуда и вывода процентов заполнения?

Answer 1

Синхронность анимации изменения формы капли и анимации падения капель достигается одновременным началом, продолжительностью анимации и условием запуска второй анимации begin="an1.begin"

Синхронность между числом упавших капель и уровнем заполнения сосуда водой, достигается дискретной анимацией градиента, который закрашивает сосуд и иммитирует его постепенное наполнение

<!-- анимация градиента для наполнения сосуда водой         -->
        <animate id="OP" dur="60s"
            attributeName="offset"
            fill="freeze"
           calcMode="discrete"
  values="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;1"/> 

За вывод процентов отвечает JS

Прочтите пожалуйста комментарии в коде, надеюсь это поможет понять основные моменты работы анимаций

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" width="332" height="412" viewBox="0 0 1238 1648" >
<defs>
 <radialGradient id="rg" r="1" fx="0.25" fy="0.5">
              <stop offset="0%" stop-color="white"></stop>
              <stop offset="75%" stop-color="#1B7FE4"></stop>
             
  </radialGradient>
<linearGradient id="water" x1="0" y1="1" x2="0" y2="0" >
      <stop offset="0" stop-color="#8FBAE4" >
        <!-- анимация градиента для наполнения сосуда водой         -->
        <animate id="OP" dur="60s" attributeName="offset" fill="freeze" values="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;1" calcMode="discrete" /> 
      </stop>
      <stop offset="0" stop-color="transparent">
         <animate  begin="0s" dur="60s" attributeName="offset" fill="freeze" values="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;1" calcMode="discrete"/> 
      </stop>
      
    </linearGradient>
 </defs> 
     <!-- Верхняя опора, с которой падает капля -->
  <polyline  points="605,75 1238,30" stroke="#882B88" stroke-width="60"  />
 
 <polyline stroke-dasharray="60,40" points="605,75 1238,30" stroke="#8CB8E4" stroke-width="24" stroke-linecap="round" >
   <animate attributeName="stroke-dashoffset" dur="12s" values="-320;0" repeatcount="5" />
  </polyline>
<g opacity="1" transform="translate(450,0)">
<path  fill="url(#rg)" id="pathX" >
  <!-- Анимация изменения формы капли -->
<animate id="an1"
  attributeName="d"
  begin="0s;an2.end"
  dur="3s"
  repeatCount="1"
  values="
     m 228.82,126.17 c 0,0 -11.21426,-24.27631 -54.17763,-36.049322 -6.26889,-1.717829 -34.05856,-0.314692 -40.44915,0.872881 C 106.06884,96.219957 84.38,126.17 84.38,126.17 c -43.19,59.62 0.65,142 74,141.33 71.09,-1.56 113.12,-82.46 70.47,-141.33;
   
   m 228.82,126.17 c 0,0 -36.96426,-56.572924 -62.47,-86.24 -4.23749,-4.928853 -15.48617,-5.112646 -19.5,0 -21.57777,27.484873 -62.47,86.24 -62.47,86.24 -43.19,59.62 0.65,142 74,141.33 71.09,-1.56 113.12,-82.46 70.47,-141.33" />  
   <!-- Анимация падения капель -->
 <animateTransform id="an2" attributeName="transform" type="translate" dur="3s" begin="an1.begin" values="0,0;0,60;0,1400" keyTimes="0;0.85;1" />   
</path> 
   <animate attributeName="opacity" begin="OP.end" dur="1ms" values="1;0" fill="freeze" />
</g>    
           <!-- Сосуд, наполняемый водой -->
  <path fill="url(#water)" stroke="#BC3CBC" stroke-width="35" d="m809.6 819.9c53 20.8 101.8 49.8 143.8 85.9 92.6 79.6 144.6 187.6 144.6 300.3 0 112.6-52 220.6-144.6 300.3-92.6 79.6-218.2 124.4-349.2 124.4-131 0-256.6-44.7-349.2-124.4-92.6-79.6-144.6-187.6-144.6-300.3 0-112.6 52-220.6 144.6-300.3 40.3-34.7 86.9-62.7 137.4-83.4" /> 
 
   <!-- Вывод процентов заполнения -->
 <text id="count" x="600" y="1280" text-anchor="middle" dy="7" font-size="200" fill="#BC3CBC">100%</text>  
</svg>
<script>
var count = $(('#count'));
$({ Counter: 0 }).animate({ Counter: count.text() }, {
  duration: 60000,
  easing: 'linear',
  step: function () {
    count.text(Math.ceil(this.Counter)  + "%");
  }
});

</script>

READ ALSO
Как поместить один блок под другой?

Как поместить один блок под другой?

Появилась задача - поместить SVG блок под блок описания, но так, чтобы он оказался ПОД блоком описанияВот что у меня вышло:

201
Стилизвация маркера в списку ul li?

Стилизвация маркера в списку ul li?

Здравствуйте дорогие друзья! Подскажите как сделать стилизация маркера списка (ul li) Слева должен быть блок с такими стилями

222
unexpected token &lt; in JSON

unexpected token < in JSON

помогите, не отправляется форма отправки на почту

134
Кроссбраузерность с textarea

Кроссбраузерность с textarea

Здравствуйте господа и дамыУ меня есть вопрос касательно тега teaxtarea и фреймворка bootstrap 4

143