← Назад к вопросам

Как делать анимацию через JavaScript?

1.0 Junior🔥 111 комментариев
#JavaScript Core#Браузер и сетевые технологии

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

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

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

Как делать анимацию через JavaScript

Анимация через JavaScript — это мощный способ создания интерактивных и динамичных интерфейсов. Я покажу несколько методов от простых к сложным.

1. setTimeout и setInterval (Базовый способ)

Минусы: плохо для производительности, непредсказуем

// Плохой пример - не используй
let position = 0;
const interval = setInterval(() => {
  position += 1;
  element.style.left = position + 'px';
  
  if (position >= 100) {
    clearInterval(interval);
  }
}, 16); // ~60fps (1000/60 = ~16ms)

Проблемы:

  • Не синхронизирован с браузером (может пропустить кадры)
  • Продолжает работать, даже если tab не активный
  • Плохая производительность

2. requestAnimationFrame (RAF) — Рекомендуется

Это синхронизировано с браузером (идеально для анимаций)

// Хороший пример
let position = 0;
const startTime = Date.now();
const duration = 1000; // 1 секунда

function animate() {
  const elapsed = Date.now() - startTime;
  const progress = Math.min(elapsed / duration, 1);
  
  position = progress * 100; // 0 -> 100
  element.style.left = position + 'px';
  
  if (progress < 1) {
    requestAnimationFrame(animate);
  }
}

requestAnimationFrame(animate);

Плюсы RAF:

  • Синхронизирован с браузером (60fps или 120fps)
  • Паузится когда tab не активный
  • Оптимален для производительности
  • Браузер может оптимизировать

3. CSS Transitions и Animations (Самый простой способ)

Для простых анимаций — лучше использовать CSS

CSS Transitions

// JavaScript только триггерит, CSS делает работу
const element = document.querySelector('.box');

// Добавляем класс
element.classList.add('slide'); // Transition произойдёт

// CSS
style = `
  .box {
    position: relative;
    transition: all 0.3s ease; /* Браузер оптимизирует */
  }
  
  .box.slide {
    left: 100px;
  }
`;

CSS Animations

const element = document.querySelector('.box');
element.classList.add('bounce'); // Запускает анимацию

// CSS
style = `
  @keyframes bounce {
    0% { transform: translateY(0); }
    50% { transform: translateY(-20px); }
    100% { transform: translateY(0); }
  }
  
  .box.bounce {
    animation: bounce 0.5s ease;
  }
`;

4. Easing функции (Плавность анимации)

Без easing анимация выглядит неестественно

// Линейная (монотонная)
function easeLinear(progress) {
  return progress;
}

// Ease-in (медленно ускоряется)
function easeInQuad(progress) {
  return progress * progress;
}

// Ease-out (быстро замедляется)
function easeOutQuad(progress) {
  return progress * (2 - progress);
}

// Ease-in-out (медленно разгоняется и останавливается)
function easeInOutQuad(progress) {
  return progress < 0.5 
    ? 2 * progress * progress 
    : -1 + (4 - 2 * progress) * progress;
}

// Использование
function animate(duration, easing, callback) {
  const startTime = Date.now();
  
  function frame() {
    const elapsed = Date.now() - startTime;
    const progress = Math.min(elapsed / duration, 1);
    const easedProgress = easing(progress);
    
    callback(easedProgress);
    
    if (progress < 1) {
      requestAnimationFrame(frame);
    }
  }
  
  requestAnimationFrame(frame);
}

// Применение
animate(1000, easeOutQuad, (progress) => {
  element.style.left = (progress * 100) + 'px';
});

5. Web Animations API (Современный способ)

Объединяет лучшее от JS и CSS

const element = document.querySelector('.box');

// Определяем keyframes
const keyframes = [
  { transform: 'translateX(0)', offset: 0 },
  { transform: 'translateX(100px)', offset: 1 }
];

// Опции анимации
const options = {
  duration: 1000,      // 1 секунда
  easing: 'ease-out',  // встроенные easing функции
  fill: 'forwards',    // остаются ли стили после
  iterations: 1        // количество повторений
};

const animation = element.animate(keyframes, options);

// События
animation.onfinish = () => console.log('Done!');
animation.oncancel = () => console.log('Cancelled');

// Управление
animation.pause();
animation.play();
animation.reverse();
animation.playbackRate = 2; // 2x скорость

6. Spring Анимация (Реалистичная физика)

