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

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

如果您从一开始就关注本系列,那么您现在应该对形状、组和图层非常熟悉。您还应该能够使用 Konva 在画布上轻松绘制一些基本和复杂的形状。如果您计划使用 Konva 创建一些交互式应用程序或游戏,那么学习如何将事件绑定到舞台上的不同形状是下一个合乎逻辑的步骤。

在本教程中,您将学习如何使用 Konva 将事件绑定到任何形状。您还将了解事件委托和传播。有时,您可能需要以编程方式控制形状的点击区域以及触发事件。我们也将讨论这两个主题。

将事件绑定到形状

您可以借助 on() 方法将不同的事件绑定到使用 Konva 创建的任何形状。您所要做的就是将事件名称作为第一个参数传递,并将事件发生时要执行的函数作为第二个参数传递。您可以使用 Konva 检测 mouseupmousedownmouseentermouseleavemouseover mousemoveclickdblclick。此外,Konva 还允许您检测 wheeldragstartdragmovedragend 事件。

这里是一个检测正多边形(六边形)上的 mousedownmouseleave 事件的示例。同样,较小的圆圈绑定到 mouseovermouseup 事件,较大的圆圈绑定到 mouseentermouseleavemousemove 事件。

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();
});

如果用户在光标位于正多边形内时按下任意鼠标按钮,我们会将多边形的边数增加 1。 sides() 方法可以在不带参数的情况下使用获取多边形的边数或与一个参数一起使用来设置多边形的边数。您还可以使用 getSides() 获取边数,并使用 setSides() 设置边数。每当鼠标光标离开多边形时,多边形的边就会减一。

对于较小的圆圈, mouseover 事件用于将描边宽度值设置为 10。 mouseup 事件将描边宽度值更改为 5。请记住mouseup 事件必须发生在圆本身内部。例如,如果在圆内按下鼠标按钮,然后在光标移至圆外后才松开鼠标按钮,则描边宽度不会更改为 5。

对于较大的圆圈,我们使用 mousemove 事件来更改其 fill 颜色。每当光标移入和移出圆圈时,我们还会使用 stage.container().style.cursor 更改较大圆圈的光标。

您应该记住的一件重要的事情是,如果任何形状的事件侦听器导致诸如 fill 之类的属性发生更改,则必须在相应图层上调用 draw() 方法颜色、描边宽度等。否则,更改将不会反映在画布上。

您不必一次将一个事件绑定到一个形状。您还可以将包含多个事件类型的空格分隔字符串传递给 on() 方法。这会将字符串中列出的所有事件绑定到该特定形状。

Konva 还支持所有这些活动的相应移动版本。例如,您可以注册touchstarttouchmove, touchend, tap, 在移动设备上使用 Konva 的 dbltapdragstartdragmovedragend

您还可以使用 fire() 方法针对特定形状触发任何这些事件。同样,Konva 允许您触发自定义事件,例如 throwStones

删除事件监听器

您可以借助 Konva 中的 off() 方法删除附加到形状的任何事件侦听器。您只需指定您不想监听的事件名称即可。

您还可以为单个形状创建多个事件绑定。例如,假设您有一个圆,并且您希望每次鼠标光标经过它时都增加圆的半径,直至达到一定限制。您可能还想在每个 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() 方法以编程方式触发自己的自定义事件。本教程的最后一部分向您展示了如何定义自己的命中区域,以便检测可能大于或小于原始形状的区域上的命中。

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

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

以上就是Konva 的 HTML5 Canvas 事件:第 5 部分,操作的详细内容,更多请关注编程之家其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)