0

I am trying to flip a group (horizontally) using Konvajs.Following the advice of this post, I am using the scaleX property. This works---mostly. However, it doesn't flip around the center.

function reverse(shape){
   var layer = shape.getLayer();
   var oldScaleX = shape.attrs.scaleX;
   var width = shape.getClientRect().width;
   var adjuster = oldScaleX * width;
   var startX = shape.attrs.x + adjuster;
   var startY = shape.attrs.y;
   shape.scaleX(-oldScaleX); 
   shape.position({x: startX, y: startY});
   layer.draw();
};

I tried using the offsetX and offsetY properties like in this post, but it doesn't seem to do anything.

shape.offsetX(shape.width()/2);
shape.offsetY(shape.height()/2);
shape.x(shape.x() - shape.attrs.offsetX);
shape.y(shape.y() - shape.attrs.offsetY);

The shapes will flip initially, but if they are rotated first, they tend to jump around.

Codepen

  • I posted [something re rotation points](https://stackoverflow.com/questions/53277253/rotating-around-a-point-offset-function-moves-the-shape) - maybe of assistance. – Vanquished Wombat Nov 13 '18 at 09:28
  • It will be much simpler for you if you will set the origin of the shape to its center (with using offset) before any flip action. On the flip you just need to apply a negative scale. – lavrton Nov 14 '18 at 15:15

1 Answers1

0

Based on my function posted in this other question, here is a snippet to rotate a shape around its centre. In this case the shape is a group composed of 2 rects but any shape will work.

// Set up the canvas / stage
  var stage = new Konva.Stage({container: 'container', width: 600, height: 200});
  var layer = new Konva.Layer({draggable: false});
  stage.add(layer);

  var shape = new Konva.Group({x: 80, y: 40, width: 60, height: 60 });
  var r1 = new Konva.Rect({ x:10, y:10, width: 70, height: 40, fill: 'cyan'})
  var r2 = new Konva.Rect({ x:50, y:10, width: 40, height: 100, fill: 'cyan'})
  shape.add(r1)  
  shape.add(r2)  
  layer.add(shape)


  // set the group rotate point. Note - x,y is relative to top-left of stage !
 var pos = shape.getClientRect();
  RotatePoint(shape, {x: pos.x + pos.width/2, y: pos.y + pos.height/2});

  stage.draw();

  // This is where the flip happens 
  var scaleX = 1, inc = -0.2;  // set inc = 1 for full flip in one call
  function flipShape(){

    scaleX = scaleX + inc;
    shape.scaleX(scaleX); // and that's it

    // fun with colors on front and back of shape
    r1.fill(scaleX < 0 ? 'magenta' : 'cyan');
    r2.fill(scaleX < 0 ? 'magenta' : 'cyan');

    $('#info').html('Set ScaleX(' + scaleX.toFixed(2) + ')'); // What's happening?

    layer.draw();  // show the change

    inc = (scaleX % 1 === 0 ? -1 * inc : inc);  // decide next increment, reversed at 1 & -1
  }

$('#flip').on('click', function(e){

  flipShape(); // click button - flip shape a bit

})


/*
Set the offset for rotation to the given location and re-position the shape
*/
function RotatePoint(shape, pos){  // where pos = {x: xpos, y: yPos}
var initialPos = shape.getAbsolutePosition();
var moveBy = {x: pos.x - initialPos.x, y: pos.y - initialPos.y};

// offset is relative to initial x,y of shape, so deduct x,y.
shape.offsetX(moveBy.x);
shape.offsetY(moveBy.y);

// reposition x,y because changing offset moves it.
shape.x(initialPos.x + moveBy.x);
shape.y(initialPos.y + moveBy.y);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
<p>Clck the button to progressively flip a shape using scaleX &nbsp;<button id='flip'>Flip a bit</button>&nbsp;<span id='info'></span></p>

<div id='container' style="position: absolute; top: 0; z-index: -1; display: inline-block; width: 600px, height: 200px; background-color: silver; "></div>
Vanquished Wombat
  • 9,075
  • 5
  • 28
  • 67