用 konva 图像模拟 <img> 对象拟合/对象位置属性的最佳策略

Posted

技术标签:

【中文标题】用 konva 图像模拟 <img> 对象拟合/对象位置属性的最佳策略【英文标题】:Best strategy to mimic <img> object-fit / object-position property with konva images 【发布时间】:2020-10-05 05:46:26 【问题描述】:

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

是否可以在 konva 中模仿 html &lt;img /&gt; 标签 object-fit 属性,以便我们可以告诉图像对象以适应 cover / contain 模式中的图像。同样,模仿object-position 也会很有用。

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

【问题讨论】:

【参考方案1】:

您可以使用 Konva.ImagecropXcropYcropWidthcropHeight 属性来模拟类似的 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.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();

演示:https://konvajs.org/docs/sandbox/Scale_Image_To_Fit.html

【讨论】:

以上是关于用 konva 图像模拟 <img> 对象拟合/对象位置属性的最佳策略的主要内容,如果未能解决你的问题,请参考以下文章

Konva stage.toDataUrl()是不是渲染我在画布中看到的图像?

在React Konva中使用globalCompositeOperation来屏蔽形状组

Cordova - 在 <img> 标签中显示本地图像文件

05 canvas——Konva简单使用

React Konva,blueimp-load-image 上传图像重新缩放

更改 Konva.js 中的图像渲染