4

I have a problem with the Zindex in konva.js. After I added everything to the layer I am trying to assign a property to a node for each element separately. But it does not work. For example

for(let i = 0; i<=this.layer['children']; i++){
    this.layer['children'][i].setZIndex(someInt);
}

How can i set zindex for all elements in layer?

  • Not relevant. I thought that you could set any number in the property. But it turns out the maximum number is the number of elements. – Kamron Maxmudov Oct 11 '18 at 08:24

4 Answers4

4

zIndex in Konva is just index of the element in an array of children of the parent element. So you can't set any number to it and it can not be bigger than children.length - 1.

lavrton
  • 18,973
  • 4
  • 30
  • 63
  • Just to clarify, in some dev languages like VB6 you can set z-index to any positive or negative number so I get why the OP may have thought this way. What you are saying for Konvajs is that if I have four shapes on a layer, the lowest value I can place as the value in setZindex() is 0 and the highest is 3 ? Or is it 1 and 4 ? – Vanquished Wombat Oct 11 '18 at 13:12
  • 1
    @VanquishedWombat from 0 to 3 – lavrton Oct 11 '18 at 13:21
  • Technically other numbers may work too (I mean no errors). But can give unexpected results. – lavrton Oct 11 '18 at 13:23
1

Working snippet illustrating the getZIndex(), setZIndex(), moveUp() and moveDown() methods of the Kovajs.Shape object. See also example at Konvajs site.

Buttons allow use to move green circle up and down the z-index list by increments of 1, then also to try to move up +10 and down -100. Resulting z-index is shown in text below circles.

// Create the stage
var stage = new Konva.Stage({
    container: 'container',
    width: $('#container').width(),
    height: $('#container').height()
});

// create the layer
var layer = new Konva.Layer();

var data = [ {x: 60, color: 'red'}, {x: 90, color: 'limegreen'}, {x: 120, color: 'gold'}]
var circles = [];

for (var i = 0; i < data.length; i = i + 1){
  // create some circles
  var circle = new Konva.Circle({
      x: data[i].x,
      y: 60,
      radius: 50,
      fill: data[i].color,
      stroke: 'black',
      strokeWidth: 2
  });
  layer.add(circle);
  circles.push(circle);
}

stage.add(layer);

var green = circles[1]; 
function sayIndex(){
$('#info').html("Green zIndex=" + circles[1].getZIndex());
}

$('#greenup').on('click', function(){
  green.moveUp();
  sayIndex();
  layer.draw();
})

$('#greendn').on('click', function(){
  green.moveDown();
  sayIndex();
  layer.draw();
})


$('#greenup10').on('click', function(){
  var ind = circles[1].getZIndex();
  green.setZIndex(ind + 10);
  sayIndex();
  layer.draw();
})

$('#greendn100').on('click', function(){
  var ind = circles[1].getZIndex();
  green.setZIndex(ind - 100);
  sayIndex();
  layer.draw();
})
#container
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#buttons
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#info
{
position: absolute;
left: 20px;
top: 135px;
}
p
{
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<div id="container"></div>
<div id="buttons">

<p><button id='greenup'>Move Green + 1</button></p>
<p><button id='greendn'>Move Green -1</button></p>
<p><button id='greenup10'>Move Green +10</button></p>
<p><button id='greendn100'>Move Green -100</button></p>

<span id='info'></span>

</div>
Vanquished Wombat
  • 9,075
  • 5
  • 28
  • 67
1

<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/konva@2.4.2/konva.min.js"></script>
  <meta charset="utf-8">
  <title>Konva Shape Layering Demo</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #F0F0F0;
    }
    #buttons {
        position: absolute;
        left: 10px;
        top: 0px;
    }
    button {
        margin-top: 10px;
        display: block;
    }
  </style>
</head>
<body>
  <div id="container"></div>
  <div id="buttons">
      <button id="toTop">
yellow z-index -2
     </button>
      <button id="toBottom">
      yellow -9
      </button>
      <button id="up">
          yellow z-index 1
      </button>
      <button id="down">
          yellow z-index -5
      </button>
      <button id="zIndex">
          Set yellow box zIndex to 3
      </button>
  </div>
  <script>
    var width = window.innerWidth;
    var height = window.innerHeight;
    
    var stage = new Konva.Stage({
      container: 'container',
      width: width,
      height: height
    });

    var layer = new Konva.Layer();
    var offsetX = 0;
    var offsetY = 0;
    var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
    var yellowBox = null;

    for(var n = 0; n < 6; n++) {
        // anonymous function to induce scope
        (function() {
            var i = n;
            var box = new Konva.Rect({
                x: i * 30 + 210,
                y: i * 18 + 40,
                width: 100,
                height: 50,
                fill: colors[i],
                stroke: 'black',
                strokeWidth: 4,
                draggable: true,
                name: colors[i]
            });

            box.on('mouseover', function() {
                document.body.style.cursor = 'pointer';
            });
            box.on('mouseout', function() {
                document.body.style.cursor = 'default';
            });
            if(colors[i] === 'yellow') {
                yellowBox = box;
            }
            layer.add(box);
        })();
    }

    stage.add(layer);

    // add button event bindings
    document.getElementById('toTop').addEventListener('click', function() {
        yellowBox.setZIndex(-2);
        layer.draw();
    }, false);

    document.getElementById('toBottom').addEventListener('click', function() {
        yellowBox.setZIndex(-9);
        layer.draw();
    }, false);

    document.getElementById('up').addEventListener('click', function() {
        yellowBox.setZIndex(1);
        layer.draw();
    }, false);

    document.getElementById('down').addEventListener('click', function() {
        yellowBox.setZIndex(-5);
        layer.draw();
    }, false);

    document.getElementById('zIndex').addEventListener('click', function() {
        yellowBox.setZIndex(3);
        layer.draw();
    }, false);
  </script>

</body>
</html>
Last

Fun messing with ZIndex code, the setZIndex is all you need; It will vain the z-index inside Konva.JS

1

If you would prefer to be able to set the render order of nodes using arbitrary numbers (like CSS, or how it works in most game engines, etc), you can use this fork of Konva. Alternatively, you could also grab & apply just the rejected pull request for this feature if you already have a customized Konva version.

The new feature works by adding a zOrder property to all Nodes, and a special kind of group AbsoluteRenderOrderGroup that reads and understands this property for all children.

Skye
  • 11
  • 3