Home  >  Article  >  Web Front-end  >  HTML5 Canvas events for Konva: Part 5, Actions

HTML5 Canvas events for Konva: Part 5, Actions

WBOY
WBOYOriginal
2023-09-03 10:33:031028browse

Konva 的 HTML5 Canvas 事件:第 5 部分,操作

If you've been following this series from the beginning, you should be very familiar with shapes, groups, and layers by now. You should also be able to easily draw some basic and complex shapes on canvas using Konva. If you plan to use Konva to create some interactive applications or games, then learning how to bind events to different shapes on the stage is the next logical step.

In this tutorial you will learn how to bind events to any shape using Konva. You'll also learn about event delegation and propagation. Sometimes you may need to programmatically control the click area of ​​a shape and trigger events. We will also discuss these two topics.

Bind events to shapes

You can bind different events to any shape created with Konva with the help of the on() method. All you have to do is pass the event name as the first argument and the function to be executed when the event occurs as the second argument. You can use Konva to detect mouseup, mousedown, mouseenter, mouseleave, mouseover , mousemove, click and dblclick. Additionally, Konva allows you to detect wheel, dragstart, dragmove and dragend events.

Here is an example of detecting mousedown and mouseleave events on a regular polygon (hexagon). Likewise, the smaller circle is bound to the mouseover and mouseup events, and the larger circle is bound to the mouseenter, mouseleave, and mousemove events.

var canvasWidth = 600;
var canvasHeight = 400;

var stage = new Konva.Stage({
  container: "example",
  width: canvasWidth,
  height: canvasHeight
});

var layerA = new Konva.Layer();

var polyA = new Konva.RegularPolygon({
  x: 125,
  y: 125,
  sides: 6,
  radius: 80,
  fill: "yellow",
  stroke: "black",
  strokeWidth: 5
});

var circA = new Konva.Circle({
  x: 275,
  y: 225,
  height: 100,
  fill: "orange",
  stroke: "black"
});

var circB = new Konva.Circle({
  x: 475,
  y: 275,
  radius: 100,
  fill: "red",
  stroke: "black"
});

layerA.add(polyA, circA, circB);

stage.add(layerA);

polyA.on("mousedown", function() {
  polyA.sides(polyA.sides() + 1);
  layerA.draw();
});

polyA.on("mouseleave", function() {
  var totalSides = polyA.sides();
  if(totalSides > 3) {
    polyA.sides(polyA.sides() - 1);
  }
  layerA.draw();
});

circA.on("mouseover", function() {
  circA.strokeWidth(10);
  layerA.draw();
});

circA.on("mouseup", function() {
  circA.strokeWidth(5);
  layerA.draw();
});

circB.on("mouseenter", function() {
  stage.container().style.cursor = "crosshair";
});

circB.on("mouseleave", function() {
  stage.container().style.cursor = "default";
});

circB.on("mousemove", function() {
  var pointerPos = stage.getPointerPosition();
  var r = pointerPos.x % 255;
  var g = pointerPos.y % 255;
  circB.fill("rgb(" + r + ", " + g + ", 100)");
  layerA.draw();
});

If the user presses any mouse button while the cursor is inside a regular polygon, we increase the number of sides of the polygon by 1. sides() The method can be used without parameters to get the number of sides of a polygon or with one parameter to set the number of sides of a polygon. You can also use getSides() to get the number of sides and setSides() to set the number of sides. Each time the mouse cursor leaves the polygon, the polygon's sides are reduced by one.

For smaller circles, the mouseover event is used to set the stroke width value to 10. mouseup event changes the stroke width value to 5. Remember that the mouseup event must occur inside the circle itself. For example, if you press the mouse button inside a circle and then release the mouse button after the cursor moves outside the circle, the stroke width does not change to 5.

For the larger circle, we use the mousemove event to change its fill color. We also use stage.container().style.cursor to change the cursor for the larger circle whenever the cursor moves in and out of the circle.

One important thing you should remember is that if any shape's event listener causes a property such as fill to change, you must call draw() on the corresponding layer Method color, stroke width, etc. Otherwise, changes will not be reflected on the canvas.

You don't have to bind events to one shape at a time. You can also pass a space-separated string containing multiple event types to the on() method. This will bind all events listed in the string to that specific shape.

Konva also supports corresponding mobile versions of all these activities. For example, you can register touchstart, touchmove, touchend, tap, Use Konva's dbltap, dragstart, dragmove and dragend on your mobile device.

You can also trigger any of these events for a specific shape using the fire() method. Likewise, Konva allows you to trigger custom events such as throwStones.

Delete event listener

You can remove any event listener attached to a shape with the help of the off() method in Konva. You just specify the event names that you don't want to listen to.

您还可以为单个形状创建多个事件绑定。例如,假设您有一个圆,并且您希望每次鼠标光标经过它时都增加圆的半径,直至达到一定限制。您可能还想在每个 mouseover 事件上更改圆圈的填充颜色。

一种选择是在单个 mouseover 事件侦听器中执行这两项任务,并稍后停止更新半径。另一种选择是创建两个具有不同命名空间的 mouseover 事件侦听器来识别它们。这样,您将能够独立地增加半径并更改填充颜色。

