Создание собственных пресетов

В Velocity.js повторяющиеся анимации удобно инкапсулировать в виде переиспользуемых конфигураций. Такой подход позволяет стандартизировать поведение интерфейсных элементов и уменьшить дублирование кода.

Под «пресетом» в контексте Velocity.js обычно понимается заранее определённый набор параметров анимации или зарегистрированный эффект, который можно вызывать по имени вместо передачи полного объекта настроек.

Ключевая цель:

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

Регистрация пользовательских эффектов через RegisterEffect

Основной механизм создания пресетов — $.Velocity.RegisterEffect.

Базовая структура:

$.Velocity.RegisterEffect("preset.slideFadeIn", {
    defaultDuration: 400,
    calls: [
        [
            { opacity: 1, translateY: 0 },
            1,
            { easing: "ease-out" }
        ]
    ]
});

Разбор структуры

  • "preset.slideFadeIn" — имя эффекта, которое будет использоваться при вызове
  • defaultDuration — длительность по умолчанию
  • calls — массив шагов анимации

Каждый шаг внутри calls описывается тройкой:

[
  свойства,
  доля_времени,
  опции
]

Простейший пресет появления

Создание базового пресета появления элемента:

$.Velocity.RegisterEffect("preset.fadeIn", {
    defaultDuration: 300,
    calls: [
        [
            { opacity: 1 },
            1
        ]
    ]
});

Использование:

$(".box").velocity("preset.fadeIn");

Такой подход заменяет повторяющиеся блоки:

$(".box").velocity({ opacity: 1 }, 300);

Пресеты с несколькими шагами

Многосоставные анимации позволяют строить более выразительные эффекты.

Пример «всплытия»:

$.Velocity.RegisterEffect("preset.popIn", {
    defaultDuration: 600,
    calls: [
        [
            { scale: 0.8, opacity: 0 },
            0.4
        ],
        [
            { scale: 1.05, opacity: 1 },
            0.3
        ],
        [
            { scale: 1 },
            0.3
        ]
    ]
});

Логика выполнения

  • первый шаг: стартовое состояние
  • второй шаг: overshoot (перепрыгивание)
  • третий шаг: стабилизация

Такой подход имитирует физику пружины без использования сложных физ-движков.


Параметризация пресетов

Пресеты можно делать динамическими через функции.

$.Velocity.RegisterEffect("preset.slideFrom", function(elements, options) {
    return {
        defaultDuration: options.duration || 500,
        calls: [
            [
                {
                    translateX: options.from || -100,
                    opacity: 0
                },
                0
            ],
            [
                {
                    translateX: 0,
                    opacity: 1
                },
                1,
                {
                    easing: options.easing || "ease-out"
                }
            ]
        ]
    };
});

Использование:

$(".item").velocity("preset.slideFrom", {
    duration: 700,
    from: -200,
    easing: "ease-in-out"
});

Преимущество подхода

  • один пресет — множество вариантов поведения
  • возможность адаптации под контекст
  • отсутствие дублирования эффектов

Создание библиотеки пресетов

При масштабировании интерфейса пресеты группируются в единый слой абстракции.

Пример структуры:

const MotionPresets = {
    fade: "preset.fadeIn",
    pop: "preset.popIn",
    slideLeft: "preset.slideFromLeft",
    slideRight: "preset.slideFromRight"
};

Использование:

$(".card").velocity(MotionPresets.pop);

Такой уровень абстракции полезен в крупных приложениях, где десятки компонентов используют одни и те же типы анимаций.


Комбинирование пресетов и цепочек

Velocity.js поддерживает последовательные вызовы, что позволяет комбинировать эффекты.

$(".panel")
    .velocity("preset.fadeIn", { duration: 200 })
    .velocity("preset.slideFrom", { duration: 400, from: 50 });

Каждый вызов выполняется после завершения предыдущего.


Использование easing внутри пресетов

Easing играет ключевую роль в восприятии анимации.

Пример пресета с нестандартной кривой:

$.Velocity.RegisterEffect("preset.softEntrance", {
    defaultDuration: 500,
    calls: [
        [
            { opacity: 0, translateY: 20 },
            0
        ],
        [
            { opacity: 1, translateY: 0 },
            1,
            { easing: [0.25, 0.1, 0.25, 1] }
        ]
    ]
});

Кубическая кривая Безье позволяет добиться более «живого» движения по сравнению с стандартными ease-in и ease-out.


