警告:运行代码片段之前,请先调低音量!

我希望能够在舞台上单击以添加“模块”形状。但是我发现单击“模块”形状本身会创建另一个形状,这意味着应该在不应该触发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>

最佳答案

当您希望舞台监听舞台内容上的事件时,stage.contentClick()侦听器是一种特殊情况。但是,cancelBubble()函数并不能阻止事件发生,例如,单击形状到stage.contentClick()侦听器。

为了获得想要的效果,即给人以点击舞台的印象,您需要添加一个填充舞台的rect,并监听该rect而不是舞台上的事件。

下面是一个工作示例。我特意添加了红色背景,所以您知道舞台上方还有其他地方。要删除此内容,请在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>

关于javascript - 将监听器设置为舞台点击,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47948575/

10-11 14:10