Недавно я провел небольшое исследование того, как легко включить движение в наши веб-приложения, что, как правило, является второстепенным и никогда не ставится в приоритет. У меня в голове застряла фраза одного из наших дизайнеров: движение можно использовать, чтобы «порадовать» клиентов. Конечно, это не то же самое, что заставить продукт работать, но хорошо выполненное движение может действительно улучшить взаимодействие с пользователем, углубить их взаимодействие и, в конечном итоге, помочь вернуть их в будущем.

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

Что такое фреймерское движение?

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

Концепции

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

Реагировать на контекст

Маркеры и всплывающие подсказки связаны через контекст реакции. Провайдер предоставляет доступ к дочерним компонентам, чтобы определить, какую всплывающую подсказку показать / скрыть. Маркеры подключаются к этому провайдеру, чтобы установить текущую выбранную всплывающую подсказку. Всплывающие подсказки подключаются к поставщику, чтобы определить, показывать себя или нет.

Порталы

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

Стилизованные компоненты

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

Крючки

Для этого решения используется ряд обработчиков реагирования, в том числе useState для установки положения всплывающей подсказки на экране, useRef для доступа к всплывающим подсказкам, лежащим в основе элемента DOM, и useEffect и useLayoutEffect для управления отрисовкой компонентов.

Framer motion

Здесь и происходит настоящая анимация. Без него всплывающие подсказки работают, но выглядят не так хорошо. С помощью движения фреймера мы можем создавать всплывающие подсказки, которые анимируются, когда они входят в DOM и покидают его. Это делается с помощью компонента AnimatePresence. Вот фрагмент кода всплывающей подсказки.

const Component = (
  <AnimatePresence>
    {active && (
      <Tooltip
        ref={ref}
        position={position}
        {...motionProps}
      >
        {children}
      </Tooltip>
    )}
  </AnimatePresence>
);
return createPortal(Component, document.getElementById("tooltips"));

Компонент AnimatePresence оборачивает дочерний компонент и обрабатывает анимацию, когда он входит в DOM или выходит из нее. Как функции анимации обрабатываются опорой «motionProps», показанной ниже…

const variants = {
  active: {
    opacity: 1,
    y: 0,
    transition: {
      duration: 0.4,
      ease: "easeOut",
    },
  },
  inactive: {
    opacity: 0,
    y: -40,
    transition: {
      duration: 0.3,
    },
  },
};
export const motionProps = {
  variants,
  initial: "inactive",
  animate: "active",
  exit: "inactive",
};

Таким образом, один из способов обработки анимации входа / выхода - использовать варианты с последующим указанием того, какой вариант использовать для различных этапов (начальный, анимированный, выход). В приведенном выше коде говорится, что для начальной и выходной анимации элемент должен сместиться вверх на 40 пикселей, исчезнуть и что это должно занять 0,3 секунды. Когда он активен, он должен сместиться на 40 пикселей вниз, исчезнуть, и это займет 0,4 секунды. Для него также настроено ослабление, поэтому всплывающая подсказка немного замедляется по мере приближения к месту назначения.

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

Заключение

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

Ознакомьтесь с образцом репо, который показывает полный код (предостережение, работа еще не завершена 😉). Надеюсь, тебе понравится.