Nov 20, 2022

# Solution 1 :

You can emulate similar CSS behavior with `cropX`, `cropY`, `cropWidth` and `cropHeight` properties of `Konva.Image`.

You can use this function for calculations:

``````function getCrop(image, size, clipPosition = 'center-middle') {
const width = size.width;
const height = size.height;
const aspectRatio = width / height;

let newWidth;
let newHeight;

const imageRatio = image.width / image.height;

if (aspectRatio >= imageRatio) {
newWidth = image.width;
newHeight = image.width / aspectRatio;
} else {
newWidth = image.height * aspectRatio;
newHeight = image.height;
}

let x = 0;
let y = 0;
if (clipPosition === 'left-top') {
x = 0;
y = 0;
} else if (clipPosition === 'left-middle') {
x = 0;
y = (image.height - newHeight) / 2;
} else if (clipPosition === 'left-bottom') {
x = 0;
y = (image.height - newHeight);
} else if (clipPosition === 'center-top') {
x = (image.width - newWidth) / 2;
y = 0;
} else if (clipPosition === 'center-middle') {
x = (image.width - newWidth) / 2;
y = (image.height - newHeight) / 2;
} else if (clipPosition === 'center-bottom') {
x = (image.width - newWidth) / 2;
y = (image.height - newHeight);
} else if (clipPosition === 'right-top') {
x = (image.width - newWidth);
y = 0;
} else if (clipPosition === 'right-middle') {
x = (image.width - newWidth);
y = (image.height - newHeight) / 2;
} else if (clipPosition === 'right-bottom') {
x = (image.width - newWidth);
y = (image.height - newHeight);
} else if (clipPosition === 'scale') {
x = 0;
y = 0;
newWidth = width;
newHeight = height;
} else {
console.error(
new Error('Unknown clip position property - ' + clipPosition)
);
}

return {
cropX: x,
cropY: y,
cropWidth: newWidth,
cropHeight: newHeight
}
}

// usage:
const crop = getCrop(img.image(), { width: img.width(), height: img.height()}, pos);
img.setAttrs(crop);
img.getLayer().batchDraw();
``````

# Problem :

Assume we have a 1000×1000 image drawn onto canvas, and set konva image size to something like 500×700.

Is it possible to mimic html `<img />` tags `object-fit` property in konva so we can tell image object to fit image in `cover` / `contain` mode. Similarly it would be useful to mimic `object-position`.

Thus far the only way I can think of doing this is to clip image with a rectangle with some custom logic added to handle use cases above. I was wondering if there is a better way?