假设我们在画布上绘制了一个1000x1000的图像,并将konva图像的大小设置为500x700之类。
是否有可能在konva中模仿html <img />
标记object-fit
属性,所以我们可以告诉图像对象在cover
/ contain
模式下适合图像。同样,模仿object-position
也很有用。
到目前为止,我能想到的唯一方法是用矩形裁剪图像,并添加一些自定义逻辑以处理上述用例。我想知道是否有更好的方法?
[您使用cropX
的cropY
,cropWidth
,cropHeight
和Konva.Image
属性模拟类似的CSS行为。
您可以使用此功能进行计算:
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.width * 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();