0

This is really easy in DOM because I can just do object-fit: cover in css and the image would crop and fill in the width and height. But in Konvajs the default seems to be to fill it.

Here is what I've tried:

  const [image] = useImage(content.img);

  if (image) {
    image.setAttribute('style', `object- 
    fit:cover;width:${content.width};height:${content.height}`);
  }

This doesn't work.

1 Answers1

1

Just in case anyone else is looking for a solution.

The only way I could achieve this is doing calculations on where to crop the original image.

const crop = () => {
  if (content.width > content.height) {
    const [cropX, cropY, cropW, cropH] = cropBasedOnWidth();
    if (cropY < 0) {
      const [cropX, cropY, cropW, cropH] = cropBasedOnHeight();
      return {x: cropX, y: cropY, height: cropH, width: cropW};
    }
    return {x: cropX, y: cropY, height: cropH, width: cropW};
  } else if (content.width < content.height) {
    const [cropX, cropY, cropW, cropH] = cropBasedOnHeight();

    if (cropX < 0) {
      const [cropX, cropY, cropW, cropH] = cropBasedOnWidth();
      return {x: cropX, y: cropY, height: cropH, width: cropW};
    }
      return {x: cropX, y: cropY, height: cropH, width: cropW};
    } else {
      return undefined;
    }
  }

const cropBasedOnWidth = () => {
 const cropW = content.naturalWidth;
 const cropH = cropW / content.width * content.height;
 const cropX = content.naturalWidth / 2 - cropW / 2;
 const cropY = content.naturalHeight / 2 - cropH / 2;
 return [cropX, cropY, cropW, cropH];
}

const cropBasedOnHeight = () => {
  const cropH = content.naturalHeight;
  const cropW = cropH / content.height * content.width;
  const cropX = content.naturalWidth / 2 - cropW / 2;
  const cropY = content.naturalHeight / 2 - cropH / 2;
  return [cropX, cropY, cropW, cropH];
}
...
return <Image crop={crop()} ... />

I don't know if there is a better way.