Paper.js предоставляет мощные средства для работы с векторной
графикой на канвасе, включая реализацию drag and drop
для объектов. В Paper.js любой объект типа Path,
Shape, Raster или Group может
быть перемещён мышью при помощи событий mouseDown,
mouseDrag и mouseUp.
Каждый объект в Paper.js может быть связан с обработчиками событий мыши. Основные события для реализации drag and drop:
var circle = new Path.Circle({
center: [100, 100],
radius: 50,
fillColor: 'red'
});
circle.onMouseD own = function(event) {
this.data.dragging = true;
this.data.startPosition = this.position.clone();
this.data.offset = event.point.subtract(this.position);
};
circle.onMouseD rag = function(event) {
if (this.data.dragging) {
this.position = event.point.subtract(this.data.offset);
}
};
circle.onMous eUp = function(event) {
this.data.dragging = false;
};
dataСвойство data объекта Paper.js позволяет хранить
пользовательские данные. Для drag and drop часто используют:
dragging — логическая переменная, указывающая на
активность перетаскивания.startPosition — начальная позиция объекта перед
перемещением.offset — смещение курсора относительно центра
объекта.Это обеспечивает плавное перемещение без “скачков” при клике в произвольной точке объекта.
Объединение нескольких элементов в Group позволяет перемещать их как единое целое:
var rect1 = new Path.Rectangle([0,0], [50,50]);
rect1.fillColor = 'blue';
var rect2 = new Path.Rectangle([60,0], [50,50]);
rect2.fillColor = 'green';
var group = new Group([rect1, rect2]);
group.onMouseD own = function(event) {
this.data.dragging = true;
this.data.offset = event.point.subtract(this.position);
};
group.onMouseD rag = function(event) {
if (this.data.dragging) {
this.position = event.point.subtract(this.data.offset);
}
};
group.onMous eUp = function(event) {
this.data.dragging = false;
};
Группы упрощают управление сложными сценами и позволяют сохранять относительное расположение объектов.
Можно ограничить перемещение объекта рамкой или определённой областью:
circle.onMouseD rag = function(event) {
var newPos = event.point.subtract(this.data.offset);
if (newPos.x < 50) newPos.x = 50;
if (newPos.y < 50) newPos.y = 50;
if (newPos.x > 450) newPos.x = 450;
if (newPos.y > 450) newPos.y = 450;
this.position = newPos;
};
Таким образом создаётся эффект “ограниченной зоны” для drag and drop.
Для более плавного перемещения можно использовать свойства tweening:
circle.onMouseD rag = function(event) {
var target = event.point.subtract(this.data.offset);
this.tween(
{ position: this.position },
{ position: target },
0.2 // длительность анимации в секундах
);
};
Paper.js не имеет встроенного tweening API, но можно реализовать
простую интерполяцию с помощью view.onFrame:
circle.onMouseD rag = function(event) {
this.data.target = event.point.subtract(this.data.offset);
};
view.onFr ame = function() {
if (circle.data.target) {
circle.position = circle.position.add(
circle.data.target.subtract(circle.position).multiply(0.2)
);
}
};
Для случаев, когда объекты накладываются друг на друга, важно
изменять z-index через bringToFront():
circle.onMouseD own = function(event) {
this.bringToFront();
this.data.dragging = true;
this.data.offset = event.point.subtract(this.position);
};
Это гарантирует, что перемещаемый объект всегда виден поверх остальных элементов.
Paper.js позволяет отслеживать, какие объекты выделены, и перемещать их вместе:
var selectedItems = [];
function select(item) {
if (!selectedItems.includes(item)) {
selectedItems.push(item);
item.strokeColor = 'orange';
}
}
function deselect(item) {
selectedItems = selectedItems.filter(i => i !== item);
item.strokeColor = 'black';
}
view.onMouseD own = function(event) {
var hit = project.hitTest(event.point);
if (hit) select(hit.item);
};
view.onMouseD rag = function(event) {
selectedItems.forEach(item => {
item.position = item.position.add(event.delta);
});
};
Такой подход упрощает создание интерактивных редакторов и игр, где требуется перемещать несколько объектов одновременно.
Paper.js интегрируется с обычными событиями DOM. Для сложных
интерфейсов можно использовать комбинацию событий канваса и
addEventListener:
var tool = new Tool();
tool.onMouseD own = function(event) {
console.log("Клик в позиции:", event.point);
};
tool.onMouseD rag = function(event) {
console.log("Перемещение на:", event.delta);
};
Использование Tool обеспечивает глобальный контроль над
взаимодействием с мышью, даже если объекты не привязаны к событиям
напрямую.
offset для
плавного drag and drop.Group и единые
обработчики событий.bringToFront() при наложении объектов для
правильного отображения.Эти подходы формируют основу интерактивного управления объектами в Paper.js, позволяя создавать полноценные редакторы, визуализации и игровые интерфейсы.