>  기사  >  웹 프론트엔드  >  Konva용 HTML5 Canvas 이벤트: 5부, 작업

Konva용 HTML5 Canvas 이벤트: 5부, 작업

WBOY
WBOY원래의
2023-09-03 10:33:03963검색

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

이 시리즈를 처음부터 따라오셨다면 이제 도형, 그룹, 레이어에 매우 익숙해졌을 것입니다. 또한 Konva를 사용하면 캔버스에 기본적이고 복잡한 모양을 쉽게 그릴 수 있습니다. Konva를 사용하여 대화형 응용 프로그램이나 게임을 만들 계획이라면 이벤트를 무대의 다양한 모양에 바인딩하는 방법을 배우는 것이 논리적인 다음 단계입니다.

이 튜토리얼에서는 Konva를 사용하여 이벤트를 모든 모양에 바인딩하는 방법을 배웁니다. 또한 이벤트 위임 및 전파에 대해서도 알아봅니다. 때로는 도형의 클릭 영역을 프로그래밍 방식으로 제어하고 이벤트를 트리거해야 할 수도 있습니다. 우리는 또한 이 두 가지 주제에 대해서도 논의할 것입니다.

이벤트를 모양에 바인딩

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

다음은 정다각형(육각형)에서 mousedownmouseleave 事件的示例。同样,较小的圆圈绑定到 mouseovermouseup 事件,较大的圆圈绑定到 mouseentermouseleavemousemove를 감지하는 이벤트입니다.

으아아아

커서가 정다각형 안에 있는 동안 사용자가 마우스 버튼을 누르면 다각형의 변의 수가 1씩 늘어납니다. sides() 方法可以在不带参数的情况下使用获取多边形的边数或与一个参数一起使用来设置多边形的边数。您还可以使用 getSides() 获取边数,并使用 setSides() 면 수를 설정하세요. 마우스 커서가 다각형을 떠날 때마다 다각형의 변이 하나씩 줄어듭니다.

작은 서클의 경우 mouseover 事件用于将描边宽度值设置为 10。 mouseup 事件将描边宽度值更改为 5。请记住mouseup 이벤트는 서클 자체 내에서 발생해야 합니다. 예를 들어 원 내부에서 마우스 버튼을 누른 다음 커서가 원 밖으로 이동한 후 마우스 버튼을 놓으면 획 너비가 5로 변경되지 않습니다.

더 큰 원의 경우 mousemove 事件来更改其 fill 颜色。每当光标移入和移出圆圈时,我们还会使用 stage.container().style.cursor를 사용하여 더 큰 원의 커서를 변경합니다.

기억해야 할 한 가지 중요한 점은 모양의 이벤트 리스너가 채우기와 같은 속성을 변경하는 경우 해당 레이어 색상, 획 너비 등에 대해 draw() 메서드를 호출해야 한다는 것입니다. 그렇지 않으면 변경 사항이 캔버스에 반영되지 않습니다.

이벤트를 한 번에 하나의 셰이프에 바인딩할 필요는 없습니다. 여러 이벤트 유형을 포함하는 공백으로 구분된 문자열을 on() 메소드에 전달할 수도 있습니다. 그러면 문자열에 나열된 모든 이벤트가 해당 특정 모양에 바인딩됩니다.

Konva는 이러한 모든 활동에 해당하는 모바일 버전도 지원합니다. 예를 들어, touchstart를 등록할 수 있습니다. touchmove, 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부, 작업의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.