Javascript. Формат переменной

91
24 июня 2021, 13:40

У меня два вопроса:

1) Я передаю в функцию circle: number - начальная позиция круга, final - конец круга, selector - объект, c которым я буду работать, найденный по селектору.
Получается так, что всем четырём круга передаются цифры, и они заполняются в правильном соотношении, но текст не выводится в трёх следующих кругах, а в первом выводится.
Вопрос: почему в первом круге всё выводится, а в следующих нет?

2) Я сделал анимацию с помощью .progressbar__thumb {transition: stroke-dasharray 0.05s linear} в СSS , а в JS таймер интервальный, который срабатывает раз в 50 миллисекунд, также как и transition.
В итоге получается заполнение круга не таким плавным, как хотелось бы.
Вопрос: возможно сделать заполнение как-то плавнее?

function setProgress(percent, selector__circle) { 
  let circle = document.querySelector(selector__circle); 
  let total = Math.PI * circle.r.baseVal.value; 
  circle.style.strokeDasharray = `${total*percent/100} ${total*(1-percent/100)*2}`; 
  document.querySelector('svg text').innerHTML = '<tspan>' + percent.toFixed(0) + '</tspan>%'; 
} 
 
function circle (number, final, selector) { 
	let timer = setInterval(function () { 
		setProgress(number, selector); 
		number += 1; 
		if (number == final) { 
			clearInterval(timer); 
		} 
	}, 50); 
} 
 
circle(0, 91, '.progress__container:nth-child(1) .progressbar__thumb'); 
circle(0, 81, '.progress__container:nth-child(2) .progressbar__thumb'); 
circle(0, 71, '.progress__container:nth-child(3) .progressbar__thumb'); 
circle(0, 91, '.progress__container:nth-child(4) .progressbar__thumb');
.cards__progress__bar { 
	display: -webkit-flex; 
	display: -moz-flex; 
	display: -ms-flex; 
	display: -o-flex; 
	display: flex; 
	-webkit-flex-wrap: wrap; 
	-moz-flex-wrap: wrap; 
	-ms-flex-wrap: wrap; 
	-o-flex-wrap: wrap; 
	flex-wrap: wrap; 
	justify-content: space-around; 
	max-width: 1000px; 
	margin: 0 auto; 
	margin-top: 80px; 
} 
 
.progress__container { 
	width: 150px; 
	height: 150px; 
	margin-bottom: 50px; 
} 
 
.progressbar__track { 
	fill: transparent; 
	stroke: #ededed; 
	stroke-width: 2px; 
} 
 
.progressbar__thumb { 
	fill: transparent; 
	stroke: #ff0036; 
	stroke-width: 2px; 
	transition: stroke-dasharray 0.05s linear; 
	transform-origin: center; 
	transform: rotate(180deg); 
} 
 
.progressbar text { 
	font-family: 'Lato', sans-serif; 
	font-weight: 400; 
} 
 
.progressbar text tspan { 
	fill: #ff0036; 
}
<div class="cards__progress__bar"> 
 
					<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=33 text-anchor=middle dominant-baseline=middle></text> 
					  </svg> 
					</div> <!-- .progress__container --> 
 
					<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=33 text-anchor=middle dominant-baseline=middle></text> 
					  </svg> 
					</div> <!-- .progress__container --> 
 
					<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=33 text-anchor=middle dominant-baseline=middle></text> 
					  </svg> 
					</div> <!-- .progress__container --> 
 
					<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=33 text-anchor=middle dominant-baseline=middle></text> 
					  </svg> 
					</div> <!-- .progress__container --> 
 
				</div> <!-- .cards__progress__bar -->

Answer 1

могу лишь ответить почему у Вас только в первом кругу заполняется текст. потому что в строке

document.querySelector('svg text').innerHTML = '<tspan>' + percent.toFixed(0) + '</tspan>%';

каждый раз меняется текст одного и того самого элемента. Это происходит потому что querySelector находит один ближайший ему найденный селектор в DOM, то есть в Вашем случае один и то же 'svg text' 4 раза подряд.

Answer 2

Вопрос: возможно сделать заполнение как-то плавнее?
Ответ: да, возможно, нужно использовать requestAnimationFrame вместо таймера.

function circle (number, final, selector) {
    let myReq = null;
    circleStep();
    function circleStep() {
        setProgress(number, selector);
        number += 1;
        if (number == final) {
            cancelAnimationFrame(myReq);
        }
        myReq = requestAnimationFrame(circleStep);
    }
}
READ ALSO
пропадает элемент, когда jquery объект конвертирую в массив

пропадает элемент, когда jquery объект конвертирую в массив

Снимок из лога сначала в объекте 4 элемента, потом получаю массив из DOM элементов, $itemslength так же 4, но консоль показывает, что длина массива...

90
Как удалить div при скролле страницы?

Как удалить div при скролле страницы?

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

95