Статьи

Начало работы с Paper.js: взаимодействие с пользователем

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

Несмотря на то, что мы прошли долгий путь, нам все еще не хватает одной вещи. До этого момента между нашим холстом и пользователем не было никакого взаимодействия. Было бы хорошо, если бы мы могли дать пользователям возможность взаимодействовать с различными путями или рисовать что-то самостоятельно. Этот учебник охватит все основы взаимодействия с пользователем, начиная с переменной tool .

Существует глобальная переменная tool которая существует только в сценариях, которые содержат функции-обработчики для взаимодействия с мышью или клавиатурой. Эта переменная дает вам доступ к таким свойствам, как minDistance , который является минимальным расстоянием, после которого мышь может снова onMouseDrag событие onMouseDrag с момента его последнего запуска. Точно так же свойство maxDistance позволяет вам указать максимальное расстояние, после которого событие onMouseDrag нужно запустить снова.

Paper.js также имеет объект ToolEvent . Это расширение объекта события и единственный параметр, который передается всем обработчикам событий мыши. Он содержит всю необходимую информацию об этих событиях мыши, таких как:

  • type , который сообщает вам, является ли событие mouseup , mousedown , mousemove или mousedrag .
  • point , которая дает вам положение мыши, когда событие было запущено.
  • delta , которая дает вам расстояние между текущей и последней позицией мыши, когда событие было запущено.
  • count , которое дает вам количество раз, когда событие мыши было запущено.
  • item , который дает вам элемент, который присутствовал в месте события мыши. Если элемент является частью group или compound пути, возвращается самый верхний уровень group или compound пути.
  • lastPoint , который дает положение мыши, когда событие было lastPoint в последний раз.
  • downPoint , который дает вам положение мыши в координатах проекта, когда он последний раз был нажат.
  • middlePoint , который дает вам точку в середине lastPoint и point .

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
function onMouseDown(event) {
  // Do something
  console.log(‘Mouse pressed!’);
}
 
function onMouseDrag(event) {
  // Do something else
  console.log(‘Mouse dragged!’);
}
 
function onMouseUp(event) {
  // Do anything
  console.log(‘Mouse released!’);
}

Давайте создадим базовую демонстрацию на основе обработчиков onMouseDown и onMouseUp . Каждый раз, когда пользователь нажимает кнопку мыши, мы создаем новый Path и отмечаем эту точку как начало нашего Path .

Каждый раз, когда пользователь отпускает кнопку мыши, мы добавляем новую точку в качестве конца нашего Path . Это создаст прямую линию от точки, где была нажата кнопка мыши, до точки, где она была отпущена. Вот код:

01
02
03
04
05
06
07
08
09
10
11
12
var aPath;
 
function onMouseDown(event) {
  aPath = new Path();
  aPath.strokeColor = ‘purple’;
  aPath.strokeWidth = event.point.x/10;
  aPath.add(event.point);
}
   
function onMouseUp(event) {
  aPath.add(event.point);
}

Я также установил для strokeColor значение purple, а strokeWidth до одной десятой значения координаты x, используя свойство event.point . Если вы попытаетесь нарисовать несколько вертикальных линий в серой области ниже, вы заметите, что все они имеют ширину, прямо пропорциональную их расстоянию с левой стороны.

Теперь давайте создадим несколько кругов, используя событие onMouseDrag . Каждый раз, когда происходит событие перетаскивания, мы будем рисовать круг с центром в средней точке последней и текущей точки перетаскивания. Радиус круга будет напрямую зависеть от скорости перетаскивания пользователя.

Чтобы найти центр нашего круга, мы можем использовать свойство middlePoint которое мы обсуждали в предыдущем разделе. Чтобы определить радиус окружности, мы можем использовать свойство delta и разделить результат на 2. Вот код, который нам нужен:

01
02
03
04
05
06
07
08
09
10
11
12
tool.maxDistance = 50;
tool.minDistance = 4;
 
function onMouseDrag(event) {
  var circle = new Path.Circle({
    center: event.middlePoint,
    radius: event.delta.length / 2
  });
   
  circle.fillColor = ‘pink’;
  circle.strokeColor = ‘black’;
}