circA.on("mouseover.radius", function() {
  var curRadius = circA.radius();
  if(curRadius < 150) {
    circA.radius(curRadius + 5);
    layerA.draw();
  } else {
    circA.off('mouseover.radius');
  }
});

circA.on("mouseover.fillcolor", function() {
  var h = Math.floor(Math.random()*360);
  var color = "hsl(" + h + ", 60%, 60%)";
  circA.fill(color);
  layerA.draw();
});

您应该注意,我已在两个侦听器中添加了 layerA.draw() 。如果您未能将其添加到 mouseover.fillcolor 侦听器中,则一旦半径变为 150,颜色就会停止更新。

您还可以使用 setListening() 方法停止侦听绑定到某个形状的所有事件,而不是一次删除一个事件侦听器。您可以将 truefalse 传递给此方法,以关闭事件侦听器 onoff。请记住,您还必须在调用 setListening() 后立即调用 drawHit() 方法来重新绘制受影响图层的命中图。 p>

事件委托和传播

您还可以将事件绑定到图层本身,而不是将事件直接绑定到图层上的所有形状。之后,您可以使用事件对象的 target 属性确定哪个形状触发了事件。通过这种方式,Konva 允许您有效地将事件从父级委托给其子级。

假设您正在监听 Konva 图层上绘制的圆圈上的单击事件。相同的单击事件会传播到包含组以及包含图层。这可能是也可能不是预期的行为。如果要防止事件在形状内部冒泡到包含层,可以将事件对象的 cancelBubble 属性设置为 true

var canvasWidth = 600;
var canvasHeight = 400;

var stage = new Konva.Stage({
  container: "example",
  width: canvasWidth,
  height: canvasHeight
});

var layerA = new Konva.Layer();

var circA = new Konva.Circle({
  x: 300,
  y: 200,
  height: 100,
  fill: "orange",
  stroke: "black",
  name: "Orange Circle"
});

var starA = new Konva.Star({
  x: 125,
  y: 125,
  innerRadius: 25,
  outerRadius: 75,
  rotation: 90,
  fill: "blue",
  stroke: "black",
  name: "Blue Star"
});

var ringA = new Konva.Ring({
  x: 475,
  y: 275,
  innerRadius: 25,
  outerRadius: 75,
  fill: "brown",
  stroke: "black",
  name: "Brown Ring"
});

var textA = new Konva.Text({
  text: "",
  fontFamily: "Calibri",
  fontSize: 24,
  fill: "black",
  x: 10,
  y: 10
});

layerA.add(circA, starA, ringA, textA);

stage.add(layerA);

layerA.on("click", function(e) {
  var shapeName = e.target.attrs.name;
  textA.setText(shapeName);
  layerA.draw();
});

我使用 name 属性为每个形状指定一个名称。然后使用 setText() 方法将 textA 内的文本更改为我们刚刚单击的形状的名称。

自定义命中区域

在上面的示例中,当单击发生在内圆和外圆之间时,环记录了对其的单击。如果您也想记录小圆圈内的点击怎么办? Konva 允许您使用 hitFunc 属性定义自定义命中区域。该属性接受一个函数作为其值,该函数用于绘制自定义命中区域。

以下示例向您展示如何创建自定义命中区域。您现在应该能够单击星形尖峰之间的区域并仍然记录单击。借助自定义点击区域,您可以确保用户不必单击确切位置即可注册单击事件。在处理更小或更复杂的形状时,这可以带来更好的用户体验。

var starA = new Konva.Star({
  x: 125,
  y: 125,
  innerRadius: 25,
  outerRadius: 75,
  rotation: 90,
  fill: "blue",
  stroke: "black",
  name: "Blue Star",
  hitFunc: function(context) {
    context.beginPath();
    context.arc(0, 0, this.getOuterRadius(), 0, Math.PI * 2, true);
    context.closePath();
    context.fillStrokeShape(this);
  }
});

var ringA = new Konva.Ring({
  x: 475,
  y: 275,
  innerRadius: 25,
  outerRadius: 75,
  fill: "brown",
  stroke: "black",
  name: "Brown Ring",
  hitFunc: function(context) {
    context.beginPath();
    context.arc(0, 0, this.getOuterRadius(), 0, Math.PI * 2, true);
    context.closePath();
    context.fillStrokeShape(this);
  }
});

最终想法

在本教程中,我们介绍了可以绑定到 Konva 中任何形状的不同移动和桌面事件。您可以一次附加一个事件,也可以一次附加多个事件。 Konva 还允许您使用 fire() 方法以编程方式触发自己的自定义事件。本教程的最后一部分向您展示了如何定义自己的命中区域,以便检测可能大于或小于原始形状的区域上的命中。

将本教程的知识与本系列中其他教程的知识相结合,您现在应该能够在画布上绘制各种形状并允许用户与它们进行交互。

如果您对本教程有任何疑问,请随时在评论中告诉我。

The above is the detailed content of HTML5 Canvas events for Konva: Part 5, Actions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn