@FIain

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

Здравствуйте, столкнулся с такой проблемой. При каждом клике нужно добавить к прогресс бару 10%, они добавляются, но моментально, хотелось бы чтобы была плавная анимация. Я попытался реализовать это с помощью setInterval, но ничего не выходит.

Демонстрация проблемы:

63593fa558afa887421824.gif

JS:
let progressBar = document.querySelector(".progressbar");
let progressBarValue = document.querySelector(".progressbar__value");
const body = document.querySelector("body");

let progressBarStartValue = 0;
let progressBarEndValue = 100;
let speed = 50;

body.addEventListener("click", function(e) {
  if (progressBarStartValue === progressBarEndValue) {
    alert("you have completed all the tasks");
  } else {
    let progress = setInterval(() => {
      if (progressBarStartValue != 100) {
        progressBarStartValue += 10;
        clearInterval(progress);
      }
      progressBarValue.textContent = `${progressBarStartValue}%`;
      progressBar.style.background = `conic-gradient(
                #FFF ${progressBarStartValue * 3.6}deg,
                #262623 ${progressBarStartValue * 3.6}deg
            )`;
    }, speed);
  }
});


HTML:
<main class="main">
  <section class="statistic">
    <div class="container">
      <div class="statistic__inner">
        <div class="statistic__text">
          <h2 class="statistic__title">You're almost there!</h2>
          <p class="statistic__subtitle">keep up the good work</p>
        </div>
        <div class="progressbar"><span class="progressbar__value">0%</span></div>
      </div>
    </div>
  </section>
</main>


CSS:
.progressbar {
  position: relative;
  height: 150px;
  width: 150px;
  background-color: #262623;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.progressbar::before {
  content: "";
  position: absolute;
  height: 80%;
  width: 80%;
  background-color: #0f0f0f;
  border-radius: 50%;
}

.progressbar__value {
  color: #fff;
  z-index: 9;
  font-size: 25px;
  font-weight: 600;
}
  • Вопрос задан
  • 342 просмотра
Решения вопроса 1
RAX7
@RAX7
css transition не поддерживает анимацию градиентов.
На js это можно реализовать с помощью requestAnimationFrame
const lerp = (a, b, t) => a * (1 - t) + b * t;

// from: https://easings.net
const easeOutQuad = (x) => 1 - (1 - x) * (1 - x);

function tween(from, to, duration, onUpdate, easeFn) {
  let rafId = null;
  let begin;

  const loop = (now) => {
    begin ??= now;
    const progress = Math.min(1, (now - begin) / duration);
    const ease = easeFn ? easeFn(progress) : progress;
    const val = lerp(from, to, ease);

    onUpdate(val);

    if (progress === 1) {
      rafId = null;
      return;
    }

    rafId = requestAnimationFrame(loop);
  };

  rafId = requestAnimationFrame(loop);

  return () => rafId ?? cancelAnimationFrame(rafId);
}

const progressBar = document.querySelector(".progressbar");
const progressBarValue = document.querySelector(".progressbar__value");

const progressBarStartValue = 0;
const progressBarEndValue = 100;
const progressBarStep = 10;
const animationDuration = 1000;

let progressBarCurrentValue = progressBarStartValue;
let killTween = null;

function onUpdate(val) {
  progressBarValue.textContent = `${val.toFixed(1)}%`;
  progressBar.style.background = `conic-gradient(#FFF ${val * 3.6}deg, #262623 ${val * 3.6}deg)`;

  if (val === progressBarEndValue) {
    alert("you have completed all the tasks");
  }
}

document.body.addEventListener("click", (e) => {
  if (progressBarCurrentValue === progressBarEndValue) {
    alert("you have completed all the tasks");
  } else {
    const fromValue = progressBarCurrentValue;

    progressBarCurrentValue = Math.min(
      progressBarEndValue,
      progressBarCurrentValue + progressBarStep
    );

    killTween?.();
    killTween = tween(
      fromValue,
      progressBarCurrentValue,
      animationDuration,
      onUpdate,
      easeOutQuad
    );
  }
});
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
noder_ss
@noder_ss
Линуксоид-энтузиаст и SQL разработчик
Transition-duration: длительность перехода по типу 0.2s
Ответ написан
Комментировать
@grip_ers
Frontend Developer
Попробуй transition
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы