Реализация SVG-анимаций (SMIL/CSS/JS) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация SVG-анимаций (SMIL/CSS/JS) на сайте
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация SVG-анимаций (SMIL/CSS/JS) на сайте

SVG-анимации существуют в трёх форматах, каждый со своей нишей. SMIL (Synchronized Multimedia Integration Language) — декларативные анимации внутри SVG-разметки, работают без JavaScript. CSS-анимации через @keyframes — для простых трансформаций. JavaScript через Web Animations API или GSAP — для интерактивных и управляемых сцен. Рассмотрим все три подхода с реальными примерами.

SMIL: анимации внутри SVG

SMIL-анимации описываются прямо в SVG-коде через теги <animate>, <animateTransform>, <animateMotion>:

<!-- public/animations/logo.svg -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- Анимация цвета заливки -->
  <circle cx="100" cy="100" r="50" fill="#3b82f6">
    <animate
      attributeName="fill"
      values="#3b82f6;#8b5cf6;#ec4899;#3b82f6"
      dur="3s"
      repeatCount="indefinite"
      calcMode="spline"
      keySplines="0.4 0 0.2 1; 0.4 0 0.2 1; 0.4 0 0.2 1"
    />
    <animate
      attributeName="r"
      values="50;45;50"
      dur="1.5s"
      repeatCount="indefinite"
    />
  </circle>

  <!-- Движение по пути -->
  <circle r="8" fill="white">
    <animateMotion
      dur="4s"
      repeatCount="indefinite"
      rotate="auto"
    >
      <mpath href="#orbit-path" />
    </animateMotion>
  </circle>

  <path
    id="orbit-path"
    d="M 100,30 A 70,70 0 1,1 99.9,30"
    fill="none"
    stroke="rgba(255,255,255,0.2)"
    stroke-width="1"
  />

  <!-- Морфинг формы через атрибут d -->
  <path fill="#f59e0b">
    <animate
      attributeName="d"
      dur="2s"
      repeatCount="indefinite"
      values="
        M 100,20 L 180,80 L 150,160 L 50,160 L 20,80 Z;
        M 100,10 L 190,90 L 160,170 L 40,170 L 10,90 Z;
        M 100,20 L 180,80 L 150,160 L 50,160 L 20,80 Z
      "
    />
  </path>
</svg>

SMIL работает во всех современных браузерах кроме IE (уже не актуально). Нет поддержки в Safari iOS для некоторых атрибутов — нужно тестировать.

CSS-анимации SVG

CSS подходит для трансформаций, opacity, stroke-анимаций. Важный момент: transform-origin в SVG работает не так, как в HTML — координаты относятся к SVG viewport:

/* styles/svg-animations.css */

/* Пульсирующий индикатор */
.pulse-ring {
  transform-origin: center;
  animation: pulse 2s ease-out infinite;
}

@keyframes pulse {
  0% { transform: scale(0.8); opacity: 1; }
  100% { transform: scale(2); opacity: 0; }
}

/* Отрисовка линии (stroke dasharray/dashoffset) */
.draw-path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 2s ease-in-out forwards;
}

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

/* Появление с задержкой для групп элементов */
.stagger-item {
  opacity: 0;
  transform: translateY(20px);
  animation: fadeUp 0.5s ease-out forwards;
}

.stagger-item:nth-child(1) { animation-delay: 0.1s; }
.stagger-item:nth-child(2) { animation-delay: 0.2s; }
.stagger-item:nth-child(3) { animation-delay: 0.3s; }

@keyframes fadeUp {
  to { opacity: 1; transform: translateY(0); }
}
// components/AnimatedLogo.tsx
export function AnimatedLogo() {
  return (
    <svg viewBox="0 0 100 100" className="w-16 h-16">
      {/* Фоновое кольцо */}
      <circle
        cx="50" cy="50" r="40"
        fill="none"
        stroke="#e5e7eb"
        strokeWidth="4"
      />
      {/* Анимированный прогресс */}
      <circle
        cx="50" cy="50" r="40"
        fill="none"
        stroke="#3b82f6"
        strokeWidth="4"
        strokeLinecap="round"
        className="draw-path"
        style={{ transformOrigin: '50px 50px', transform: 'rotate(-90deg)' }}
      />
    </svg>
  )
}

