Konva – Flip an image in-place

Someone asked on the Discord channel about how to flip an image – the case related to artwork on a tee-shirt designer app. Here’s my thoughts on that…

TLDR: Here’s the sample code at codepen

The way to slip an image is to set its scale to -1. Keep in mind that this will reverse the image too – if you want to flip without reversing then you need to rotate it – see my other post about that.

A note about offset: you can read in the Konva docs about manipulating the offset point to make an image flip in place. I tend to stay away from messing with the offset because it introduces some dissonance between what I see and what my brain tells me I should see. You’re brain might be wired better than mine – if so you may want to leave now and use the offset method!

So – we know we can flip an image by setting scale to -1. And flip it back by setting to +1. The issue is that the point of inflection is the top-left position of the image, which means that the image will appear to be translated (that’s matrix-speak for ‘moved’) up and left. In the CodePen click the left hand button ‘Flip scale -1 (bad)’ to see the effect – or just look at the video below.

This is almost definitely not what we want to happen. My workaround is to move the image to where we want it to be at the same time as we flip it via the scale change. But note that this will also be problematic if you rotate the image – the computation of the new position is complex. The answer to keeping to simple math is to place the image into Konva.Group. Now the Group is being rotated, but the image is inside the group and therefore its co-ordinates are immune from the rotational complexity.

This is function is the heart of the approach – as you can see in the CodePen, all the (good) buttons invoke this function.

// This is a generic flip function covering flip H, flip V, 
// flip both, and reset. Note that resetPos is set to the 
// position that we use for position reset.
// And - make sure your image is inside a group!
//
function flip(direction, shape) {
  if (direction === "h") {

    const scaleX = -1 * shape.scaleX();
    shape.setAttrs({scaleX: scaleX, x: resetPos.x + (scaleX === -1 ? shape.width() : 0) });
    
  } else if (direction === "v") {

    const scaleY = -1 * shape.scaleY();
    shape.setAttrs({ scaleY: scaleY,  y: resetPos.y + (scaleY === -1 ? shape.height() : 0) });

  } else if (direction === "both") {

    flip('v', shape)
    flip('h', shape) 

  } else if (direction === "reset") {
    
    shape.setAttrs({ scale: { x: 1, y: 1 }, x: resetPos.x, y: resetPos.y });    
  
  }
}

Summary

We’ve seen a way to easily flip an image in-place, through the x and y axes, or both at once, even when the image is rotated. The approach works for any Konva shape or collection of shapes within a group. Hap flipping!

Thanks for reading.

VW. April 2023.

Image by Ridwan Muhamad Iqbal at Unsplash.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: