Я пытаюсь сделать анимацию прогресс-бара
https://codepen.io/mihail-kamahin/pen/YzKZjWd
Я хочу сделать так, чтобы из одной точки круга анимация начиналась сразу с двух сторон, на картинке я показал схематично, как я хотел это сделать
Но у меня не получается, я пытался ещё один круг создавать, поверх уже созданного, но получается какая-то каша. Кто уже работал с кругами на svg
, возможно, знаете, как это сделать?
function setProgress(percent, selector__circle) {
const circle = document.querySelector(`${selector__circle}`);
const radius = circle.r.baseVal.value;
const circumference = 2 * Math.PI * radius;
circle.style.strokeDasharray = `${circumference} ${circumference}`;
circle.style.strokeDashoffset = circumference;
const offset = circumference - percent / 100 * circumference;
circle.style.strokeDashoffset = offset;
}
var number = 125;
setProgress(number, '.progressbar__thumb');
click__me = document.querySelector('.click__me');
click__me.addEventListener('click', function() {
setProgress(number += 25, '.progressbar__thumb');
});
.progress__container {
width: 140px;
height: 140px;
}
.progressbar__track {
fill: transparent;
stroke: #3E4153;
stroke-width: 3px;
}
.progressbar__thumb {
fill: transparent;
stroke: yellow;
stroke-width: 4px;
transform: rotate(270deg);
transform-origin: center;
transition: 0.5s linear;
}
.click__me {
margin-top: 30px;
margin-left: 30px;
}
<div class="progress__container">
<svg class="progressbar" viewbox="0 0 64 64">
<circle class="progressbar__track" cx="50%" cy="50%" r="30"> </circle>
<circle class="progressbar__thumb" cx="50%" cy="50%" r="30"> </circle>
</svg>
</div>
<button class="click__me">Click me</button>
Все можно сделать за счет одного лишь stroke-dasharray
, корректно посчитав длины:
function setProgress(percent, selector__circle) {
const circle = document.querySelector(selector__circle);
const total = Math.PI * circle.r.baseVal.value;
circle.style.strokeDasharray = `${total*percent} ${total*(1-percent)*2}`;
document.querySelector('svg text').innerHTML = (percent*100).toFixed(0) + '%';
}
var number = 0;
setProgress(number, '.progressbar__thumb');
document.querySelector('.click__me').addEventListener('click', function() {
setProgress(number = number+0.1 > 1 ? 0 : number+0.1, '.progressbar__thumb');
});
.progress__container {
width: 140px;
height: 140px;
}
.progressbar__track {
fill: transparent;
stroke: #3E4153;
stroke-width: 3px;
}
.progressbar__thumb {
transform:
translate(32px,32px)
rotate(180deg)
translate(-32px,-32px);
fill: transparent;
stroke: yellow;
stroke-width: 4px;
transition: 0.2s;
}
.click__me {
margin-top: 10px;
margin-left: 35px;
}
<div class="progress__container">
<svg class="progressbar" viewbox="0 0 64 64">
<circle class="progressbar__track" cx="50%" cy="50%" r="30"></circle>
<circle class="progressbar__thumb" cx="50%" cy="50%" r="30"></circle>
<text x=32 y=32 text-anchor=middle dominant-baseline=middle></text>
</svg>
</div>
<button class="click__me">Click me</button>
Как я понял из рисунка, - анимация прогресс бара должна начинаться из одной точки синхронно двумя линиями и заканчиваться тоже в одной точке.
Расчет цифр в атрибуте stroke-dasharray
При радиусе окружности r="100"
длина окружности равна C= 2 * PI * R = 628,3
Половина окружности равна 314,15
Анимация линии достигается с помощью увеличения черты от нуля до максимума - 628,3
У атрибута stroke-dasharray
первый параметр это длина черты, второй параметр это длина пробела, поэтому:
Чтобы получить в начале нулевую длину черты записываем:
stroke-dasharray="0 314.15 0 314.15"
Длина черты 0
длина пробела -314.15
длина черты 0
длина пробела -314.15
, в итоге линию не будет видно.
Для максимального значения видимости линии нужно убрать пробелы :
stroke-dasharray=0 0 628.3 0
Для анимации линии записываем в values
эти два значения stroke-dasharray
values="0 314.15 0 314.15;0 0 628.3 0"
var btn = document.getElementById('btn');
var anim = document.getElementById('an');
btn.onclick = function () {
anim.beginElement();
}
<button id="btn">Begin</button>
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="250" height="250" viewBox="0 0 300 300" >
<!-- Серая окружность, показывающая трассировку анимации. При необходимости можно убрать -->
<circle cx="150" cy="150" r="100" stroke="#d3d3d3" stroke-width="6" fill="none" />
<!-- Окружность, реализующая прогресс бар -->
<circle cx="150" cy="150" r="100" stroke="purple" stroke-width="6" fill="none" stroke-dasharray="0 628.3" >
<animate id="an"
attributeName="stroke-dasharray"
values="0 314.15 0 314.15;0 0 628.3 0"
begin="indefinite"
dur="4s"
fill="freeze"/>
</circle>
</svg>
.container
{
width:50%;
height:50%;
background:black;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="#d3d3d3" stroke-width="10" />
<!-- Средняя точка начала анимации в центре слева stroke-dashoffset="31.1" -->
<path id="center" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="crimson" stroke-width="10" stroke-dashoffset="31.1" stroke-dasharray="0 128.5" >
<animate attributeName="stroke-dasharray" values="0 128.5 0 128.5;0 0 257 0" begin="btn_C.click" dur="4s" restart="whenNotActive" />
</path>
<!-- Средняя точка слева stroke-dashoffset="-159.5" -->
<path id="Left" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="yellowgreen" stroke-width="10" stroke-dashoffset="-159.5" stroke-dasharray="0 128.5" >
<animate attributeName="stroke-dasharray" values="0 128.5 0 128.5;0 0 257 0" begin="btn_L.click" dur="4s" restart="whenNotActive" />
</path>
<!-- Средняя точка слева сверху stroke-dashoffset="128.5" -->
<path id="Top" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="gold" stroke-width="10" stroke-dashoffset="128.5" stroke-dasharray="0 128.5" >
<animate attributeName="stroke-dasharray" values="0 128.5 0 128.5;0 0 257 0" begin="btn_T.click" dur="4s" restart="whenNotActive" />
</path>
<!-- Средняя точка справа внизу stroke-dashoffset="192.7" -->
<path id="Bottom" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="dodgerblue" stroke-width="10" stroke-dashoffset="192.7" stroke-dasharray="0 128.5" >
<animate attributeName="stroke-dasharray" values="0 128.5 0 128.5;0 0 257 0" begin="btn_B.click" dur="4s" restart="whenNotActive" />
</path>
<!-- Средняя точка справа stroke-dashoffset="223.9" -->
<path id="Bottom" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="purple" stroke-width="10" stroke-dashoffset="223.9" stroke-dasharray="0 128.5" >
<animate attributeName="stroke-dasharray" values="0 128.5 0 128.5;0 0 257 0" begin="btn_R.click" dur="4s" restart="whenNotActive" />
</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_C" transform="translate(3 0)">
<rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="#B2B2B2"/>
<text x="24" y="95" font-size="10" fill="crimson" >C</text>
</g>
<g id="btn_T" transform="translate(23 0)" >
<rect x="20" y="84" width="15" height="15" rx="7.5" fill="none" stroke="dodgerblue"/>
<text x="24" y="95" font-size="10" fill="orange" >T</text>
</g>
<g id="btn_B" transform="translate(43 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="dodgerblue" >B</text>
</g>
<g id="btn_R" transform="translate(63 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="purple" >R</text>
</g>
</svg>
</div>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть две Gulp задачиКогда я пытаюсь ввести предвыполнение pug:data перед pug, выполняется только pug:data
с JS знаком очень мало, в основном пытался что нибудь делать на JQКак это реализовать
У меня есть простой сайт и на нём я хочу предоставить юзерам возможность менять темы оформления, к примеру есть три файла: