Two.js — это мощная библиотека для создания двумерной графики с поддержкой Canvas, SVG и WebGL. Она легко интегрируется в любые фронтенд-фреймворки, такие как React, Vue и Angular, благодаря своей модульной архитектуре и отсутствию жёстких зависимостей.
Для React предпочтительно использовать useRef и
useEffect для управления жизненным циклом рендера. Основная
идея — создать контейнер для канваса и привязать к нему экземпляр
Two.js.
import React, { useRef, useEffect } from 'react';
import Two from 'two.js';
function TwoCanvas() {
const containerRef = useRef(null);
useEffect(() => {
const params = { width: 800, height: 600, type: Two.Types.svg };
const two = new Two(params).appendTo(containerRef.current);
const circle = two.makeCircle(400, 300, 50);
circle.fill = '#FF8000';
circle.stroke = 'black';
circle.linewidth = 3;
two.update();
return () => two.clear();
}, []);
return <div ref={containerRef}></div>;
}
export default TwoCanvas;
Ключевые моменты:
useRef обеспечивает
постоянную ссылку на DOM-элемент, к которому привязывается Two.js.useEffect гарантирует создание и
очистку графики при монтировании и размонтировании компонента.two.update(), что позволяет управлять
анимациями и динамическим содержимым.Во Vue 3 с Composition API Two.js подключается через ref
и onMounted:
<template>
<div ref="canvasContainer"></div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import Two from 'two.js';
const canvasContainer = ref(null);
let two;
onMounted(() => {
two = new Two({ width: 600, height: 400, type: Two.Types.canvas }).appendTo(canvasContainer.value);
const rect = two.makeRectangle(300, 200, 100, 100);
rect.fill = '#3498db';
rect.stroke = '#2980b9';
rect.linewidth = 4;
two.update();
});
onBeforeUnmount(() => {
two.clear();
});
</script>
Особенности:
ref обеспечивает реактивную привязку к
DOM-элементу.onMounted гарантирует создание Two.js только после
того, как элемент появился в DOM.onBeforeUnmount позволяет корректно удалить объекты,
предотвращая утечки памяти.В Angular Two.js удобно интегрировать через ViewChild и
lifecycle hooks:
import { Component, ElementRef, OnInit, OnDestroy, ViewChild } from '@angular/core';
import Two from 'two.js';
@Component({
selector: 'app-two-canvas',
template: '<div #canvasContainer></div>',
})
export class TwoCanvasComponent implements OnInit, OnDestroy {
@ViewChild('canvasContainer', { static: true }) container!: ElementRef;
private two!: Two;
ngOnInit() {
this.two = new Two({ width: 500, height: 500, type: Two.Types.webgl }).appendTo(this.container.nativeElement);
const triangle = this.two.makePolygon(250, 250, 80, 3);
triangle.fill = '#2ecc71';
triangle.stroke = '#27ae60';
triangle.linewidth = 5;
this.two.update();
}
ngOnDestroy() {
this.two.clear();
}
}
Angular требует явного управления жизненным циклом компонентов, поэтому ngOnInit и ngOnDestroy идеально подходят для инициализации и очистки сцены Two.js.
Two.js прекрасно работает с анимациями через свой встроенный метод
bind:
two.bind('update', () => {
circle.rotation += 0.02;
}).play();
Для реактивных фреймворков можно использовать связывание состояния с
объектами Two.js. В React это делается через state и
useEffect:
useEffect(() => {
circle.fill = color;
two.update();
}, [color]);
Во Vue аналогично применяется watch для реактивных переменных:
watch(fillColor, (newColor) => {
rect.fill = newColor;
two.update();
});
two.update() —
обновлять сцену только при изменениях объектов.Two.js поддерживает базовые события для объектов через прослушивание DOM-событий:
circle._renderer.elem.addEventListener('click', () => {
circle.fill = '#e74c3c';
two.update();
});
В реактивных фреймворках события можно связывать с методами компонентов, сохраняя консистентность состояния приложения.
Для крупных проектов рекомендуется:
Такой подход упрощает масштабирование и поддержку проекта, особенно в условиях сложных интерактивных интерфейсов.