Media queries и анимации

Анимационная система в Motion One опирается на идею тесной интеграции с условиями среды браузера. Медиа-запросы становятся частью логики анимации, позволяя динамически изменять параметры движения в зависимости от размеров экрана, предпочтений пользователя и состояния устройства.

Ключевая особенность заключается в том, что анимация перестаёт быть фиксированной последовательностью значений и превращается в адаптивное поведение, которое пересобирается при изменении условий отображения.

Принцип адаптивной анимации

Медиа-запросы в анимации работают как слой условий, определяющий набор свойств:

  • ширина и высота окна
  • ориентация устройства
  • плотность пикселей
  • системные предпочтения (например, уменьшенное движение)
  • произвольные CSS media queries

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

Базовая структура медиа-условий

Анимации строятся вокруг конфигурации, где ключом выступает media query строка, а значением — параметры трансформации.

import { animate } from "motion";

animate(".box", {
  x: {
    "(min-width: 768px)": 300,
    "(max-width: 767px)": 100
  },
  opacity: 1
});

В этой модели одно свойство может иметь несколько вариантов значений, зависящих от состояния viewport.

Разделение анимаций по брейкпоинтам

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

import { animate } from "motion";

animate(".card", {
  x: 0,
  scale: 1,
  opacity: 1
}, {
  media: {
    "(min-width: 1024px)": {
      x: 200,
      scale: 1.1
    },
    "(min-width: 768px) and (max-width: 1023px)": {
      x: 100,
      scale: 1.05
    },
    "(max-width: 767px)": {
      x: 0,
      scale: 1
    }
  }
});

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

Приоритет и пересечение условий

При наличии нескольких совпадающих медиа-условий применяется наиболее специфичное правило. Это поведение аналогично каскадности CSS:

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

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

Системные предпочтения пользователя

Особое значение имеет адаптация под настройки операционной системы. Одним из ключевых медиа-условий является prefers-reduced-motion.

import { animate } from "motion";

animate(".element", {
  x: 200,
  rotate: 360
}, {
  media: {
    "(prefers-reduced-motion: reduce)": {
      x: 0,
      rotate: 0
    }
  }
});

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

Комбинирование медиазапросов с временными анимациями

Медиа-условия могут влиять не только на конечные значения, но и на характер анимации: длительность, easing и задержки.

import { animate } from "motion";

animate(".panel", {
  opacity: 1,
  y: 0
}, {
  media: {
    "(min-width: 1024px)": {
      duration: 0.8,
      easing: "ease-out"
    },
    "(max-width: 1023px)": {
      duration: 0.3,
      easing: "linear"
    }
  }
});

Таким образом один и тот же эффект движения может иметь разную кинетику в зависимости от контекста устройства.

Реакция на изменение состояния viewport

Анимации в Motion One автоматически пересчитываются при изменении размеров окна. Это означает:

  • повторная проверка media queries
  • обновление активных анимационных параметров
  • корректировка текущего состояния без перезапуска логики вручную

При изменении брейкпоинта анимация не обрывается, а плавно переходит в новое состояние.

Множественные свойства с независимыми условиями

Каждое свойство может иметь собственную логику адаптации:

import { animate } from "motion";

animate(".item", {
  x: {
    "(min-width: 1200px)": 400,
    "(min-width: 768px)": 200,
    "(max-width: 767px)": 0
  },
  opacity: {
    "(min-width: 768px)": 1,
    "(max-width: 767px)": 0.5
  },
  scale: 1
});

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

Интеграция с layout-изменениями

Медиа-запросы часто совпадают с изменениями сетки интерфейса. Анимации используются как связующее звено между layout-состояниями.

Типовые сценарии:

  • переход от grid к stacked layout
  • изменение количества колонок
  • изменение размеров карточек
  • перераспределение контента

Анимация компенсирует резкие изменения DOM, делая переходы визуально непрерывными.

Динамическая композиция анимаций

Медиа-условия могут влиять на состав анимации, включая добавление или исключение отдельных свойств:

import { animate } from "motion";

animate(".modal", {
  opacity: 1,
  scale: 1,
  filter: {
    "(min-width: 1024px)": "blur(0px)",
    "(max-width: 1023px)": "blur(2px)"
  }
});

Фильтры и трансформации становятся частью адаптивного слоя, изменяющего визуальную плотность интерфейса.

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

Использование медиа-запросов в анимациях требует учёта стоимости пересчёта состояний:

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

Оптимальная стратегия заключается в минимизации количества пересекающихся условий и использовании стабильных брейкпоинтов.

Сочетание с пользовательскими событиями

Медиа-условия могут комбинироваться с интерактивными триггерами:

  • hover
  • focus
  • scroll-based анимации
  • pointer events

При этом медиа-запрос задаёт базовую модель поведения, а события уточняют локальные изменения состояния.

import { animate } from "motion";

const element = document.querySelector(".box");

animate(element, {
  scale: {
    "(min-width: 768px)": 1.2,
    "(max-width: 767px)": 1
  }
});

element.addEventListener("mouseenter", () => {
  animate(element, { rotate: 10 });
});

Иерархия адаптивных слоёв

В сложных интерфейсах формируется несколько уровней управления анимацией:

  1. базовое состояние (default)
  2. медиа-запросы
  3. пользовательские события
  4. программные изменения состояния

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

Стабилизация анимационного состояния

При смене медиа-условий важно сохранять консистентность текущего состояния. В Motion One переходы между условиями не сбрасывают прогресс анимации, а пересчитывают целевые значения относительно текущего положения элемента.

Это исключает резкие скачки и обеспечивает непрерывность визуального движения даже при резком изменении viewport.