Если пользователь будет перетаскивать мышь слишком быстро или слишком медленно, круги станут слишком большими или слишком маленькими.

Эта проблема может быть решена с помощью свойств maxDistance и minDistance . Если пользователь перетаскивает слишком быстро, свойство maxDistance будет maxDistance событие перетаскивания каждые 50 пикселей. Если скорость перетаскивания пользователя слишком minDistance свойство minDistance не будет minDistance до тех пор, пока не будет достигнут минимальный порог расстояния, который мы указали. Вы можете проверить приведенный выше код, перетащив мышку в серую область ниже:

У объекта event есть три свойства, которые вы можете использовать для взаимодействия с клавиатурой. Свойство event.key сообщит вам, какая клавиша была нажата, а свойство event.character сообщит вам символ, который был сгенерирован при нажатии клавиши. Чтобы определить, было ли это событием event.type или keydown , вы можете использовать свойство event.type .

Давайте использовать эти свойства вместе, чтобы создать крошечные круги и переместить их. Посмотрите на код ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
var step = 10;
var centerPoint = new Point(100, 100);
   
function onKeyDown(event) {
      
  var circle = new Path.Circle(centerPoint, 3);
  circle.fillColor = ‘pink’;
  circle.strokeColor = ‘black’;
   
  if(event.key == ‘a’) {
    centerPoint -= new Point(step,0);
  }
  // Code for other keys
      
}

Мы создаем переменный step который будет использоваться для определения скорости движения нашего круга. Переменная centerPoint хранит расположение центра наших кругов. Обработчик onKeyDown имеет код для обработки всех событий onKeyDown . Это событие вызывается непрерывно, пока нажата клавиша.

Это причина того, что новые круги создаются постоянно. Основываясь на нажатой клавише, мы меняем значение centerPoint чтобы переместить наш недавно созданный круг в другое место. Вы можете увидеть код в действии в демоверсии ниже:

Некоторые клавиши, например клавиша Shift и клавиша Option , при нажатии не выводят символ напрямую. Эти клавиши называются клавишами-модификаторами. У объекта event есть свойство event.modifiers которое можно использовать для определения нажатой клавиши-модификатора. Рассмотрим код ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
var path;
   
function onMouseDown(event) {
  path = new Path();
  path.strokeColor = ‘black’;
  path.strokeWidth = 2;
  path.add(event.point);
}
   
function onMouseDrag(event) {
  if(event.modifiers.shift) {
    path.lastSegment.point = event.point;
    path.simplify();
  } else {
    path.add(event.point);
  }
}

Всякий раз, когда пользователь нажимает кнопку мыши, обработчик onMouseDown создает новый путь и добавляет к нему точку. После начала перетаскивания обработчик onMouseDrag добавляет новую точку к нему при каждом событии перетаскивания.

Если вы перетаскиваете мышь с нажатой клавишей Shift , обработчик обнаруживает ее с event.modifiers.shift свойства event.modifiers.shift . В этом случае вместо добавления новой точки на каждом событии перетаскивания он просто устанавливает координаты последнего сегмента в текущем местоположении указателя мыши. Это также упрощает полный путь, который был нарисован. Вы можете перетащить мышь в серую область ниже, чтобы увидеть, как ведет себя траектория при нажатии клавиши Shift .

Если клавиша Shift не работает, возможно, это связано с тем, что холст не имеет фокуса. В этом случае вы должны сначала щелкнуть внутри небольшого белого пространства под холстом, чтобы придать ему фокус.

Обработчики событий, которые мы обсуждали сегодня, охватывают наиболее распространенные сценарии интерактивности. Как видно из руководства, нетрудно манипулировать элементами на холсте, основываясь на действиях пользователя. Лучший способ учиться — это практиковать. Поэтому я хотел бы предложить вам создать свои собственные демонстрации, объединяющие все, что вы узнали в трех уроках до этого момента.

Если у вас есть какие-либо вопросы относительно этого урока, пожалуйста, дайте мне знать в комментариях.