[英]FabricJS prevent canvas.clipTo from clipping canvas.backgroundImage
I want to set a global clipTo
in my Fabric-powered Canvas that will affect all user-added layers. 我想在我的Fabric-Powered Canvas中设置一个全局clipTo
,它将影响所有用户添加的图层。 I want a background image and an overlay image, which are unaffected by this clip mask. 我想要一个背景图像和一个叠加图像,它不受此剪辑蒙版的影响。
Example: 例:
Here's what's happening in this photo: 这是这张照片中发生的事情:
canvas.clipTo
function was added, which clips the canvas to a rectangular shape 添加了canvas.clipTo
函数,该函数将canvas.clipTo
为矩形 I want the user-added image (the pug) to be limited to the rectangular area. 我希望用户添加的图像(哈巴狗)仅限于矩形区域。
I do not want the background image (the blue t-shirt shape) affected by the clip area. 我不希望剪辑区域影响背景图像(蓝色T恤形状)。
Is there a simple way to accomplish this? 有没有一种简单的方法来实现这一目标? I really don't want to have to add a clipTo
on every single user layer rather than one tidy global clipTo
. 我真的不想在每个用户层上添加一个clipTo
而不是一个整洁的全局clipTo
。
You can play with a JS fiddle showing the problem here . 你可以玩一个JS小提琴,在这里显示问题。
I came here with the same need and ultimately found a solution for what I'm working on. 我带着同样的需求来到这里,最终找到了我正在努力的解决方案。 Maybe it helps: 也许它有帮助:
For SVG paths, within the clipTo
function you can modify the ctx directly prior to calling render(ctx)
and these changes apply outside the clipped path o. 对于SVG路径,在clipTo
函数中,您可以在调用render(ctx)
之前直接修改render(ctx)
并且这些更改将应用于剪切路径o之外。 Like so: 像这样:
var clipPath = new fabric.Path("M 10 10 L 100 10 L 100 100 L 10 100", {
fill: 'rgba(0,0,0,0)',
});
var backgroundColor = "rgba(0,0,0, 0.2)";
var opts = {
controlsAboveOverlay: true,
backgroundColor: 'rgb(255,255,255)',
clipTo: function (ctx) {
if (typeof backgroundColor !== 'undefined') {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, 300, 150);
}
clipPath.render(ctx);
}
}
var canvas = new fabric.Canvas('c', opts);
canvas.add(new fabric.Rect({
width: 50,
height: 50,
left: 30,
top: 30,
fill: 'rgb(255,0,0)'
}));
You can of course add an image instead of a color, or whatever else you want done. 您当然可以添加图像而不是颜色,或者您想要的任何其他内容。 The trick I've found is to put it in the clipTo
function on the ctx
directly. 我发现的技巧是将它直接放在ctx
的clipTo
函数中。
One (sorta hacky) solution: set a CSS background image on your canvas element, as shown in https://jsfiddle.net/qpnvo3cL/ 一个(sorta hacky)解决方案:在canvas元素上设置CSS背景图像,如https://jsfiddle.net/qpnvo3cL/所示
<canvas id="c" width="500" height="500"></canvas>
<style>
background: url('http://fabricjs.com/assets/jail_cell_bars.png') no-repeat;
</style>
<script>
var canvas = window._canvas = new fabric.Canvas('c');
canvas.clipTo = function(ctx) {
ctx.rect(100,100,100,100);
}
</script>
Have you tried clipping a fabric Group ? 您是否尝试剪裁布料组 ? You could make the whole shirt one canvas. 你可以把整个衬衫做成帆布。 The center graphics would be one Group which you clip to where you want it. 中心图形将是一个组,您可以将其剪切到所需的位置。 The white t-shirt and the blue overlay would of course not be part of the clipped group. 白色T恤和蓝色叠加当然不是剪辑组的一部分。
Here's an example of clipping a group: 这是剪辑组的示例:
var rect = new fabric.Rect({width:100, height: 100, fill: 'red' });
var circle = new fabric.Circle({ radius: 100, fill: 'green' });
var group1 = new fabric.Group([ circle, rect ], { left: 100, top: 100 });
canvas.add(group1);
group1.clipTo = function(ctx) {
ctx.rect(50,50,200,200);
};
See this jsfiddle I made: https://jsfiddle.net/uvepfag5/4/ 看到我做的这个jsfiddle: https ://jsfiddle.net/uvepfag5/4/
I find clip rather slow so I tend to use globalCompositeOperation to do masking. 我发现剪辑相当慢,所以我倾向于使用globalCompositeOperation进行屏蔽。
If you really need to use clip then use it in conjunction with save and restore. 如果您确实需要使用剪辑,请将其与保存和恢复结合使用。
// ctx is canvas context 2d
// pug is the image to be clipped
// draw your background
ctx.save(); // save state
ctx.rect(100,100,100,100); // set the clip area
ctx.clip(); // apply the clip
ctx.drawImage(pug,x,y); // draw the clipped image
ctx.restore(); // remove the clipping
// draw the other layers.
or you can 或者你可以
// draw background
ctx.globalCompositeOperation = "xor"; // set up the mask
ctx.fillRect(100,100,100,100); // draw the mask, could be an image.
// Alpha will effect the amount of masking,
// not available with clip
ctx.globalCompositeOperation = "destination-over";
ctx.drawImage(pug,x,y); // draw the image that is masked
ctx.globalCompositeOperation = "source-over";
// draw the stuff that needs to be over everything.
The advantage of composite operations is you have control over the clipping at a per pixel level, including the amount of clipping via the pixel alpha value 复合操作的优点是您可以控制每像素级别的裁剪,包括通过像素alpha值裁剪的数量
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.