CSS animations

Atomico предоставляет возможность использовать CSS-анимации напрямую в компонентах, сохраняя при этом декларативный подход и реактивность. Основой для управления стилями в Atomico служит функция css и встроенные свойства компонента. Анимации можно применять как к обычным стилям, так и к динамически изменяемым значениям через реактивные состояния.

Определение анимаций

CSS-анимации в Atomico задаются с использованием стандартного синтаксиса @keyframes. В компоненте их можно подключать через css:

import { c, css } from "atomico";

const fadeIn = css`
    @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
    }

    .fade-in {
        animation: fadeIn 1s ease-in-out forwards;
    }
`;

function FadeComponent() {
    return <host shadowDom>
        <div class="fade-in">Пример анимации</div>
    </host>;
}

FadeComponent.styles = [fadeIn];

customElements.define("fade-component", FadeComponent);

Ключевые моменты:

  • @keyframes определяет промежуточные состояния анимации.
  • Класс .fade-in применяет анимацию к элементу.
  • Атрибут forwards в animation сохраняет конечное состояние анимации после её завершения.

Анимация на основе состояний

Atomico позволяет связывать анимацию с реактивными состояниями компонента через useState:

import { c, useState, css } from "atomico";

const slideAnimation = css`
    @keyframes slideRight {
        from { transform: translateX(0); }
        to { transform: translateX(100px); }
    }

    .slide {
        animation: slideRight 0.5s ease-in-out forwards;
    }
`;

function SlideComponent() {
    const [active, setActive] = useState(false);

    return (
        <host shadowDom>
            <button onCl ick={() => setActive(!active)}>Сдвинуть</button>
            <div class={active ? "slide" : ""}>Сдвигаемый блок</div>
        </host>
    );
}

SlideComponent.styles = [slideAnimation];

customElements.define("slide-component", SlideComponent);

Особенности подхода:

  • Состояние active управляет применением класса с анимацией.
  • Анимация запускается при изменении состояния, что обеспечивает реактивный и управляемый эффект.

Переходы между стилями

Atomico поддерживает плавные CSS-переходы (transition) для изменения свойств без ключевых кадров:

import { c, useState, css } from "atomico";

const hoverTransition = css`
    .box {
        width: 100px;
        height: 100px;
        background: red;
        transition: background 0.3s ease, transform 0.3s ease;
    }

    .box.active {
        background: green;
        transform: scale(1.2);
    }
`;

function TransitionComponent() {
    const [active, setActive] = useState(false);

    return (
        <host shadowDom>
            <div class={`box ${active ? "active" : ""}`} 
                 onCl ick={() => setActive(!active)}></div>
        </host>
    );
}

TransitionComponent.styles = [hoverTransition];

customElements.define("transition-component", TransitionComponent);

Пояснения:

  • Свойство transition задаёт плавное изменение параметров.
  • Изменение класса через состояние инициирует плавное преобразование.
  • Такой метод предпочтителен для простых эффектов без сложной синхронизации.

Анимации с динамическими стилями

Можно создавать анимации, основанные на переменных JavaScript, через шаблонные строки и реактивные значения:

import { c, useState, css } from "atomico";

function DynamicAnimation() {
    const [distance, setDistance] = useState(50);

    const dynamicStyle = css`
        .dynamic {
            transform: translateX(${distance}px);
            transition: transform 0.5s ease;
        }
    `;

    return (
        <host shadowDom>
            <button onCl ick={() => setDistance(distance + 20)}>Сдвинуть</button>
            <div class="dynamic">Динамический блок</div>
        </host>
    );
}

customElements.define("dynamic-animation", DynamicAnimation);

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

  • Анимация полностью управляется реактивным состоянием.
  • Нет необходимости писать отдельные ключевые кадры.
  • Позволяет интегрировать анимации с логикой компонента.

Комбинирование анимаций и слотов

Atomico поддерживает применение анимаций ко вложенным элементам через слоты, сохраняя инкапсуляцию стилей:

import { c, css } from "atomico";

const slotAnimation = css`
    @keyframes fadeUp {
        from { opacity: 0; transform: translateY(20px); }
        to { opacity: 1; transform: translateY(0); }
    }

    ::slotted(*) {
        animation: fadeUp 0.4s ease forwards;
    }
`;

function SlotComponent() {
    return (
        <host shadowDom>
            <slot></slot>
        </host>
    );
}

SlotComponent.styles = [slotAnimation];

customElements.define("slot-component", SlotComponent);

Особенности применения:

  • Псевдокласс ::slotted позволяет анимировать элементы, переданные через <slot>.
  • Анимация работает только внутри Shadow DOM, сохраняя инкапсуляцию.

Итоговые рекомендации по анимациям в Atomico

  • Для повторяющихся и сложных эффектов использовать @keyframes.
  • Для простых переходов и изменений состояния — transition.
  • Реактивные состояния позволяют запускать анимации на события или динамические изменения данных.
  • Стилизация слотов обеспечивает анимацию вложенных компонентов без утечки стилей.

Atomico интегрирует CSS-анимации в реактивную модель компонентов, обеспечивая чистый и управляемый подход к динамическому отображению интерфейса.