PixiJS в Vue: монтирование и размонтирование

PixiJS — это библиотека для рендеринга 2D-графики в реальном времени, основанная на WebGL. Она предоставляет мощные инструменты для создания визуальных эффектов, анимаций и игр. Использование PixiJS в приложениях на Vue.js дает возможность интегрировать производительную графику и анимации в динамичные интерфейсы.

Основы монтирования PixiJS в Vue

Интеграция PixiJS с Vue начинается с настройки компонента, который будет отвечать за рендеринг графики. Чтобы правильно вставить PixiJS-сцену в приложение на Vue, нужно выполнить несколько ключевых шагов.

  1. Установка зависимостей Для начала нужно установить саму библиотеку PixiJS. Это можно сделать через npm:

    npm install pixi.js
  2. Создание компонента для PixiJS В Vue компонент можно создать как обычный Vue-файл. Основной задачей является привязка PixiJS-сцены к DOM-элементу, который управляется Vue. Пример компонента:

    <template>
      <div ref="pixiContainer"></div>
    </template>
    
    <script>
    import * as PIXI from 'pixi.js';
    
    export default {
      name: 'PixiComponent',
      mounted() {
        // Инициализация PixiJS
        this.createPixiScene();
      },
      beforeDestroy() {
        // Очистка сцены PixiJS при размонтировании компонента
        this.destroyPixiScene();
      },
      methods: {
        createPixiScene() {
          // Создание PixiJS приложения
          this.app = new PIXI.Application({
            width: 800,
            height: 600,
            backgroundColor: 0x1099bb,
            resolution: window.devicePixelRatio || 1
          });
          // Добавление сцены в DOM
          this.$refs.pixiContainer.appendChild(this.app.view);
    
          // Создание простого графического объекта
          const graphics = new PIXI.Graphics();
          graphics.beginFill(0xff9900);
          graphics.drawRect(0, 0, 100, 100);
          graphics.endFill();
          this.app.stage.addChild(graphics);
        },
        destroyPixiScene() {
          // Очистка сцены PixiJS
          if (this.app) {
            this.app.destroy(true, { children: true, texture: true, baseTexture: true });
            this.app = null;
          }
        }
      }
    };
    </script>
    
    <style scoped>
    div {
      width: 100%;
      height: 100%;
    }
    </style>

    В этом примере:

    • В методе mounted создается экземпляр приложения PixiJS, который рендерит графику в DOM-элемент, указанный через ref.
    • Метод beforeDestroy отвечает за очистку всех ресурсов PixiJS перед удалением компонента.

Обработка изменений в размерах и реактивности

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

Для решения этой задачи можно использовать Vue-события или реактивные данные для обновления размеров канваса. Пример:

<template>
  <div ref="pixiContainer" @resize="onResize"></div>
</template>

<script>
export default {
  data() {
    return {
      width: 800,
      height: 600
    };
  },
  mounted() {
    this.createPixiScene();
    window.addEventListener('resize', this.onResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.onResize);
    this.destroyPixiScene();
  },
  methods: {
    onResize() {
      // Изменение размеров компонента PixiJS при изменении размеров окна
      this.width = window.innerWidth;
      this.height = window.innerHeight;
      this.app.renderer.resize(this.width, this.height);
    },
    createPixiScene() {
      this.app = new PIXI.Application({
        width: this.width,
        height: this.height,
        backgroundColor: 0x1099bb
      });
      this.$refs.pixiContainer.appendChild(this.app.view);
    },
    destroyPixiScene() {
      if (this.app) {
        this.app.destroy(true, { children: true, texture: true, baseTexture: true });
        this.app = null;
      }
    }
  }
};
</script>

В данном примере добавлен обработчик события resize, который обновляет размер канваса, что особенно важно при изменении размеров окна браузера.

Монтирование и размонтирование с использованием Vuex

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

Пример:

// store.js
export default new Vuex.Store({
  state: {
    pixiApp: null
  },
  mutations: {
    setPixiApp(state, app) {
      state.pixiApp = app;
    },
    destroyPixiApp(state) {
      if (state.pixiApp) {
        state.pixiApp.destroy(true, { children: true, texture: true, baseTexture: true });
        state.pixiApp = null;
      }
    }
  }
});
// PixiComponent.vue
<template>
  <div ref="pixiContainer"></div>
</template>

<script>
import * as PIXI from 'pixi.js';
import { mapState, mapMutations } from 'vuex';

export default {
  computed: {
    ...mapState(['pixiApp'])
  },
  mounted() {
    this.createPixiScene();
  },
  beforeDestroy() {
    this.destroyPixiScene();
  },
  methods: {
    ...mapMutations(['setPixiApp', 'destroyPixiApp']),
    createPixiScene() {
      const app = new PIXI.Application({
        width: 800,
        height: 600,
        backgroundColor: 0x1099bb
      });
      this.$refs.pixiContainer.appendChild(app.view);
      this.setPixiApp(app);
    },
    destroyPixiScene() {
      this.destroyPixiApp();
    }
  }
};
</script>

В этом примере с использованием Vuex PixiJS-сцена сохраняется в хранилище, что позволяет контролировать её состояние глобально. Это полезно, если PixiJS-сцена должна изменяться или перерисовываться в зависимости от состояния приложения.

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

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

  2. Удаление объектов При удалении объектов или графики из сцены важно не только убрать их из сцены, но и уничтожить их для освобождения памяти. PixiJS предоставляет методы destroy для объектов и текстур.

  3. Использование анимации В PixiJS есть встроенные механизмы для создания анимаций, такие как requestAnimationFrame. Это позволяет синхронизировать рендеринг с частотой обновления экрана, что улучшает производительность.

  4. Использование низкоуровневого рендеринга Для сложных сцен с большим количеством объектов можно использовать такие техники, как culling (вывод только видимых объектов), чтобы снизить нагрузку на рендеринг.

Итоги

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