В библиотеке Motion One ключевые кадры (keyframes) представляют собой способ описания промежуточных состояний анимации через последовательность значений свойства. Синтаксис построен на идее декларативного перечисления значений, между которыми движется анимируемое свойство, без необходимости вручную описывать каждый шаг интерполяции.
Ключевые кадры задаются через массив значений или через массив объектов, где каждое значение соответствует состоянию анимации в определённый момент времени.
На уровне API animate ключевые кадры передаются вторым
аргументом:
import { animate } from "motion"
animate(element, {
x: [0, 200]
})
В этом случае библиотека автоматически интерполирует значение
x от 0 до 200.
Расширенная форма включает несколько промежуточных состояний:
animate(element, {
x: [0, 200, 100]
})
Здесь движение происходит от 0 к 200, затем возврат к 100.
Каждое анимируемое свойство может иметь собственный набор ключевых кадров. Синхронизация выполняется по индексу массива.
animate(element, {
x: [0, 200, 100],
opacity: [0, 1, 0.5]
})
x = 0, opacity = 0x = 200, opacity = 1x = 100, opacity = 0.5При различной длине массивов применяется нормализация временной шкалы, где значения распределяются пропорционально общей длительности.
Помимо массивов допускается объектная форма, где каждый кадр задаётся явно через набор объектов:
animate(element, {
keyframes: [
{ x: 0, opacity: 0 },
{ x: 200, opacity: 1 },
{ x: 100, opacity: 0.5 }
]
})
Такой синтаксис полезен при сложных анимациях, где важно зафиксировать состояние каждого кадра как единый снимок.
В Motion One поддерживается управление временной шкалой через
свойство offset. Оно позволяет привязывать ключевые кадры к
конкретным моментам анимации в диапазоне от 0 до 1.
animate(element, {
x: [0, 200, 100],
offset: [0, 0.7, 1]
})
В данном случае:
Использование offset обеспечивает точное распределение
ключевых кадров независимо от их количества.
Объектный стиль с offset позволяет комбинировать
значения более явно:
animate(element, {
keyframes: [
{ x: 0, opacity: 0, offset: 0 },
{ x: 200, opacity: 1, offset: 0.5 },
{ x: 100, opacity: 0.2, offset: 1 }
]
})
Такая форма объединяет декларацию состояния и временную позицию в одном объекте.
В Motion One трансформации могут задаваться как отдельными свойствами
или как строка transform.
animate(element, {
x: [0, 100, 50],
rotate: [0, 180, 90],
scale: [1, 1.5, 1]
})
Каждая трансформация интерполируется независимо, но синхронизированно по ключевым кадрам.
animate(element, {
transform: [
"translateX(0px) rotate(0deg)",
"translateX(100px) rotate(180deg)",
"translateX(50px) rotate(90deg)"
]
})
Такой синтаксис используется при необходимости полного контроля над итоговой матрицей трансформации.
Ключевые кадры в Motion One поддерживают различные типы значений:
0 → 100px, %,
remrgba, hex, hsldeg, radanimate(element, {
backgroundColor: ["#000000", "#ff0000", "#00ff00"],
rotate: ["0deg", "180deg", "360deg"],
x: ["0px", "200px", "50px"]
})
Интерполяция выполняется по типу значения, что позволяет смешивать сложные визуальные переходы без дополнительной логики.
Вместо статического массива допускается использование функции, возвращающей набор keyframes. Такой подход применяется при динамической генерации анимаций.
animate(element, (progress) => ({
x: [0, progress * 300, 100]
}))
Функциональная форма используется при необходимости привязки анимации к внешним данным или состоянию.
При несовпадении количества значений разных свойств применяется алгоритм распределения ключевых кадров:
animate(element, {
x: [0, 100],
opacity: [0, 1, 0.5, 0.2]
})
В этом случае временная шкала автоматически растягивается, чтобы все значения были учтены без потери синхронизации.
Хотя easing задаётся на уровне опций, его влияние распространяется на весь набор ключевых кадров:
animate(element, {
x: [0, 300, 150]
}, {
easing: "ease-in-out",
duration: 2
})
Все переходы между кадрами интерполируются согласно выбранной кривой времени.
При зацикливании ключевые кадры повторяются с сохранением последовательности значений:
animate(element, {
x: [0, 200, 0]
}, {
repeat: Infinity
})
Последний кадр может совпадать с первым для обеспечения плавного цикла без скачков значений.
Массивы ключевых кадров обрабатываются как дискретные точки функции времени. Между ними библиотека строит непрерывную кривую:
Такой подход позволяет использовать keyframes как компактное описание сложных траекторий движения и визуальных переходов без явного управления таймингом.