模仿具有konva图像的对象适合/对象位置属性的最佳策略

问题描述 投票:0回答:1

假设我们在画布上绘制了一个1000x1000的图像,并将konva图像的大小设置为500x700之类。

是否有可能在konva中模仿html <img />标记object-fit属性,所以我们可以告诉图像对象在cover / contain模式下适合图像。同样,模仿object-position也很有用。

到目前为止,我能想到的唯一方法是用矩形裁剪图像,并添加一些自定义逻辑以处理上述用例。我想知道是否有更好的方法?

html5-canvas konvajs react-konva
1个回答
0
投票

[您使用cropXcropYcropWidthcropHeightKonva.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();

演示:https://jsbin.com/levomeyuvu/3/edit?js,output

© www.soinside.com 2019 - 2024. All rights reserved.