阅读前两个教程后,您应该能够创建路径和一些基本的预定义形状。 您还应该能够简化或展平您的路径,以及将它们绘制在不同的图层上并将它们融合在一起。
即使我们已经走了很长一段路,但仍然缺少一件事。 到目前为止,我们的画布和用户之间没有任何交互。 如果我们能够为用户提供与各种路径进行交互或自己绘制内容的能力,那将是很好的。 本教程将从tool
变量开始,涵盖用户交互的所有基础知识。
工具和工具事件
有一个全局tool
变量,仅存在于脚本中,该脚本包含与鼠标或键盘进行交互的处理函数。 此变量使您可以访问诸如minDistance
属性,该属性是自上次触发鼠标后可以再次触发onMouseDrag
事件的最小距离。 类似地,属性maxDistance
允许您指定最大距离,在此距离之后onMouseDrag
事件需要再次触发。
Paper.js也有一个ToolEvent
对象。 它是事件对象的扩展,并且是传递给所有鼠标事件处理程序的唯一参数。 它包含有关这些鼠标事件的所有相关信息,例如:
-
type
,它告诉您事件是mouseup
,mousedown
,mousemove
还是mousedrag
。 -
point
,可以在触发事件时为您提供鼠标的位置。 -
delta
,可以在触发事件时为您提供当前位置与最后一个鼠标位置之间的距离。 -
count
,它为您提供了触发鼠标事件的次数。 -
item
,它为您提供鼠标事件所在位置处的项目。 如果该项目是一个的一部分group
或compound
路径然后的最上层group
或compound
被返回路径。 -
lastPoint
,它给出上一次触发事件时鼠标的位置。 -
downPoint
,它为您提供鼠标在最后一次单击时在项目坐标中的位置。 -
middlePoint
,它为您提供lastPoint
和point
中间的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
处理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);
}
我还使用event.point
属性将strokeColor
设置为purple, strokeWidth
设置为x坐标值的十分之一。 如果尝试在下面的灰色区域中绘制一些垂直线,则会注意到所有垂直线的宽度都与它们与左侧的距离成正比。
现在,让我们使用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
属性。 您可以通过在下面的灰色区域拖动鼠标来测试上面的代码:
键盘互动
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
,该step
将用于确定圆运动的速度。 变量centerPoint
存储我们的圆心的位置。 onKeyDown
处理程序具有处理所有keydown
事件的代码。 只要按下一个键,就会连续触发此事件。
这就是不断创建新圈子的原因。 基于按下的键,我们更改centerPoint
的值以将我们新创建的圆移动到其他位置。 您可以在下面的演示中看到运行中的代码:
某些键(例如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
处理函数都会创建一个新的Path并为其添加一个点。 开始拖动后, onMouseDrag
处理程序会在每个拖动事件上为其添加一个新点。
如果在按住Shift键的情况下拖动鼠标,则处理程序将使用event.modifiers.shift
属性检测到它。 在这种情况下,它不会在每个拖动事件上添加新点,而只是将最后一段的坐标设置为鼠标指针的当前位置。 它还简化了绘制的完整路径。 您可以在下面的灰色区域拖动鼠标,以查看按下Shift键时路径的行为。
如果Shift键似乎不起作用,那可能是因为画布没有焦点。 在这种情况下,您应该首先在画布下方的白色空白区域内单击以使其聚焦。
最后的想法
我们今天讨论的事件处理程序涵盖了最常见的交互方案。 从本教程可以明显看出,根据用户的动作来操作画布中的项目并不难。 最好的学习方法是练习。 因此,我建议您创建自己的演示,结合到目前为止在三个教程中学到的所有知识。
如果您对本教程有任何疑问,请在评论中让我知道。
翻译自: https://code.tutsplus.com/tutorials/getting-started-with-paperjs-user-interaction--cms-26509