\n\n\n```\n\n### Рекомендация\n\n**Для 10 секунд лучший выбор - CSS transition + requestAnimationFrame для текста:**\n\n- Анимация эффективна (браузер оптимизирует)\n- Гладко выглядит\n- Простой код\n- Хорошо работает на слабых устройствах","dateCreated":"2026-04-02T22:24:10.838432","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как делать анимацию progress bar от 0 до 10 секунд через JavaScript?

1.0 Junior🔥 81 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Анимация Progress Bar за 10 секунд

Практический вопрос об анимации прогресса. Покажу несколько подходов от простого к сложному.

1. Простой подход с setInterval

const progressBar = document.getElementById('progress');
let progress = 0;
const duration = 10000; // 10 секунд в миллисекундах
const step = 100; // каждый шаг в миллисекундах
const increment = 100 / (duration / step); // сколько % за каждый шаг

const interval = setInterval(() => {
  progress += increment;
  
  if (progress >= 100) {
    progress = 100;
    clearInterval(interval);
  }
  
  progressBar.style.width = progress + '%';
  progressBar.textContent = Math.floor(progress) + '%';
}, step);

HTML:

<div class="progress-container">
  <div id="progress" class="progress-bar">0%</div>
</div>

CSS:

.progress-container {
  width: 100%;
  height: 30px;
  background-color: #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background-color: #4CAF50;
  transition: width 0.1s linear;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
}

2. С requestAnimationFrame (более гладкая анимация)

const progressBar = document.getElementById('progress');
const startTime = Date.now();
const duration = 10000; // 10 секунд

function animate() {
  const elapsed = Date.now() - startTime;
  const progress = Math.min((elapsed / duration) * 100, 100);
  
  progressBar.style.width = progress + '%';
  progressBar.textContent = Math.floor(progress) + '%';
  
  if (progress < 100) {
    requestAnimationFrame(animate);
  }
}

animate();

Преимущества requestAnimationFrame:

  • Синхронизируется с refresh rate экрана (60 fps)
  • Плавнее выглядит анимация
  • Автоматически оптимизируется браузером

3. С CSS transitions (самый элегантный)

const progressBar = document.getElementById('progress');

// Запускаем анимацию
setTimeout(() => {
  progressBar.style.transition = 'width 10s linear';
  progressBar.style.width = '100%';
}, 0);

// После завершения
setTimeout(() => {
  progressBar.textContent = '100%';
}, 10000);

CSS:

.progress-bar {
  height: 30px;
  background-color: #4CAF50;
  width: 0%;
  transition: width 10s linear; /* Определяем длительность в CSS */
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
}

Способ работает благодаря:

  • CSS transition handle анимацию (плавнее и эффективнее)
  • JavaScript только изменяет значение width
  • Браузер сам оптимизирует анимацию

4. С использованием timeouts для обновления текста

class ProgressBar {
  constructor(elementId, duration = 10000) {
    this.element = document.getElementById(elementId);
    this.duration = duration;
    this.startTime = null;
    this.animationId = null;
  }
  
  start() {
    this.startTime = Date.now();
    this.element.style.transition = `width ${this.duration}ms linear`;
    
    // Принудительно запускаем анимацию
    requestAnimationFrame(() => {
      this.element.style.width = '100%';
    });
    
    // Обновляем текст периодически
    this.updateText();
  }
  
  updateText() {
    const elapsed = Date.now() - this.startTime;
    const progress = Math.min((elapsed / this.duration) * 100, 100);
    this.element.textContent = Math.floor(progress) + '%';
    
    if (progress < 100) {
      setTimeout(() => this.updateText(), 100);
    }
  }
  
  stop() {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId);
    }
  }
}

// Использование
const progress = new ProgressBar('progress', 10000);
progress.start();

5. С easing функциями (ускорение/замедление)

// Linear (равномерная)
const easeLinear = (t) => t;

// Ease-in (медленное начало)
const easeInQuad = (t) => t * t;

// Ease-out (медленный конец)
const easeOutQuad = (t) => t * (2 - t);

// Ease-in-out (медленные начало и конец)
const easeInOutQuad = (t) => t < 0.5 ? 2*t*t : -1+(4-2*t)*t;

function animateProgress(elementId, duration, easingFunction = easeLinear) {
  const element = document.getElementById(elementId);
  const startTime = Date.now();
  
  function animate() {
    const elapsed = Date.now() - startTime;
    const progress = Math.min(elapsed / duration, 1);
    const eased = easingFunction(progress);
    const percentage = eased * 100;
    
    element.style.width = percentage + '%';
    element.textContent = Math.floor(percentage) + '%';
    
    if (progress < 1) {
      requestAnimationFrame(animate);
    }
  }
  
  animate();
}

// Использование с easing
animateProgress('progress', 10000, easeOutQuad);

6. React компонент

import React, { useState, useEffect } from 'react';

function ProgressBar({ duration = 10000 }) {
  const [progress, setProgress] = useState(0);
  
  useEffect(() => {
    const startTime = Date.now();
    
    const interval = setInterval(() => {
      const elapsed = Date.now() - startTime;
      const newProgress = Math.min((elapsed / duration) * 100, 100);
      
      setProgress(newProgress);
      
      if (newProgress >= 100) {
        clearInterval(interval);
      }
    }, 50);
    
    return () => clearInterval(interval);
  }, [duration]);
  
  return (
    <div className="progress-container">
      <div 
        className="progress-bar"
        style={{ width: progress + '%' }}
      >
        {Math.floor(progress)}%
      </div>
    </div>
  );
}

Сравнение подходов

ПодходПлюсыМинусы
setIntervalПростой, контрольМожет быть рывкав, CPU
requestAnimationFrameГладко, оптимизированоЧуть сложнее
CSS transitionЭффективно, плавноМеньше контроля
ClassПереиспользуемый, чистыйБольше кода
ReactИнтеграция с компонентомНужен React

Полный практический пример

<!DOCTYPE html>
<html>
<head>
  <style>
    .progress-container {
      width: 100%;
      max-width: 500px;
      height: 30px;
      background-color: #e0e0e0;
      border-radius: 4px;
      overflow: hidden;
      margin: 20px 0;
    }
    
    .progress-bar {
      height: 100%;
      background: linear-gradient(90deg, #4CAF50, #45a049);
      width: 0%;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      transition: width 0.1s linear;
    }
  </style>
</head>
<body>
  <h1>Progress Bar: 10 секунд</h1>
  
  <div class="progress-container">
    <div id="progress" class="progress-bar">0%</div>
  </div>
  
  <button onclick="startProgress()">Начать</button>
  <button onclick="stopProgress()">Остановить</button>
  
  <script>
    let animationId = null;
    let startTime = null;
    const progressBar = document.getElementById('progress');
    const duration = 10000;
    
    function startProgress() {
      startTime = Date.now();
      animate();
    }
    
    function animate() {
      const elapsed = Date.now() - startTime;
      const progress = Math.min((elapsed / duration) * 100, 100);
      
      progressBar.style.width = progress + '%';
      progressBar.textContent = Math.floor(progress) + '%';
      
      if (progress < 100) {
        animationId = requestAnimationFrame(animate);
      }
    }
    
    function stopProgress() {
      cancelAnimationFrame(animationId);
    }
  </script>
</body>
</html>

Рекомендация

Для 10 секунд лучший выбор - CSS transition + requestAnimationFrame для текста:

  • Анимация эффективна (браузер оптимизирует)
  • Гладко выглядит
  • Простой код
  • Хорошо работает на слабых устройствах