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

Для интеграции ScrollMagic с Vue необходимо установить библиотеку через npm или yarn:

npm install scrollmagic
# или
yarn add scrollmagic

После установки библиотеку импортируют в компонент Vue, обычно в mounted(), чтобы гарантировать, что DOM уже доступен для манипуляций:

import ScrollMagic from "scrollmagic";

export default {
  mounted() {
    this.initScrollMagic();
  },
  methods: {
    initScrollMagic() {
      const controller = new ScrollMagic.Controller();
      // Создание сцен будет здесь
    }
  }
}

Основы работы с контроллером и сценами

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

const controller = new ScrollMagic.Controller();

Scene — это объект, который связывает элемент с поведением при прокрутке. Основные параметры сцены:

  • triggerElement — элемент DOM, который служит триггером для начала анимации.
  • duration — длина сцены в пикселях (или процент прокрутки).
  • offset — смещение от начала триггерного элемента, с которого начинается анимация.

Пример создания простой сцены:

new ScrollMagic.Scene({
  triggerElement: "#myElement",
  duration: 300,
  offset: 50
})
.setClassToggle("#myElement", "active") // добавляет класс при достижении сцены
.addTo(controller);

Использование анимаций с GSAP

ScrollMagic отлично интегрируется с библиотекой GSAP для плавных анимаций. Импортируется GSAP и создается tween для сцены:

import { gsap } from "gsap";

const tween = gsap.to("#myElement", { x: 200, opacity: 1, duration: 1 });

new ScrollMagic.Scene({
  triggerElement: "#myElement",
  duration: 500
})
.setTween(tween)
.addTo(controller);

При использовании Vue стоит убедиться, что анимации создаются после того, как элементы полностью отрендерены. Обычно это делается в mounted() или через nextTick:

this.$nextTick(() => {
  this.initScrollMagic();
});

Управление жизненным циклом Vue компонентов

В Vue компонентах важно очищать ScrollMagic сцены при уничтожении компонента, чтобы избежать утечек памяти и конфликтов при повторном монтировании:

export default {
  mounted() {
    this.initScrollMagic();
  },
  beforeDestroy() {
    this.destroyScrollMagic();
  },
  methods: {
    initScrollMagic() {
      this.controller = new ScrollMagic.Controller();
      this.scene = new ScrollMagic.Scene({
        triggerElement: "#myElement",
        duration: 300
      })
      .setClassToggle("#myElement", "active")
      .addTo(this.controller);
    },
    destroyScrollMagic() {
      if (this.scene) {
        this.scene.destroy(true);
        this.scene = null;
      }
      if (this.controller) {
        this.controller.destroy(true);
        this.controller = null;
      }
    }
  }
}

Интеграция с динамическими данными

При работе с динамическим контентом необходимо пересоздавать сцены после обновления DOM. В Vue для этого используется watch или updated:

watch: {
  items() {
    this.$nextTick(() => {
      this.destroyScrollMagic();
      this.initScrollMagic();
    });
  }
}

Это гарантирует, что все элементы сцены корректно обновлены и анимации привязаны к новым DOM-узлам.

Настройка нескольких сцен

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

this.scenes = [];

this.scenes.push(
  new ScrollMagic.Scene({
    triggerElement: "#element1",
    duration: 200
  })
  .setClassToggle("#element1", "visible")
  .addTo(this.controller)
);

this.scenes.push(
  new ScrollMagic.Scene({
    triggerElement: "#element2",
    duration: 400
  })
  .setTween(gsap.to("#element2", { y: 100, opacity: 1 }))
  .addTo(this.controller)
);

Очистка массива при уничтожении компонента:

this.scenes.forEach(scene => scene.destroy(true));
this.scenes = [];

Советы по производительности

  • Использовать .addIndicators() только для отладки, на продакшене удалять.
  • Минимизировать количество сцен с тяжелыми анимациями.
  • При больших списках динамических элементов использовать делегирование триггеров или объединение анимаций в группы.

Применение с компонентной структурой Vue

Для удобства сцены можно создавать в отдельных миксинах или composables. Это позволяет повторно использовать ScrollMagic логику в разных компонентах без дублирования кода:

// composables/useScrollMagic.js
import ScrollMagic from "scrollmagic";
import { onMounted, onBeforeUnmount } from "vue";

export function useScrollMagic(callback) {
  let controller;
  let scenes = [];

  onMounted(() => {
    controller = new ScrollMagic.Controller();
    scenes = callback(controller);
  });

  onBeforeUnmount(() => {
    scenes.forEach(scene => scene.destroy(true));
    controller.destroy(true);
  });
  
  return { controller, scenes };
}

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

import { useScrollMagic } from "@/composables/useScrollMagic";

export default {
  setup() {
    useScrollMagic(controller => [
      new ScrollMagic.Scene({
        triggerElement: "#item",
        duration: 300
      }).setClassToggle("#item", "active").addTo(controller)
    ]);
  }
}

Этот подход полностью соответствует архитектуре Vue 3 и упрощает поддержку сложных анимационных интерфейсов.