JavaScript: Web Animations API

Web Animations API — нативный JS без библиотек, хорошая производительность:

// utils/svg-animator.ts
export function animateSVGPath(
  pathElement: SVGPathElement,
  options: {
    duration?: number
    easing?: string
    delay?: number
  } = {}
): Animation {
  const length = pathElement.getTotalLength()

  pathElement.style.strokeDasharray = `${length}`
  pathElement.style.strokeDashoffset = `${length}`

  return pathElement.animate(
    [
      { strokeDashoffset: length },
      { strokeDashoffset: 0 },
    ],
    {
      duration: options.duration ?? 1500,
      easing: options.easing ?? 'ease-in-out',
      delay: options.delay ?? 0,
      fill: 'forwards',
    }
  )
}

export function animateSVGGroup(
  elements: SVGElement[],
  staggerMs = 100
): Animation[] {
  return elements.map((el, i) =>
    el.animate(
      [
        { opacity: 0, transform: 'translateY(20px)' },
        { opacity: 1, transform: 'translateY(0)' },
      ],
      {
        duration: 500,
        delay: i * staggerMs,
        easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
        fill: 'forwards',
      }
    )
  )
}

GSAP + SVG: продвинутый уровень

GSAP даёт максимальный контроль над SVG-анимациями, особенно для сложных временных линий:

// components/AnimatedDiagram.tsx
import { useEffect, useRef } from 'react'
import { gsap } from 'gsap'
import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin'

gsap.registerPlugin(DrawSVGPlugin)

export function AnimatedDiagram() {
  const svgRef = useRef<SVGSVGElement>(null)

  useEffect(() => {
    if (!svgRef.current) return

    const ctx = gsap.context(() => {
      const paths = svgRef.current!.querySelectorAll('.data-path')
      const nodes = svgRef.current!.querySelectorAll('.node')
      const labels = svgRef.current!.querySelectorAll('.label')

      const tl = gsap.timeline({ repeat: -1, repeatDelay: 2 })

      // Отрисовка путей последовательно
      tl.from(paths, {
        drawSVG: '0%',
        duration: 1.5,
        stagger: 0.3,
        ease: 'power2.inOut',
      })
      // Появление узлов
      .from(nodes, {
        scale: 0,
        opacity: 0,
        transformOrigin: 'center',
        stagger: 0.15,
        ease: 'back.out(2)',
        duration: 0.5,
      }, '-=0.5')
      // Появление подписей
      .from(labels, {
        opacity: 0,
        y: 10,
        stagger: 0.1,
        duration: 0.4,
      }, '-=0.3')
    }, svgRef)

    return () => ctx.revert()
  }, [])

  return (
    <svg ref={svgRef} viewBox="0 0 400 300">
      <path className="data-path" d="M 50,150 C 150,50 250,50 350,150" stroke="#3b82f6" strokeWidth="2" fill="none" />
      <circle className="node" cx="50" cy="150" r="8" fill="#3b82f6" />
      <circle className="node" cx="200" cy="80" r="8" fill="#8b5cf6" />
      <circle className="node" cx="350" cy="150" r="8" fill="#3b82f6" />
      <text className="label" x="50" y="170" textAnchor="middle" fontSize="12">Начало</text>
      <text className="label" x="350" y="170" textAnchor="middle" fontSize="12">Конец</text>
    </svg>
  )
}

Доступность SVG-анимаций

// Для декоративных анимаций
<svg aria-hidden="true" focusable="false">
  {/* ... */}
</svg>

// Для информативных
<svg role="img" aria-label="Анимированный прогресс загрузки 75%">
  <title>Загрузка файла</title>
  <desc>Прогресс-бар показывает 75% завершения загрузки</desc>
  {/* ... */}
</svg>

Respect prefers-reduced-motion:

@media (prefers-reduced-motion: reduce) {
  .draw-path,
  .pulse-ring,
  .stagger-item {
    animation: none;
  }
  .draw-path { stroke-dashoffset: 0; }
}

Типичные сроки

Простые CSS stroke-анимации для иконок — 2–4 часа. SMIL-анимации для логотипа/иллюстрации — 1 день. Сложная JS-анимированная диаграмма/инфографика с GSAP — 2–4 дня.