Переключение между инструментами

В Paper.js инструменты (Tool) являются ключевыми объектами для обработки событий ввода пользователя, таких как движения мыши, клики и нажатия клавиш. Каждый инструмент может иметь свои собственные обработчики событий, позволяя создавать интерактивные сцены с различными режимами работы.

Создание инструмента выполняется через конструктор new Tool(). При этом можно назначить обработчики событий:

let pencilTool = new Tool();

pencilTool.onMouseD own = function(event) {
    console.log('Начало рисования в точке:', event.point);
};

pencilTool.onMouseD rag = function(event) {
    console.log('Текущая точка:', event.point);
};

pencilTool.onKeyD own = function(event) {
    console.log('Нажата клавиша:', event.key);
};

Объект event содержит важные свойства:

  • event.point — координаты точки в пространстве канвы.
  • event.delta — смещение курсора между событиями drag.
  • event.middlePoint — средняя точка между последним и текущим положением курсора.

Активация и переключение инструментов

Для того чтобы инструмент начал обрабатывать события, необходимо его активировать через свойство Tool.active или метод tool.activate().

let pencilTool = new Tool();
let eraserTool = new Tool();

pencilTool.activate(); // Активен инструмент рисования

eraserTool.onMouseD rag = function(event) {
    project.activeLayer.removeChildren(event.point, event.delta.length);
};

// Переключение при нажатии клавиши
tool.onKeyD own = function(event) {
    if(event.key === 'e') {
        eraserTool.activate();
    } else if(event.key === 'p') {
        pencilTool.activate();
    }
};

Важно: В Paper.js одновременно может быть активен только один инструмент. При активации нового инструмента предыдущий автоматически становится неактивным.

Организация нескольких инструментов

Для сложных приложений часто используется набор инструментов для разных задач: рисование, выделение, перемещение объектов. Оптимальный способ организации:

  1. Создание отдельного инструмента для каждой задачи.
  2. Назначение обработчиков событий специфично для каждой функции.
  3. Централизованное управление активацией.
let tools = {
    draw: new Tool(),
    select: new Tool(),
    move: new Tool()
};

tools.draw.onMouseD rag = function(event) {
    new Path.Circle({
        center: event.point,
        radius: 5,
        fillColor: 'black'
    });
};

tools.select.onMouseD own = function(event) {
    let hitItem = project.hitTest(event.point);
    if(hitItem) {
        hitItem.selected = !hitItem.selected;
    }
};

// Функция переключения
function activateTool(name) {
    tools[name].activate();
}

// Переключение через клавиши
view.onKeyD own = function(event) {
    if(event.key === 'd') activateTool('draw');
    if(event.key === 's') activateTool('select');
    if(event.key === 'm') activateTool('move');
};

Состояние инструмента и пользовательский интерфейс

Paper.js предоставляет возможность проверять активность инструмента через свойство Tool.active. Это удобно для визуального отображения текущего режима на интерфейсе.

function updateToolbar() {
    if(tools.draw.active) toolbar.highlight('draw');
    if(tools.select.active) toolbar.highlight('select');
}

Передача данных между инструментами

Иногда необходимо, чтобы один инструмент мог использовать данные, созданные другим. В Paper.js объекты проекта (project) и слои (Layer) доступны глобально, что упрощает обмен информацией.

tools.draw.onMouseD rag = function(event) {
    let circle = new Path.Circle({
        center: event.point,
        radius: 10,
        fillColor: 'blue'
    });
    project.activeLayer.addChild(circle);
};

tools.select.onMouseD own = function(event) {
    let item = project.hitTest(event.point);
    if(item) {
        item.remove();
    }
};

События клавиатуры при работе с инструментами

Обработчики onKeyDown и onKeyUp могут быть назначены как отдельному инструменту, так и глобально через view.onKeyDown. Если обработчик находится внутри активного инструмента, он имеет приоритет над глобальным.

tools.draw.onKeyD own = function(event) {
    if(event.key === 'z') {
        console.log('Отмена последнего действия рисования');
    }
};

Рекомендации по архитектуре

  • Разделение инструментов по функциональности позволяет избегать конфликтов событий.
  • Активировать только один инструмент для исключения одновременного срабатывания нескольких обработчиков.
  • Хранить глобальные данные в project или отдельных слоях, чтобы все инструменты имели доступ к ним.
  • Использовать именованные функции для обработчиков, чтобы можно было легко подключать и отключать их при смене инструмента.

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