SVG анимации

Основы работы с SVG в Solid.js

SVG (Scalable Vector Graphics) представляет собой формат для описания двухмерной векторной графики. Веб-разработчики используют SVG для отображения графики на веб-страницах, так как он позволяет создавать масштабируемые и легко редактируемые изображения. В Solid.js использование SVG не отличается от стандартного HTML, и компоненты SVG можно встраивать прямо в JSX-разметку.

Анимации в SVG

Анимация в SVG может быть реализована несколькими способами: с помощью CSS, JavaScript или встроенных анимационных элементов в самом SVG. Для создания анимации в Solid.js предпочтительнее использовать JavaScript и реактивную модель данных, которая позволяет изменять свойства SVG-элементов в ответ на изменения состояния компонента.

Анимация с использованием CSS

Первый и наиболее простой способ анимации SVG — это использование CSS-анимаций. Пример:

import { createSignal } from "solid-js";

function AnimatedCircle() {
  const [isHovered, setHovered] = createSignal(false);

  return (
    <svg width="100" height="100">
      <circle
        cx="50"
        cy="50"
        r="40"
        stroke="black"
        stroke-width="3"
        fill={isHovered() ? "red" : "blue"}
        onMouseEn ter={() => setHovered(true)}
        onMouseLe ave={() => setHovered(false)}
      />
    </svg>
  );
}

export default AnimatedCircle;

В данном примере цвет круга изменяется при наведении курсора. Реактивность в Solid.js позволяет без труда отслеживать состояния и обновлять атрибуты SVG в зависимости от этих состояний.

Для создания более сложных анимаций можно использовать ключевые кадры CSS:

@keyframes scaleAnimation {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.5);
  }
}

И применить её к SVG-элементу:

import { createSignal } from "solid-js";

function ScaledCircle() {
  const [isClicked, setClicked] = createSignal(false);

  return (
    <svg width="100" height="100">
      <circle
        cx="50"
        cy="50"
        r="40"
        fill="blue"
        onCl ick={() => setClicked(!isClicked())}
        style={{
          animation: isClicked() ? "scaleAnimation 0.5s forwards" : "none",
        }}
      />
    </svg>
  );
}

export default ScaledCircle;

В этом примере при клике на круг он будет увеличиваться с помощью CSS-анимации.

Анимация с помощью JavaScript

Иногда анимации SVG требуют более сложных взаимодействий или динамического изменения атрибутов. В таких случаях можно использовать JavaScript для анимации.

Используя requestAnimationFrame для создания анимации, можно добиться плавных изменений свойств SVG. Пример:

import { createSignal, onCleanup } from "solid-js";

function AnimatedLine() {
  const [lineLength, setLineLength] = createSignal(0);

  let lineRef;

  function animate() {
    if (lineLength() < 100) {
      setLineLength(lineLength() + 1);
      requestAnimationFrame(animate);
    }
  }

  // Начать анимацию при монтировании компонента
  onCleanup(() => {
    setLineLength(0);
  });

  return (
    <svg width="200" height="200">
      <line
        ref={lineRef}
        x1="0"
        y1="0"
        x2="200"
        y2="200"
        stroke="black"
        stroke-width="2"
        stroke-dasharray="100"
        stroke-dashoffset={100 - lineLength()}
      />
      <button onCl ick={animate}>Start Animation</button>
    </svg>
  );
}

export default AnimatedLine;

Здесь линия постепенно появляется, начиная с 0 и достигая своей полной длины. Анимация контролируется с помощью JavaScript, что дает большую гибкость, позволяя изменять любые атрибуты SVG.

Реактивные анимации

Одной из сильных сторон Solid.js является реактивность, которая делает создание анимаций простым и интуитивно понятным. Пример с анимацией, основанной на изменении данных, может выглядеть так:

import { createSignal } from "solid-js";

function BounceCircle() {
  const [yPosition, setYPosition] = createSignal(0);
  let interval;

  function startBounce() {
    interval = setInterval(() => {
      setYPosition((prev) => (prev === 0 ? 100 : 0));
    }, 500);
  }

  function stopBounce() {
    clearInterval(interval);
  }

  return (
    <svg width="100" height="200">
      <circle
        cx="50"
        cy={yPosition()}
        r="30"
        fill="green"
        onCl ick={startBounce}
        onMouse Out={stopBounce}
      />
    </svg>
  );
}

export default BounceCircle;

Здесь круг будет “прыгать” вверх и вниз, изменяя свойство cy на основе состояния. Анимация будет выполняться при клике на круг и остановится, когда курсор выйдет из области SVG.

Работа с анимациями и таймерами

Взаимодействие с таймерами и анимациями SVG через Solid.js дает возможность гибко управлять временем и состоянием анимации. Например, можно использовать setTimeout для плавных переходов или задержек в анимациях:

import { createSignal } from "solid-js";

function DelayedAnimation() {
  const [opacity, setOpacity] = createSignal(0);

  function startAnimation() {
    setTimeout(() => {
      setOpacity(1);
    }, 1000);
  }

  return (
    <svg width="100" height="100">
      <circle
        cx="50"
        cy="50"
        r="40"
        fill="orange"
        opacity={opacity()}
        onCl ick={startAnimation}
      />
    </svg>
  );
}

export default DelayedAnimation;

Здесь анимация плавного появления круга начинается через 1 секунду после клика.

Заключение

SVG-анимации в Solid.js открывают широкие возможности для динамических и реактивных интерфейсов. С помощью базовых методов CSS и JavaScript можно создавать различные типы анимаций, от простых до сложных. Использование реактивных сигналов Solid.js позволяет легко управлять состоянием анимации и интегрировать её в компоненты, что делает Solid.js отличным инструментом для создания интерактивных анимационных элементов.