Пресеты с масштабированием интерфейсных компонентов

Для UI часто применяются эффекты появления карточек:

$.Velocity.RegisterEffect("preset.cardAppear", {
    defaultDuration: 350,
    calls: [
        [
            { opacity: 0, scale: 0.95 },
            0
        ],
        [
            { opacity: 1, scale: 1 },
            1,
            { easing: "ease-out" }
        ]
    ]
});

Использование:

$(".card").velocity("preset.cardAppear");

Такая анимация создаёт ощущение лёгкого «подъёма» интерфейса без перегрузки визуального восприятия.


Стagger-анимации как часть пресета

Velocity позволяет работать с задержками элементов.

Пример:

$(".list-item").velocity({
    opacity: 1,
    translateX: 0
}, {
    duration: 300,
    stagger: 80
});

Это можно обернуть в концепцию пресета через функцию:

$.Velocity.RegisterEffect("preset.staggerFadeIn", function(elements, options) {
    return {
        defaultDuration: 300,
        stagger: options.stagger || 50,
        calls: [
            [
                { opacity: 0, translateX: -10 },
                0
            ],
            [
                { opacity: 1, translateX: 0 },
                1
            ]
        ]
    };
});

Переиспользование сложных анимационных сценариев

В реальных интерфейсах пресеты часто моделируют сценарии:

  • открытие модального окна
  • появление уведомлений
  • переключение вкладок
  • раскрытие аккордеонов

Пример модального окна:

$.Velocity.RegisterEffect("preset.modalOpen", {
    defaultDuration: 250,
    calls: [
        [
            { opacity: 0, scale: 0.9 },
            0
        ],
        [
            { opacity: 1, scale: 1 },
            1,
            { easing: "ease-out" }
        ]
    ]
});

Архитектурный подход к пресетам

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

Рекомендуемая организация:

  • базовые эффекты (fade, slide, scale)
  • UI-компонентные эффекты (card, modal, tooltip)
  • сценарные эффекты (workflow transitions)
  • комбинированные эффекты (sequence presets)

Такое разделение предотвращает хаос в анимационной логике.


Конфликты и переопределения пресетов

При регистрации эффектов важно учитывать уникальность имен.

$.Velocity.RegisterEffect("preset.fadeIn", { ... });
$.Velocity.RegisterEffect("preset.fadeIn", { ... });

Последнее определение перезапишет предыдущее.

Поэтому часто используется неймспейс:

preset.ui.fadeIn
preset.layout.fadeIn
preset.modal.fadeIn

Производительность при использовании пресетов

Хотя пресеты упрощают разработку, они не отменяют стоимость анимаций.

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

  • минимизация количества одновременно анимируемых свойств
  • предпочтение transform и opacity
  • избегание layout-triggering свойств (width, height, top)
  • контроль параллельных анимаций

Оптимизированный пресет:

$.Velocity.RegisterEffect("preset.fastFade", {
    defaultDuration: 200,
    calls: [
        [
            { opacity: 1 },
            1
        ]
    ]
});

Инкапсуляция сложных сцен

Иногда пресет включает целый сценарий поведения UI:

$.Velocity.RegisterEffect("preset.notificationIn", function(elements, options) {
    return {
        defaultDuration: 400,
        calls: [
            [
                { opacity: 0, translateY: -20 },
                0
            ],
            [
                { opacity: 1, translateY: 0 },
                1,
                { easing: "ease-out" }
            ]
        ]
    };
});

Подобные эффекты позволяют описывать поведение интерфейса как единый атомарный блок.


Композиция пресетов

Пресеты можно комбинировать логически:

function showCard($el) {
    $el
        .velocity("preset.cardAppear")
        .velocity("preset.staggerFadeIn");
}

Так создаётся многоуровневая система анимаций, где каждый эффект отвечает за отдельную визуальную задачу.


Динамическое управление параметрами

Расширение пресетов через options позволяет управлять поведением без изменения определения:

$(".toast").velocity("preset.notificationIn", {
    duration: 600,
    easing: "ease-in-out"
});

Такая модель обеспечивает гибкость без потери структуры.


Стандартизация именования

Для масштабируемых систем применяется строгая схема:

  • preset.ui.*
  • preset.motion.*
  • preset.transition.*
  • preset.element.*

Это предотвращает пересечение логики и упрощает навигацию по коду.