Изображения как текстуры

В библиотеке Two.js изображения используются как текстуры, которые могут быть применены к геометрическим примитивам (прямоугольникам, кругам, многоугольникам) или произвольным формам. В отличие от простого отображения <img> в DOM, текстура в Two.js становится частью сцены и подчиняется трансформациям: масштабированию, вращению, прозрачности и анимации.

Текстура реализуется через объект Two.Texture, который инкапсулирует источник изображения и управляет его загрузкой, обновлением и повторением.


Создание текстуры

Базовое создание текстуры выполняется через конструктор:

const texture = new Two.Texture('image.jpg');

В качестве аргумента может выступать:

  • URL изображения
  • элемент <img>
  • элемент <canvas>
  • элемент <video>

После создания текстура может быть назначена свойству fill любой фигуры:

const rect = two.makeRectangle(200, 200, 300, 200);
rect.fill = texture;
rect.noStroke();

Асинхронная загрузка изображений

Загрузка изображений происходит асинхронно. До завершения загрузки текстура не отображается. Для отслеживания состояния используется событие load:

texture.bind('load', function () {
  console.log('Текстура загружена');
});

Альтернативный способ — проверка свойства:

if (texture.loaded) {
  // изображение готово
}

Повторение текстуры (Repeat)

По умолчанию изображение растягивается на всю фигуру. Для создания повторяющегося узора используется свойство repeat:

texture.repeat = 'repeat';

Допустимые значения:

  • 'no-repeat' — без повторения
  • 'repeat' — повтор по обеим осям
  • 'repeat-x' — только по горизонтали
  • 'repeat-y' — только по вертикали

Пример:

const rect = two.makeRectangle(200, 200, 400, 300);
rect.fill = texture;
texture.repeat = 'repeat-x';

Смещение текстуры (Offset)

Смещение позволяет изменять начальную точку отображения текстуры внутри фигуры:

texture.offset.set(50, 30);

Это особенно полезно для анимации:

two.bind('update', function () {
  texture.offset.x += 1;
});

Создаётся эффект прокрутки изображения.


Масштабирование текстуры

Размер текстуры регулируется через свойство scale:

texture.scale = 0.5;

Или более точно:

texture.scale = new Two.Vector(0.5, 0.75);

Это позволяет независимо управлять масштабом по осям X и Y.


Использование текстуры с формами

Текстура может применяться к любой форме:

const circle = two.makeCircle(300, 300, 100);
circle.fill = texture;
circle.stroke = 'black';

Для сложных путей:

const path = two.makePath(
  100, 100,
  200, 50,
  300, 150,
  true
);

path.fill = texture;

Текстура автоматически подстраивается под границы фигуры.


Кадрирование (Clip)

Two.js позволяет ограничить отображение текстуры с помощью clipping:

const mask = two.makeCircle(200, 200, 100);
const rect = two.makeRectangle(200, 200, 300, 300);

rect.fill = texture;
rect.mask = mask;

В этом случае текстура будет видна только внутри маски.


Работа с видео как текстурой

В качестве текстуры может использоваться видео:

const video = document.createElement('video');
video.src = 'video.mp4';
video.play();

const texture = new Two.Texture(video);

Такой подход позволяет:

  • создавать анимированные поверхности
  • синхронизировать графику с видеопотоком

Динамическое обновление текстуры

При использовании <canvas> как источника можно динамически изменять содержимое:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

const texture = new Two.Texture(canvas);

После изменения canvas необходимо уведомить Two.js:

texture._flagImage = true;

Это заставляет движок перерисовать текстуру.


Прозрачность и смешивание

Текстура поддерживает прозрачность через альфа-канал изображения. Дополнительно можно управлять общей прозрачностью фигуры:

rect.opacity = 0.5;

Также можно комбинировать текстуру с цветом:

rect.fill = texture;
rect.opacity = 0.8;

Производительность

Работа с текстурами требует внимания к производительности:

  • большие изображения увеличивают нагрузку на GPU
  • частое обновление текстур снижает FPS
  • использование повторяющихся текстур эффективнее, чем множество уникальных

Рекомендации:

  • использовать оптимизированные изображения (PNG/JPEG сжатие)
  • избегать частого изменения texture.image
  • минимизировать количество уникальных текстур

Практические паттерны использования

Фоновый узор:

const bg = two.makeRectangle(0, 0, width, height);
bg.fill = texture;
texture.repeat = 'repeat';

Анимация движения:

two.bind('update', function () {
  texture.offset.x += 2;
});

Текстура внутри формы:

const star = two.makeStar(200, 200, 5, 50, 100);
star.fill = texture;

Ограничения и особенности

  • текстура не привязывается к координатам сцены, а к фигуре
  • при масштабировании фигуры текстура масштабируется вместе с ней
  • поведение может отличаться между рендерами (SVG, Canvas, WebGL)

Взаимодействие с рендерами

Two.js поддерживает несколько типов рендеринга:

  • SVG
  • Canvas
  • WebGL

Особенности текстур:

  • в SVG текстуры реализуются через <pattern>
  • в Canvas — через drawImage
  • в WebGL — через текстурные буферы

Это влияет на:

  • производительность
  • точность отображения
  • поддержку repeat и offset

Итоговая структура работы с текстурами

  1. Создание источника (изображение, видео, canvas)

  2. Оборачивание в Two.Texture

  3. Назначение в fill фигуры

  4. Настройка параметров:

    • repeat
    • offset
    • scale
  5. Добавление анимации или взаимодействия

Такая модель делает текстуры гибким инструментом для создания сложной графики, анимаций и визуальных эффектов внутри Two.js.