Используется в современном UI (iOS, Material Design)

class SpringAnimation {
  constructor(stiffness = 0.1, damping = 0.8) {
    this.stiffness = stiffness; // Жесткость пружины
    this.damping = damping;      // Трение
    this.velocity = 0;
  }
  
  update(current, target) {
    const distance = target - current;
    const force = distance * this.stiffness;
    this.velocity += force;
    this.velocity *= this.damping; // Применяем трение
    return current + this.velocity;
  }
}

// Использование
const spring = new SpringAnimation();
let value = 0;
const target = 100;

function frame() {
  value = spring.update(value, target);
  element.style.left = value + 'px';
  
  if (Math.abs(target - value) > 0.1) {
    requestAnimationFrame(frame);
  } else {
    element.style.left = target + 'px';
  }
}

requestAnimationFrame(frame);

7. Практический пример: React компонент с анимацией

import { useEffect, useRef } from 'react';

function AnimatedBox() {
  const boxRef = useRef(null);
  
  useEffect(() => {
    if (!boxRef.current) return;
    
    const element = boxRef.current;
    const startTime = Date.now();
    const duration = 1000;
    
    function animate() {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / duration, 1);
      const easing = progress * (2 - progress); // ease-out
      
      element.style.transform = `translateX(${easing * 100}px)`;
      
      if (progress < 1) {
        requestAnimationFrame(animate);
      }
    }
    
    requestAnimationFrame(animate);
  }, []);
  
  return (
    <div
      ref={boxRef}
      style={{
        width: '50px',
        height: '50px',
        backgroundColor: 'blue',
        position: 'relative'
      }}
    />
  );
}

8. Морфинг (Морфирование форм)

// SVG морфинг
const svg = document.querySelector('path');
const startPath = 'M10 10 L100 10 L100 100 Z'; // Треугольник
const endPath = 'M50 10 A40 40 0 0 1 50 90 A40 40 0 0 1 50 10'; // Круг

function morphPath(progress) {
  // Интерполируем между двумя path'ами
  // Это сложнее, используй библиотеку
}

9. Рекомендуемые библиотеки

GSAP (GreenSock Animation Platform)

import gsap from 'gsap';

// Анимирует свойство от 0 к 100
gsap.to(element, {
  duration: 1,
  left: 100,
  opacity: 0.5,
  ease: 'power2.out',
  onComplete: () => console.log('Done')
});

Framer Motion (для React)

import { motion } from 'framer-motion';

export function AnimatedBox() {
  return (
    <motion.div
      initial={{ x: 0 }}
      animate={{ x: 100 }}
      transition={{ duration: 1, ease: 'easeOut' }}
    />
  );
}

React Spring

import { useSpring, animated } from '@react-spring/web';

export function AnimatedBox() {
  const springs = useSpring({
    from: { x: 0 },
    to: { x: 100 },
    config: { tension: 300, friction: 60 }
  });
  
  return <animated.div style={springs} />;
}

Когда использовать каждый метод:

МетодКогда использоватьПроизводительность
CSS TransitionsПростые изменения состоянияОтличная
CSS AnimationsЦиклические анимацииОтличная
requestAnimationFrameКомплексная логикаХорошая
Web Animations APIСредняя сложностьОтличная
GSAPПрофессиональные анимацииОтличная
Framer MotionReact проектыХорошая
setTimeout/setIntervalНИКОГДА!Плохая

Лучшие практики:

1. Используй transform и opacity для анимаций

// Хорошо - браузер оптимизирует
element.style.transform = 'translateX(100px)';
element.style.opacity = 0.5;

// Плохо - вызывает reflow
element.style.left = '100px';
element.style.width = '100px';

2. Отключай анимации для пользователей с prefers-reduced-motion

const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

if (!prefersReduced) {
  // Запускай анимацию
}

3. Используй will-change для подсказки браузеру

element.style.willChange = 'transform';
// Анимируй...
element.style.willChange = 'auto'; // Отключи когда готово

Итоговый ответ:

Для анимаций через JavaScript:

  1. Начни с CSS (transitions/animations)
  2. Если нужна сложная логика, используй requestAnimationFrame
  3. Для React используй Framer Motion или React Spring
  4. Для профессиональных анимаций используй GSAP
  5. Никогда не используй setTimeout/setInterval для анимаций

Оптимизируй производительность: используй transform/opacity, избегай изменений layout.