使用Fabricjs在形状内绘制图像

7
我目前正在使用canvas和Javascript进行图像处理,使用的工具是fabric.js。我希望用户能上传一张图片并与我们提供的模板合并,即:

the Template

我只想在中心的空白圆圈中显示已上传的图片,并允许用户通过拖动来调整图片。

  • 如果我将模板设为上层,则用户无法拖动和调整,因为画布已被填满。
  • 如果我将上传的图片设为上层,则该图片会溢出圆圈。

如何通过简单易用的界面解决这个问题? 我尝试过在fabric.js中使用ClipTo函数,但它不适用于图像对象。

3个回答

5

我认为覆盖图像是你想要的。

例如,可以查看自定义演示:

Example of overlayImage

var canvas = new fabric.Canvas('c13');
var circle = new fabric.Circle({ 
  radius: 30, 
  fill: '#f55', 
  top: 100, 
  left: 100 
});
canvas.add(circle);
canvas.setOverlayImage('../assets/jail_cell_bars.png', 
  canvas.renderAll.bind(canvas));

谢谢。但是我可以在覆盖图像上放置一个文本对象吗? - RSK
不一定。overlayImage 的作用是覆盖在所有其他内容之上。它只是一个在渲染循环的最后发生的简单的 drawImage 调用。但是,如果这个图像中间是透明的,你真的需要它放在最上面吗?那么在这个圆形区域内的任何内容都会被它剪裁掉。 - kangax
但是我的应用程序确实需要3个图层。1)用户上传的图像仅通过模板的透明区域显示(参考问题中的图像)。2)模板类似于问题中的图像。3)模板上方的文本。我能否在fabricjs的上层画布上绘制某些内容,而不会干扰覆盖图像? - RSK
是的,这可能有点复杂。在设计面料时,我没有考虑到这种用例。您可以使用“after:render”回调,在canvas.contextContainer上手动绘制一些内容(例如使用本地的strokeText方法)。但是很难将面料对象呈现在顶部。也许可以通过创建文本对象的某种黑客方式,然后在“contextContainer”的上下文中调用其“_render”方法——textObj._render(canvas.contextContainer)(在“after:render”回调中),或类似的方法。 - kangax

1

你可以把照片和模板都绘制到画布上。我不确定fabric.js是否支持,但如果直接调用画布函数,你只需要...

ctx = canvas.getContext('2d');
ctx.DrawImage(user_img, x,y);
ctx.DragImage(template_imb, 0, 0);

当用户拖动鼠标时,更新x和y并重新绘制两个图层。显然要确保模板中的孔是透明的。如果您希望用户能够调整图像大小,可以在DrawImage调用中添加宽度和高度,只需提供某种控件来更改它们即可。

0

更困难的方法是创建一个临时(离屏)画布。使用 globalCompositeOperation=source-in,将图像绘制在遮罩图像上,然后从那里获取 getImageData 并将其 putImageData 到目标画布上。

但如果 Charles' answer 对您有用,那么它会更加简单明了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接