• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

Paper.js入门:用户交互

阅读前两个教程后,您应该能够创建路径和一些基本的预定义形状。您还应该能够简化或展平您的路径,并将它们绘制在不同的图层上并将它们混合在一起。 

尽管我们已经走了很长一段路,但仍然缺少一件事。到目前为止,我们的画布和用户之间还没有交互。如果我们可以让用户能够与各种路径进行交互或自己绘制一些东西,那就太好了。本教程将涵盖用户交互的所有基础知识,从tool变量开始。

工具和工具事件

有一个全局tool变量只存在于包含与鼠标或键盘交互的处理函数的脚本中。此变量使您可以访问属性,例如minDistance,这是鼠标可以再次触发 onMouseDrag事件的最小距离,因为它上次被触发。同样,该属性maxDistance允许您指定onMouseDrag事件需要再次触发的最大距离。

Paper.js 也有一个 Toolevent对象。它是事件对象的扩展,也是唯一传递给所有鼠标事件处理程序的参数。它包含有关这些鼠标事件的所有相关信息,例如:

  • type,它会告诉您事件是mouseup、mousedown还是。mousemovemousedrag

  • point,它会在触发事件时为您提供鼠标的位置。

  • delta,它为您提供事件触发时当前鼠标位置和最后鼠标位置之间的距离。

  • count,它为您提供了触发鼠标事件的次数。

  • item,它为您提供了在鼠标事件位置出现的项目。如果该项目是 a groupor路径的一部分,则返回or路径compound的最顶层 。groupcompound

  • lastPoint,它给出了最后一次触发事件时鼠标的位置。

  • downPoint,它为您提供上次单击时鼠标在项目坐标中的位置。

  • middlePointlastPoint ,这为您提供了和中间的点point。 

您应该记住所有这些,因为它们将在您的大多数项目中经常使用。

鼠标交互

Paper.js 有各种自动调用的处理函数来处理不同的鼠标事件。下面列出了三个鼠标处理函数。

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. 这将创建一条从鼠标按钮被按下的点到它被释放的点的直线。这是代码:

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为紫色和strokeWidthx 坐标值的十分之一。event.point如果您尝试在下面的灰色区域中绘制一些垂直线,您会注意到它们的宽度都与它们与左侧的距离成正比。

See the Pen  Paper.js mouseUp and mouseDown by Monty (@Shokeen)  on CodePen.

onMouseDrag现在,让我们使用该事件创建一些圈子。每次触发拖动事件时,我们将绘制一个圆,其中心位于上一个和当前拖动点的中点。圆的半径将直接取决于用户的拖动速度。 

要定位我们的圆心,我们可以使用middlePoint我们在上一节中讨论的属性。要确定圆的半径,我们可以使用delta属性并将结果除以 2。这是我们需要的代码:

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属性将每 50 个像素触发一次拖动事件。如果用户的拖动速度太慢,minDistance直到达到我们指定的最小距离阈值,该属性才会被触发。您可以通过在下面的灰色区域中拖动鼠标来测试上面的代码:

See the Pen  Paper.js mouseDrag by Monty (@Shokeen)  on CodePen.

键盘交互

该event对象具有三个可用于与键盘交互的属性。该event.key属性将告诉您按下了哪个键,并且该 event.character属性将告诉您在按键时生成的字符。要确定它是 事件keyup还是keydown事件,您可以使用该event.type属性。

让我们一起使用这些属性来创建小圆圈并移动它们。看看下面的代码:

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处理程序具有处理所有 keydown事件的代码。只要按下某个键,就会连续触发此事件。 

这就是不断创建新圈子的原因。根据按下的键,我们更改 的值centerPoint以将新创建的圆圈移动到不同的位置。您可以在下面的演示中看到正在运行的代码:

See the Pen  Paper.js keyDown by Monty (@Shokeen)  on CodePen.

某些键(例如Shift键和 Option键)在按下时不会直接产生字符。这些键称为修饰键。该event对象有一个 event.modifiers属性,您可以使用它来确定按下的修饰键。考虑下面的代码:

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属性检测它。在这种情况下,不是在每个拖动事件上添加一个新点,而是将最后一段的坐标设置为鼠标指针的当前位置。它还简化了绘制的完整路径。您可以在下面的灰色区域中拖动鼠标,以查看 按下Shift键时路径的行为。

See the Pen  Paper.js Modifier Keys by Monty (@Shokeen)  on CodePen.

如果 Shift 键似乎不起作用,那可能是因为画布没有焦点。在这种情况下,您应该首先在画布下方的小空白区域内单击以使其获得焦点。

最后的想法

我们今天讨论的事件处理程序涵盖了最常见的交互场景ios。从本教程中可以明显看出,根据用户的操作来操作画布中的项目并不难。最好的学习方法是练习。因此,我建议您结合到目前为止在三个教程中学到的所有内容创建自己的演示。


文章目录
  • 工具和工具事件
  • 鼠标交互
  • 键盘交互
  • 最后的想法