为Stage click设置监听器

问题描述 投票:1回答:1

警告:在运行代码段之前调低音量!

我希望能够在舞台上单击以添加“模块”形状。但我发现单击“模块”形状本身会创建另一个,这意味着stage.click侦听器在不应该被触发时被触发。

当我点击一个形状时,如何才能有一个不会错误触发的stage.click监听器?

var width = window.innerWidth;
var height = window.innerHeight;

var rectButtonClicked  = false;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height
});

var layer = new Konva.Layer();

var group = new Konva.Group({
  draggable: true
});

stage.on('contentClick', function() {
  createModule();
});

function createModule() {

  var mouseX = stage.getPointerPosition().x;
  var mouseY = stage.getPointerPosition().y;

  var rect = new Konva.Rect({ //module rect
    x: mouseX,
    y: mouseY,
    width: 100,
    height: 50,
    cornerRadius: 5,
    fill: '#BEDBDD',
    stroke: '#807C7B',
    strokeWidth: 2,
    draggable: true
  });
  group.add(rect);

    var buttonRect = new Konva.Rect({ //button
    x: mouseX+80,
    y: mouseY+20,
    width: 10,
    height: 10,
    cornerRadius: 1,
    fill: 'blue',
    stroke: '#807C7B',
    strokeWidth: 1,
  });
  group.add(buttonRect)

  var text = new Konva.Text({  //text on module
    x: mouseX + 20,
    y: mouseY + 20,
    //fontFamily: 'Calibri',
    fontSize: 16,
    text: 'OSC',
    fill: 'black'
  });
  group.add(text);

  var randomFreq = getRandomInt();
  var osc = new Tone.Oscillator(randomFreq, "sawtooth");
  layer.add(group);
  stage.add(layer);

  buttonRect.on('click', function() {
    rectButtonClicked = !rectButtonClicked;
    if(rectButtonClicked){    
    osc.toMaster().start();
    this.setFill('red');
    }  else {
    osc.stop();
    this.setFill('blue');
    }  
});
}

function getRandomInt() {
  min = Math.ceil(100);
  max = Math.floor(1000);
  return Math.floor(Math.random() * (max - min)) + min;
}

var width = window.innerWidth;
var height = window.innerHeight;

//var drag = false;
var rectButtonClicked  = false;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height
});

var layer = new Konva.Layer();

var group = new Konva.Group({
  draggable: true
});

stage.on('contentClick', function() {
  createModule();
});

function createModule() {

  var mouseX = stage.getPointerPosition().x;
  var mouseY = stage.getPointerPosition().y;

  var rect = new Konva.Rect({ //module rect
    x: mouseX,
    y: mouseY,
    width: 100,
    height: 50,
    cornerRadius: 5,
    fill: '#BEDBDD',
    stroke: '#807C7B',
    strokeWidth: 2,
    draggable: true
  });
  group.add(rect);
  
    var buttonRect = new Konva.Rect({ //button
    x: mouseX+80,
    y: mouseY+20,
    width: 10,
    height: 10,
    cornerRadius: 1,
    fill: 'blue',
    stroke: '#807C7B',
    strokeWidth: 1,
  });
  group.add(buttonRect)
  
  var text = new Konva.Text({  //text on module
    x: mouseX + 20,
    y: mouseY + 20,
    //fontFamily: 'Calibri',
    fontSize: 16,
    text: 'OSC',
    fill: 'black'
  });
  group.add(text);
  
  var randomFreq = getRandomInt();
  var osc = new Tone.Oscillator(randomFreq, "sawtooth");
  layer.add(group);
  stage.add(layer);
  
  buttonRect.on('click', function() {
    rectButtonClicked = !rectButtonClicked;
    if(rectButtonClicked){    
    osc.toMaster().start();
    this.setFill('red');
    }  else {
    osc.stop();
    this.setFill('blue');
    }  
});
}

function getRandomInt() {
  min = Math.ceil(100);
  max = Math.floor(1000);
  return Math.floor(Math.random() * (max - min)) + min;
}
<script src="https://tonejs.github.io/build/Tone.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<div id="container"></div>
javascript konvajs
1个回答
2
投票

stage.contentClick()侦听器是您希望舞台监听舞台内容上的事件时使用的特殊情况。但是,cancelBubble()函数不会阻止从单击形状到stage.contentClick()侦听器冒泡的事件。

为了获得您想要的效果,这会给人一种在舞台上发生点击的印象,您需要添加一个填充舞台的矩形并在该矩阵而不是舞台上侦听事件。

下面是一个工作示例。我故意添加了红色背景,所以你知道舞台上还有其他东西。要删除它,请取出clickRect上的填充颜色。

我还修复了按钮,以便将内容正确分组并拖动到一起。您几乎是正确的,但您需要在createModule()函数中创建组。你可以看到我也使组元素dragabble = false来完成这个过程。

我添加了几个控制台写入,以显示事件何时触发。

[当我打开音调时,我也感到非常震惊]。

var width = window.innerWidth;
var height = window.innerHeight;

//var drag = false;
var rectButtonClicked  = false;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height
});

var layer = new Konva.Layer();
stage.add(layer);

var clickRect =  new Konva.Rect({ 
  x:0,
  y:0,
  width: width,
  height: height,
  fill: 'red',
  stroke: '#807C7B',
  strokeWidth: 2,
  listening: 'true'  
})
layer.add(clickRect);

clickRect.on('click', function() {
  console.log('Stage click');
  createModule();
});

function createModule() {
  var group = new Konva.Group({ // move group create into createModule
    draggable: true  // we will make the elements not draggable - we drag the group
  });

  var mouseX = stage.getPointerPosition().x;
  var mouseY = stage.getPointerPosition().y;

  var rect = new Konva.Rect({ //module rect
    x: mouseX,
    y: mouseY,
    width: 100,
    height: 50,
    cornerRadius: 5,
    fill: '#BEDBDD',
    stroke: '#807C7B',
    strokeWidth: 2,
    draggable: false // make the element not draggable - we drag the group
  });
  group.add(rect);
  
  rect.on('click', function(evt){
  console.log('Clicked on button');
  })
  
    var buttonRect = new Konva.Rect({ //button
    x: mouseX+80,
    y: mouseY+20,
    width: 10,
    height: 10,
    cornerRadius: 1,
    fill: 'blue',
    stroke: '#807C7B',
    strokeWidth: 1,
    listening: true,
    draggable: false  // make the element not draggable - we drag the group
  });
  group.add(buttonRect)

  var text = new Konva.Text({  //text on module
    x: mouseX + 20,
    y: mouseY + 20,
    //fontFamily: 'Calibri',
    fontSize: 16,
    text: 'OSC',
    fill: 'black',
    draggable: false  // make the element not draggable - we drag the group
  });
  group.add(text);
  
  var randomFreq = getRandomInt();
  var osc = new Tone.Oscillator(randomFreq, "sawtooth");
  layer.add(group);
  stage.add(layer);

  buttonRect.on('click', function(evt) {
    rectButtonClicked = !rectButtonClicked;
    if(rectButtonClicked){    
    osc.toMaster().start();
    this.setFill('red');
    }  else {
    osc.stop();
    this.setFill('blue');
    }  
});
}

function getRandomInt() {
  min = Math.ceil(100);
  max = Math.floor(1000);
  return Math.floor(Math.random() * (max - min)) + min;
}
stage.draw(); // draw so we can see click rect.
<script src="https://tonejs.github.io/build/Tone.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<div id="container" style="background-color: gold;"></div>
© www.soinside.com 2019 - 2024. All rights reserved.