Rumah  >  Artikel  >  hujung hadapan web  >  Acara Kanvas HTML5 untuk Konva: Bahagian 5, Tindakan

Acara Kanvas HTML5 untuk Konva: Bahagian 5, Tindakan

WBOY
WBOYasal
2023-09-03 10:33:031028semak imbas

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

Jika anda mengikuti siri ini dari awal, anda sepatutnya sudah biasa dengan bentuk, kumpulan dan lapisan sekarang. Anda juga seharusnya boleh melukis beberapa bentuk asas dan kompleks dengan mudah pada kanvas menggunakan Konva. Jika anda bercadang untuk menggunakan Konva untuk mencipta beberapa aplikasi atau permainan interaktif, maka mempelajari cara mengikat acara kepada bentuk yang berbeza di atas pentas ialah langkah logik seterusnya.

Dalam tutorial ini, anda akan belajar cara mengikat acara pada sebarang bentuk menggunakan Konva. Anda juga akan belajar tentang delegasi dan penyebaran acara. Kadangkala anda mungkin perlu mengawal secara pemrograman kawasan klik bentuk dan mencetuskan peristiwa. Kami juga akan membincangkan dua topik ini.

Ikat peristiwa kepada bentuk

Anda boleh mengikat acara berbeza pada sebarang bentuk yang dibuat dengan Konva dengan bantuan kaedah on(). Apa yang anda perlu lakukan ialah lulus nama acara sebagai argumen pertama dan fungsi yang akan dilaksanakan apabila acara berlaku sebagai argumen kedua. Anda boleh menggunakan Konva untuk mengesan mouseup, mousedown, mouseup, mouseleave, mouseover , mouseover, klik dan <code class="inline">dblclick. Selain itu, Konva membenarkan anda untuk mengesan wheel, dragstart, dragmove dan dragend acara. 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()

Berikut ialah contoh pengesanan acara mousedown dan mouseleave pada poligon biasa (heksagon). Begitu juga, kalangan yang lebih kecil terikat pada acara mouseover dan mouseup dan kalangan yang lebih besar terikat pada masuk tetikus, mouseleave dan mousemove. 🎜
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();
});
🎜Jika pengguna menekan mana-mana butang tetikus semasa kursor berada di dalam poligon biasa, kami akan menambah bilangan sisi poligon sebanyak 1. Kaedah sides() boleh digunakan tanpa parameter untuk mendapatkan bilangan sisi poligon atau dengan satu parameter untuk menetapkan bilangan sisi poligon. Anda juga boleh menggunakan getSides() untuk mendapatkan bilangan sisi dan setSides() untuk menetapkan bilangan sisi. Setiap kali kursor tetikus meninggalkan poligon, sisi poligon dikurangkan satu. 🎜 🎜Untuk kalangan yang lebih kecil, acara mouseover digunakan untuk menetapkan nilai lebar lejang kepada 10. Acara mouseup menukar nilai lebar lejang kepada 5. Ingat bahawa acara mouseup mesti berlaku di dalam bulatan itu sendiri. Sebagai contoh, jika anda menekan butang tetikus di dalam bulatan dan kemudian melepaskan butang tetikus selepas kursor bergerak ke luar bulatan, lebar lejang tidak berubah kepada 5. 🎜 🎜Untuk kalangan yang lebih besar, kami menggunakan acara mousemove untuk menukar warna isinya. Kami juga menggunakan stage.container().style.cursor untuk menukar kursor bagi bulatan yang lebih besar setiap kali kursor bergerak masuk dan keluar dari bulatan. 🎜 🎜🎜 🎜Satu perkara penting yang perlu anda ingat ialah jika sebarang pendengar acara bentuk menyebabkan sifat seperti isian berubah, anda mesti memanggil draw() pada lapisan yang sepadan Warna kaedah, lebar lejang, dsb. Jika tidak, perubahan tidak akan ditunjukkan pada kanvas. 🎜 🎜Anda tidak perlu mengikat acara pada satu bentuk pada satu masa. Anda juga boleh menghantar rentetan terhad ruang yang mengandungi berbilang jenis acara kepada kaedah on(). Ini akan mengikat semua peristiwa yang disenaraikan dalam rentetan kepada bentuk tertentu itu. 🎜 🎜Konva juga menyokong versi mudah alih yang sepadan untuk semua aktiviti ini. Contohnya, anda boleh mendaftar touchstart, gerak sentuh, sentuh, ketik, Gunakan dbltap Konva, dragstart, dragmove dan dragend pada peranti mudah alih. 🎜 🎜Anda juga boleh mencetuskan mana-mana peristiwa ini untuk bentuk tertentu menggunakan kaedah fire(). Begitu juga, Konva membenarkan anda mencetuskan acara tersuai seperti throwStones. 🎜 🎜Padamkan pendengar acara🎜 🎜Anda boleh mengalih keluar sebarang pendengar acara yang dilampirkan pada bentuk dengan bantuan kaedah off() dalam Konva. Anda hanya tentukan nama acara yang anda tidak mahu dengar. 🎜

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

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

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

Atas ialah kandungan terperinci Acara Kanvas HTML5 untuk Konva: Bahagian 5, Tindakan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn