1

This piece of code creates rectangles every time the canvas is clicked on. Each rectangle object is then pushed into an array. I would like each rectangle created being able to return its own array index when clicked on.

What do I want to achieve with this?

My idea a software with GUI that allows creating modules/nodes with input and output ports and connect them with wires (like Max/MSP, Pure Data, Quartz Composer, Reaktor, NodeRed, etc.). In order to be able to connect the modules with each other, they need to be able to return their own ID so a function external to the modules can connect them.

var width = window.innerWidth - 50;
var height = window.innerHeight - 100;

var rectArray = [];

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

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

var clickRect = new Konva.Rect({ // clickable background
  x: 0,
  y: 0,
  width: width,
  height: height,
  stroke: 'black',
  strokeWidth: 2,
  listening: 'true'
})
layer.add(clickRect);

var text = new Konva.Text({ //text to display info
  x: 10,
  y: 10,
  fontFamily: 'Calibri',
  fontSize: 24,
  text: '',
  fill: 'black'
});

clickRect.on('click', function() { /// here we create a module
  var newRect = new createModule();
  rectArray.push(newRect);
});

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

  var rect = new Konva.Rect({
    x: mouseX,
    y: mouseY,
    width: 50,
    height: 50,
    stroke: 'black',
    strokeWidth: 2,
    draggable: true
  });

  rect.on('click', function(evt) {
    alert("clicked");
  })

  text.setText(rectArray.length + 1);
  layer.add(text);
  layer.add(rect);
  stage.add(layer);
}
stage.draw(); // draw so we can see click rect.
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
<p id="display1">-</p>
alkopop79
  • 547
  • 12
  • 28

2 Answers2

1

Depends on your needs. You could give the index (which is equal to the length before you push in the array) to your "constructor" (even if you're not really creating an object here IMO) :

var width = window.innerWidth - 50;
var height = window.innerHeight - 100;

var rectArray = [];

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

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

var clickRect = new Konva.Rect({ // clickable background
  x: 0,
  y: 0,
  width: width,
  height: height,
  stroke: 'black',
  strokeWidth: 2,
  listening: 'true'
})
layer.add(clickRect);

var text = new Konva.Text({ //text to display info
  x: 10,
  y: 10,
  fontFamily: 'Calibri',
  fontSize: 24,
  text: '',
  fill: 'black'
});

clickRect.on('click', function() { /// here we create a module
  var newRect = new createModule(rectArray.length);
  rectArray.push(newRect);
});

function createModule(index) {
  var mouseX = stage.getPointerPosition().x;
  var mouseY = stage.getPointerPosition().y;

  var rect = new Konva.Rect({
    x: mouseX,
    y: mouseY,
    width: 50,
    height: 50,
    stroke: 'black',
    strokeWidth: 2,
    draggable: true
  });

  rect.on('click', function(evt) {
    alert("clicked on " + index);
  })

  text.setText(rectArray.length + 1);
  layer.add(text);
  layer.add(rect);
  stage.add(layer);
}
stage.draw(); // draw so we can see click rect.
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
<p id="display1">-</p>

But if your array is being modified, then you should keep track of the object's instance (var self = this;) and use indexOf on rectArray to dynamically find its index :

var width = window.innerWidth - 50;
var height = window.innerHeight - 100;

var rectArray = [];

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

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

var clickRect = new Konva.Rect({ // clickable background
  x: 0,
  y: 0,
  width: width,
  height: height,
  stroke: 'black',
  strokeWidth: 2,
  listening: 'true'
})
layer.add(clickRect);

var text = new Konva.Text({ //text to display info
  x: 10,
  y: 10,
  fontFamily: 'Calibri',
  fontSize: 24,
  text: '',
  fill: 'black'
});

clickRect.on('click', function() { /// here we create a module
  var newRect = new createModule();
  rectArray.push(newRect);
});

function createModule() {
  var mouseX = stage.getPointerPosition().x;
  var mouseY = stage.getPointerPosition().y;
  var self = this;
  
  var rect = new Konva.Rect({
    x: mouseX,
    y: mouseY,
    width: 50,
    height: 50,
    stroke: 'black',
    strokeWidth: 2,
    draggable: true
  });

  rect.on('click', function(evt) {
    var index = rectArray.indexOf(self);
    alert("clicked on " + index);
  })

  text.setText(rectArray.length + 1);
  layer.add(text);
  layer.add(rect);
  stage.add(layer);
}
stage.draw(); // draw so we can see click rect.
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
<p id="display1">-</p>
Serge K.
  • 5,303
  • 1
  • 20
  • 27
1

First: you need to return the created rect in the createModule function. You should not need the newkeyword when calling that function.

Then you can just query the index of the clicked rect like rectArray.indexOf(evt.target)

var width = window.innerWidth - 50;
var height = window.innerHeight - 100;

var rectArray = [];

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

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

var clickRect = new Konva.Rect({ // clickable background
  x: 0,
  y: 0,
  width: width,
  height: height,
  stroke: 'black',
  strokeWidth: 2,
  listening: 'true'
})
layer.add(clickRect);

var text = new Konva.Text({ //text to display info
  x: 10,
  y: 10,
  fontFamily: 'Calibri',
  fontSize: 24,
  text: '',
  fill: 'black'
});

clickRect.on('click', function() { /// here we create a module
  var newRect = createModule();
  rectArray.push(newRect);
});

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

  var rect = new Konva.Rect({
    x: mouseX,
    y: mouseY,
    width: 50,
    height: 50,
    stroke: 'black',
    strokeWidth: 2,
    draggable: true
  });

  rect.on('click', function(evt) {
    alert(rectArray.indexOf(evt.target));
  })

  text.setText(rectArray.length + 1);
  layer.add(text);
  layer.add(rect);
  stage.add(layer);
  return rect;
}
stage.draw(); // draw so we can see click rect.
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
<p id="display1">-</p>
Martin Schneider
  • 3,268
  • 4
  • 19
  • 29