laxer
laxer

Reputation: 760

Konva group X&Y different than shape X&Y

I am trying to edit another example that was posted on here but something doesn't seem right. I have a shape and then a couple of shapes that are grouped together with an arrow that is pointing in between the two shapes. As one of the shapes is dragged the arrow position should move as well.

The Problem

The problem is that the shape seems to be on a different coordinate system where its 0,0 point is in the upper left corner, whereas the groups coordinate system where its 0,0 point is right in the middle of the screen. What am I doing wrong?

Code

<!DOCTYPE html>
<html>

<head>
  <script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script>
  <meta charset="utf-8">
  <title>Konva Circle Demo</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #F0F0F0;
    }
  </style>
</head>

<body>
  <div id="container"></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 group = new Konva.Group({
        x:120,
        y:120,
      draggable: true,
    });

    var circle = new Konva.Circle({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      radius: 40,
      fill: 'green',
      stroke: 'black',
      strokeWidth: 2,

    });

    var circleA = new Konva.Circle({
      x: stage.getWidth() / 5,
      y: stage.getHeight() / 5,
      radius: 30,
      fill: 'red',
      stroke: 'black',
      strokeWidth: 2,
      draggable: true
    });

    var arrow = new Konva.Arrow({
      points: [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()],
      pointerLength: 10,
      pointerWidth: 10,
      fill: 'black',
      stroke: 'black',
      strokeWidth: 4
    });



        var star = new Konva.Star({
            x: stage.getWidth() / 2,
            y: stage.getHeight() / 2,
            numPoints: 5,
            innerRadius: 30,
            outerRadius: 50,
            fill: '#89b717',
            opacity: 0.8,
            scale: {
                x : 1.4,
                y : 1.4
            },
            rotation: Math.random() * 180,
            shadowColor: 'black',
            shadowBlur: 10,
            shadowOffset: {
                x : 5,
                y : 5
            },
            shadowOpacity: 0.6,

        });

        //layer.add(star);

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



    function adjustPoint(e){
      var p=[circle.getX(), circle.getY(), circleA.getX(), circleA.getY()];
      arrow.setPoints(p);
      layer.draw();
      console.log(group.getX(),group.getY());
      console.log(circleA.getX(),circleA.getY());
    }

    //circle.on('dragmove', adjustPoint);

    group.on('dragmove', adjustPoint);

    circleA.on('dragmove', adjustPoint);

    group.add(star,circle);
    //group.add(circle);
    layer.add(group);
    layer.add(circleA);
    // add the shape to the layer
    //layer.add(circle);
    layer.add(arrow);
    //layer.add(star);


    // add the layer to the stage
    stage.add(layer);

  </script>

</body>

</html>

Upvotes: 2

Views: 2046

Answers (1)

Vanquished Wombat
Vanquished Wombat

Reputation: 9525

When you put a shape on a group, it's getX() and getY() functions return values relative to the origin point of the group. Your error was to assume that the X, Y position of the circle in the group would change as the group is dragged.

In the working code below, based on your posted code, I changed only the first line of the AdjustPoint() function so that the X, Y position of the circle has added to it the X, Y position of the group.

This fixes your issue.

Tip: as you start using groups be aware that their extent on the page is that of the minimum rectangle needed to contain the group shapes. If you want to specifically control the size and location of a group, add to it a Rect() shape of specific width and height to give a known size to the group.

I also added a call to that function at the end of the code so that the arrow joins when the code initially runs.

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 group = new Konva.Group({
        x:120,
        y:10,
      draggable: true,
    });

    var circle = new Konva.Circle({
      x: stage.getWidth() / 2,
      y: 60,
      radius: 40,
      fill: 'green',
      stroke: 'black',
      strokeWidth: 2,

    });

    var circleA = new Konva.Circle({
      x: stage.getWidth() / 5,
      y: stage.getHeight() / 5,
      radius: 30,
      fill: 'red',
      stroke: 'black',
      strokeWidth: 2,
      draggable: true
    });

    var arrow = new Konva.Arrow({
      points: [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()],
      pointerLength: 10,
      pointerWidth: 10,
      fill: 'black',
      stroke: 'black',
      strokeWidth: 4
    });

    var star = new Konva.Star({
        x: stage.getWidth() / 2,
        y: 60,
        numPoints: 5,
        innerRadius: 30,
        outerRadius: 50,
        fill: '#89b717',
        opacity: 0.8,
        scale: {
            x : 1.4,
            y : 1.4
        },
        rotation: Math.random() * 180,
        shadowColor: 'black',
        shadowBlur: 10,
        shadowOffset: {
            x : 5,
            y : 5
        },
        shadowOpacity: 0.6,
    });

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



    function adjustPoint(e){
    // changes here
      var p=[ group.getX() + circle.getX(), group.getY()  + circle.getY(), circleA.getX(),  circleA.getY()];
    // changes here

      arrow.setPoints(p);
      layer.draw();
      stage.draw();
    //  console.log('group = ' + group.getX() + ', ' + group.getY());
    //  console.log('red circle = ' + circleA.getX() + ', ' + circleA.getY());
    }

    //circle.on('dragmove', adjustPoint);

    group.on('dragmove', adjustPoint);

    circleA.on('dragmove', adjustPoint);

    group.add(star,circle);
    //group.add(circle);
    layer.add(group);

    layer.add(circleA);
    // add the shape to the layer
    //layer.add(circle);
    layer.add(arrow);
    //layer.add(star);


    // add the layer to the stage
    stage.add(layer);

    // changes here
    adjustPoint();
body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #F0F0F0;
    }
<script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script>

<body>
  <div id="container"></div>

</body>

Upvotes: 2

Related Questions