В Paper.js основной принцип построения графических приложений заключается в чётком разграничении логики приложения и отрисовки графических объектов. Это позволяет создавать более читаемый, масштабируемый и поддерживаемый код, особенно в проектах с анимацией или интерактивными элементами.
Логика приложения отвечает за:
Отрисовка отвечает за:
В Paper.js объекты, такие как Path, Shape и
Raster, являются визуальными представлениями состояния.
Важно понимать, что логика не должна напрямую изменять
визуальные свойства объектов, кроме как через обновление
состояния, а отрисовка должна лишь интерпретировать это состояние.
Для чистого разделения логики удобно создать структуры данных, описывающие объекты приложения. Например, для анимации шаров можно использовать:
class Ball {
constructor(x, y, vx, vy, radius, color) {
this.position = new Point(x, y);
this.velocity = new Point(vx, vy);
this.radius = radius;
this.color = color;
}
update(delta) {
this.position = this.position.add(this.velocity.multiply(delta));
}
}
Здесь класс Ball полностью не зависит от
Paper.js. Его методы только изменяют состояние объекта.
Для отрисовки создаются Paper.js объекты и синхронизируются со состоянием:
let balls = [
new Ball(100, 100, 2, 3, 20, 'red'),
new Ball(200, 150, -1, 2, 15, 'blue')
];
let ballShapes = balls.map(ball => {
let shape = new Path.Circle(ball.position, ball.radius);
shape.fillColor = ball.color;
return shape;
});
Обновление позиции происходит в onFrame:
view.onFr ame = (event) => {
balls.forEach((ball, i) => {
ball.update(event.delta);
ballShapes[i].position = ball.position;
});
};
Таким образом, логика (ball.update) и отрисовка
(ballShapes[i].position) полностью разделены, и
Paper.js служит лишь визуальным интерфейсом.
События можно обрабатывать аналогичным образом. Например, нажатие мыши изменяет состояние объектов, а Paper.js обновляет визуализацию:
tool.onMouseD own = (event) => {
balls.forEach(ball => {
let direction = ball.position.subtract(event.point).normalize();
ball.velocity = direction.multiply(5);
});
};
Здесь Paper.js не управляет физикой — она вычисляется логикой, а библиотека лишь визуально отражает результат.
Paper.js предоставляет объект Layer, позволяющий
структурировать визуальные элементы:
let backgroundLayer = new Layer();
let objectsLayer = new Layer();
let background = new Path.Rectangle(view.bounds);
background.fillColor = 'lightgray';
backgroundLayer.addChild(background);
objectsLayer.activate();
balls.forEach(ball => {
let shape = new Path.Circle(ball.position, ball.radius);
shape.fillColor = ball.color;
});
Слои помогают разделять фон, интерфейс и динамические объекты, что упрощает управление сложными сценами.
Модель-Вид-Контроллер (MVC)
Система компонентов
Фреймбуферное обновление
onFrame полностью перерисовывать объекты, что предотвращает
расхождение логики и визуализации.shape.translate,
shape.scale или shape.rotate напрямую в
логике.view.onFrame.Такое разделение повышает предсказуемость, упрощает тестирование и делает код готовым к расширению, например, добавлению физики, коллизий или сетевого взаимодействия.