Transition и animation

Interact.js предоставляет мощный набор инструментов для создания интерактивных элементов с поддержкой drag-and-drop, resizable и gesturable компонентов. Одним из ключевых аспектов является управление переходами (transitions) и анимацией (animations), что позволяет создавать плавные и визуально привлекательные интерфейсы.


Управление CSS-переходами

Interact.js напрямую не управляет CSS-анимациями, однако интеграция с CSS-переходами позволяет создавать эффектные взаимодействия. Основной подход — использование событий drag, move, end для изменения стилей элемента с включённым CSS transition.

Пример базового перехода при перетаскивании:

interact('.draggable')
  .draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    listeners: {
      start (event) {
        event.target.style.transition = 'transform 0.2s ease';
      },
      move (event) {
        const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy;

        event.target.style.transform = `translate(${x}px, ${y}px)`;

        event.target.setAttribute('data-x', x);
        event.target.setAttribute('data-y', y);
      },
      end (event) {
        event.target.style.transition = '';
      }
    }
  });

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

  • transition применяется только на время движения, что позволяет добавить плавность при отпускании элемента.
  • inertia: true создаёт эффект инерции, плавное замедление после завершения drag.
  • modifiers ограничивают область перемещения элемента, предотвращая выход за границы.

Анимация при завершении взаимодействия

Для более сложных анимаций можно использовать requestAnimationFrame или CSS-анимации. Interact.js предоставляет событие onend, которое идеально подходит для запуска анимации после завершения взаимодействия.

Пример плавного возвращения элемента на исходную позицию:

interact('.draggable')
  .draggable({
    listeners: {
      move (event) {
        const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy;

        event.target.style.transform = `translate(${x}px, ${y}px)`;
        event.target.setAttribute('data-x', x);
        event.target.setAttribute('data-y', y);
      },
      end (event) {
        const x = parseFloat(event.target.getAttribute('data-x')) || 0;
        const y = parseFloat(event.target.getAttribute('data-y')) || 0;

        event.target.style.transition = 'transform 0.5s ease';
        event.target.style.transform = 'translate(0px, 0px)';

        setTimeout(() => {
          event.target.style.transition = '';
          event.target.setAttribute('data-x', 0);
          event.target.setAttribute('data-y', 0);
        }, 500);
      }
    }
  });

Особенности:

  • Плавный возврат элемента достигается за счёт CSS transition.
  • Использование setTimeout позволяет удалить стиль transition после завершения анимации.
  • Состояние координат хранится в data-x и data-y для точного отслеживания позиции.

Сочетание с библиотеками анимации

Interact.js хорошо интегрируется с библиотеками вроде GSAP или Anime.js, что позволяет создавать сложные последовательности анимаций. Например, при отпускании элемента можно запустить анимацию с эффектом «отскока» или «скольжения».

Пример с GSAP:

interact('.draggable')
  .draggable({
    listeners: {
      move (event) {
        const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy;

        event.target.style.transform = `translate(${x}px, ${y}px)`;
        event.target.setAttribute('data-x', x);
        event.target.setAttribute('data-y', y);
      },
      end (event) {
        const x = parseFloat(event.target.getAttribute('data-x')) || 0;
        const y = parseFloat(event.target.getAttribute('data-y')) || 0;

        gsap.to(event.target, {
          duration: 0.5,
          x: 0,
          y: 0,
          ease: "elastic.out(1, 0.5)",
          onComplete: () => {
            event.target.setAttribute('data-x', 0);
            event.target.setAttribute('data-y', 0);
          }
        });
      }
    }
  });

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

  • Лёгкое управление сложными кривыми анимации.
  • Поддержка отскока, затухания, и других эффектов.
  • Удобная интеграция с существующей логикой Interact.js.

Работа с resizable и gestures

Для элементов с изменяемым размером (resizable) и жестами (gesturable) анимация применяется аналогично. Можно создавать плавное масштабирование и поворот элементов с помощью CSS transform и transition.

Пример плавного изменения размеров:

interact('.resizable')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    listeners: {
      move (event) {
        let { width, height } = event.rect;

        event.target.style.transition = 'width 0.2s ease, height 0.2s ease';
        event.target.style.width = width + 'px';
        event.target.style.height = height + 'px';
      },
      end (event) {
        setTimeout(() => event.target.style.transition = '', 200);
      }
    },
    modifiers: [
      interact.modifiers.restrictSize({
        min: { width: 50, height: 50 },
        max: { width: 500, height: 500 }
      })
    ]
  });

Особенности:

  • restrictSize предотвращает выход за заданные минимальные и максимальные размеры.
  • Плавность изменения размеров обеспечивается transition на свойства width и height.
  • После завершения действия transition можно сбросить для избежания конфликтов с последующими изменениями.

Итоговые рекомендации по анимации с Interact.js

  • Использовать события move, start, end для управления CSS transition.
  • Хранить координаты и размеры в data-атрибутах для точного контроля.
  • Интеграция с внешними библиотеками анимации позволяет создавать более динамичные и сложные эффекты.
  • Плавность достигается комбинацией transition и requestAnimationFrame или GSAP/Anime.js.
  • Модификаторы (modifiers) помогают удерживать элементы в рамках интерфейса, сохраняя контроль над анимацией.

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