3

Есть следующий код:

$('input[type="button"]').on('click', function(){
  StartFill();
});

function StartFill() { let timer = 1000*5; $('.status').css('background', 'green'); $('#fill path') .css('stroke-dasharray', '0, 251.2') .animate({ 'stroke-dasharray': '251.2, 251.2' }, timer, 'linear', function(){ $('#fill path').css('stroke-dasharray', '0, 251.2'); $('.status').css('background', 'red'); }); }

#fill {
  width: 150px;
  height: 150px;
}

.status {
  display: block;
  width: 20px;
  height: 20px;
  background: red;
  position: absolute;
  left: 0;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- -->
<svg id="fill" viewbox="0 0 100 100">
  <path fill="none" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
  </path>
</svg>
<div class="status"></div>
<br>
<input type="button" value="start">

По задумке, при нажатии на кнопку "start" бордюр круга должен заполниться (как круговой прогресс бар).
Но он не хочет..

Думаю проблема в том, что .animate() не так "воспроизводит" "механику" stroke-dasharray.

Как можно "переиграть" данное действие?


P.s.

<animate> предлагать только в том случае, если можно "узнать" когда конец анимации.
<div class="status"> просто для визуального отображения того, что действие .animate() работает.

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
De.Minov
  • 24,026

2 Answers2

4

можно пошагово обновлять атрибут

$('input[type="button"]').on('click', function(){
  StartFill();
});

function StartFill() { $('.status').css('background', 'green');

const animationOptions = { duration: 1000*5, step: function(now) { $(this).attr("stroke-dasharray", ${now}, 251.2); }, easing: 'linear', complete: function() { $('#fill path').attr('stroke-dasharray', '0, 251.2'); $('.status').css('background', 'red'); }, };

$('#fill path') .css('percent-load', 0) .animate({ 'percent-load': 251.2 }, animationOptions); }

#fill {
  width: 150px;
  height: 150px;
}

.status {
  display: block;
  width: 20px;
  height: 20px;
  background: red;
  position: absolute;
  left: 0;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="fill" viewbox="0 0 100 100">
  <path fill="none" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
  </path>
</svg>
<div class="status"></div>
<br>
<input type="button" value="start">
exvayn
  • 629
3

Все варианты анимации animate исключительно stroke-dasharray

Чтобы лучше понять, как это работает, можно почитать топик на нашем сайте.

1. Один сегмент

Левая кнопка "L" заполнение окружности

Правая "R" - уменьшение заполнения

<meta charset="utf-8">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100">

<path fill="none" stroke-linecap="round" stroke-width="5" stroke="#e1e1e1" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80"/>

<path fill="none" stroke-dasharray="0 251" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
<animate attributeName="stroke-dasharray" values="0 251; 251 0" begin="btn_L.click" dur="4s" restart="whenNotActive" fill="freeze" />
<animate attributeName="stroke-dasharray" values="251 0; 0 251" begin="btn_R.click" dur="4s" restart="whenNotActive" fill="freeze" />

</path>

<g id="btn_L" transform="translate(-17 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="green" >L</text> </g>

&lt;g id="btn_R" transform="translate(60 0)" &gt;
  &lt;rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/&gt;
  &lt;text x="25" y="95" font-size="10" fill="crimson" &gt;R&lt;/text&gt;
&lt;/g&gt;   </code></pre>

2. Синхронно из одной общей точки

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100">

<path fill="none" stroke-linecap="round" stroke-width="5" stroke="#e1e1e1" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80"/>

<path fill="none" stroke-dasharray="0 125.6 0 125.6" stroke-dashoffset="125.6" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
<animate attributeName="stroke-dasharray" values="0 125.6 0 125.6; 0 0 251 0" begin="btn_L.click" dur="4s" restart="whenNotActive" fill="freeze" />
<animate attributeName="stroke-dasharray" values="0 0 251 0;0 125.6 0 125.6" begin="btn_R.click" dur="4s" restart="whenNotActive" fill="freeze" />

</path> </path>

<g id="btn_L" transform="translate(-17 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="green" >L</text> </g>

<g id="btn_R" transform="translate(60 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="crimson" >R</text> </g>

3. Два сегмента

<meta charset="utf-8">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100">

<path fill="none" stroke-linecap="round" stroke-width="5" stroke="#e1e1e1" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80"/>

<path fill="none" stroke-dasharray="0 251" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
<animate attributeName="stroke-dasharray" values="0 125.6 0 125.6;125.6 0 125.6 0" begin="btn_L.click" dur="4s" restart="whenNotActive" fill="freeze" />
<animate attributeName="stroke-dasharray" values="125.6 0 125.6 0;0 125.6 0 125.6" begin="btn_R.click" dur="4s" restart="whenNotActive" fill="freeze" />

</path>

<g id="btn_L" transform="translate(-17 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="green" >L</text> </g>

&lt;g id="btn_R" transform="translate(60 0)" &gt;
  &lt;rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/&gt;
  &lt;text x="25" y="95" font-size="10" fill="crimson" &gt;R&lt;/text&gt;
&lt;/g&gt;</code></pre>

4. Три сегмента

<meta charset="utf-8">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100">

<path fill="none" stroke-linecap="round" stroke-width="5" stroke="#e1e1e1" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80"/>

<path fill="none" stroke-dasharray="0 83.66 0 83.66 0 83.66" stroke-dashoffset="125.6" stroke-linecap="round" stroke-width="5" stroke="#07f" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
<animate attributeName="stroke-dasharray" values="0 83.66 0 83.66 0 83.66; 83.66 0 83.66 0 83.66 0" begin="btn_L.click" dur="4s" restart="whenNotActive" fill="freeze" />
<animate attributeName="stroke-dasharray" values="83.66 0 83.66 0 83.66 0; 0 83.66 0 83.66 0 83.66" begin="btn_R.click" dur="4s" restart="whenNotActive" fill="freeze" />

</path>

<g id="btn_L" transform="translate(-17 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="green" >L</text> </g>

<g id="btn_R" transform="translate(60 0)" > <rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/> <text x="25" y="95" font-size="10" fill="crimson" >R</text> </g>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384