Расширение прототипов Two.js

Two.js — это мощная библиотека для создания двумерной графики в браузере на базе HTML5 Canvas, SVG и WebGL. Одной из ключевых особенностей является возможность расширять функциональность стандартных объектов через прототипы. Использование прототипов позволяет добавлять новые методы к существующим классам, изменять поведение фигур и управлять их свойствами динамически.

Расширение прототипа объекта Two.Shape

Каждая фигура в Two.js наследует базовый класс Two.Shape. Для добавления нового метода используется стандартный синтаксис Jav * aScript:

Two.Shape.prototype.moveToCenter = function() {
    this.translation.set(this._renderer.width / 2, this._renderer.height / 2);
};

В данном примере создаётся метод moveToCenter, который перемещает любую фигуру в центр холста. После этого все объекты, созданные через new Two.Rectangle(), new Two.Circle() или другие наследники Two.Shape, смогут использовать этот метод:

let circle = two.makeCircle(0, 0, 50);
circle.moveToCenter();

Ключевые моменты при работе с прототипами:

  • Методы, добавленные через prototype, становятся доступными для всех существующих и будущих экземпляров.
  • Изменения прототипа не требуют изменения исходного кода библиотеки.
  • Важно использовать уникальные имена методов, чтобы не переопределить существующие функции Two.js.

Добавление пользовательских свойств

Помимо методов, прототипы позволяют добавлять новые свойства, которые автоматически будут присутствовать у всех объектов. Например, можно добавить свойство velocity для анимации:

Two.Shape.prototype.velocity = { x: 0, y: 0 };
Two.Shape.prototype.updatePosition = function() {
    this.translation.x += this.velocity.x;
    this.translation.y += this.velocity.y;
};

Это позволяет создавать динамическое поведение объектов. Каждая фигура теперь может иметь собственную скорость и обновлять положение с помощью вызова updatePosition().

let rect = two.makeRectangle(100, 100, 50, 50);
rect.velocity = { x: 1, y: 2 };
rect.updatePosition();

Расширение прототипа Two для глобальных методов

Иногда требуется добавить методы не к отдельным фигурам, а к самой библиотеке. Для этого используется прототип объекта Two:

Two.prototype.clearAndDraw = function() {
    this.clear();
    this.update();
};

Теперь любой экземпляр Two.js сможет вызывать clearAndDraw(), что объединяет очистку сцены и перерисовку в один вызов.

let two = new Two({ width: 500, height: 500 }).appendTo(document.body);
two.clearAndDraw();

Создание цепочек вызовов (Chaining)

Расширение прототипа также позволяет создавать цепочки вызовов, что упрощает написание компактного кода:

Two.Shape.prototype.scaleAndRotate = function(s, a) {
    this.scale = s;
    this.rotation = a;
    return this;
};

circle.scaleAndRotate(2, Math.PI / 4).updatePosition();

Возврат this в методе обеспечивает возможность последовательного вызова нескольких методов у одного объекта.

Практическое применение: анимации и взаимодействие

Расширение прототипов особенно полезно при создании интерактивных анимаций. Например, можно добавить метод, который изменяет цвет фигуры при наведении мыши:

Two.Shape.prototype.onHo ver = function(color) {
    this._renderer.elem.addEventListener('mouseenter', () => {
        this.fill = color;
    });
    this._renderer.elem.addEventListener('mouseleave', () => {
        this.fill = 'black';
    });
};

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

Советы по безопасному расширению прототипов

  1. Проверка существующих методов – перед добавлением нового метода убедиться, что имя не используется.
  2. Минимизация побочных эффектов – изменения прототипов влияют на все экземпляры, поэтому важно избегать нежелательных конфликтов.
  3. Использование вспомогательных объектов – для сложной логики можно добавлять вспомогательные свойства вместо изменения внутренних полей библиотеки.

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