如何限制透明矩形区域内的对象-FabricJS



我正在使用FabricJS实现设计器功能。我的想法是使用织物中的setBackgroundImage设置背景图像,我还添加了透明矩形的特定区域,并从JCrop中获取大小和位置。现在我的问题是,我想限制对象在透明矩形的特定区域内的放置。比方说,我想添加应该在那个有限区域内的文本/图像/形状,我可以实现背景图像、透明矩形的位置,甚至圆形对象,但我找不到限制对象的细节,只能将其放置在透明矩形内。

这是我下面的代码和工作的fiddle,如果你在fiddle图像中看到它,你需要选择裁剪部分,并且在画布背景下有透明的矩形,这是一个相同的裁剪选择。现在我想限制对象放置在透明矩形中的任何位置,现在我可以将对象放置在画布中的任何地方。

HTML

<img src="https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80" id="target">
<div class="canvas-container" style="position: relative; user-select: none;">
<canvas id="c1" width="600" height="600" style="border:1px solid #ccc; position: absolute;  left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>

JS

function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return {
width: srcWidth * ratio,
height: srcHeight * ratio,
aspectratio: ratio
};
}
jQuery(function($) {
//alert("Testing");
var img = new Image();
img.onload = function() {
var data = calculateAspectRatioFit(this.width, this.height, '400', '600');
console.log(data);
jQuery('#target').attr('width', data.width);
jQuery('#target').attr('height', data.height);
jQuery('#pdr-drawing-area').html("Aspect Ratio: " + data.aspectratio);
const stage = Jcrop.attach('target');
stage.listen('crop.change', function(widget, e) {
const pos = widget.pos;
console.log(pos.x, pos.y, pos.w, pos.h);
//fabric js
var canvas = new fabric.Canvas('c1');
var center = canvas.getCenter();
var img = 'https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80';
canvas.setBackgroundImage(img, function() {
canvas.backgroundImage && canvas.backgroundImage.scaleToWidth(data.width);
canvas.backgroundImage && canvas.backgroundImage.scaleToHeight(data.height);
//canvas.sendToBack(img);
canvas.renderAll();
});
console.log(pos.x * data.aspectratio);
var rect = new fabric.Rect({
left: pos.x,
top: pos.y,
fill: 'transparent',
width: (pos.w),
height: (pos.h),
strokeDashArray: [5, 5],
stroke: "black",
selectable: false,
evented: false,
//visible: false
});

canvas.add(new fabric.Circle({
radius: 30,
fill: '#f55',
top: pos.y + 2,
left: pos.x + 2
}));
canvas.add(rect);
canvas.setHeight(data.height);
canvas.setWidth(data.width);
canvas.renderAll();
});
},
img.src = 'https://images.unsplash.com/photo-1595438337199-d50ba5072c7e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=330&q=80';
});

以下是如何在FabricJS中限制移动的示例
我正在使用画布的有状态属性,请参阅下面的function objectMoving

var canvas = new fabric.Canvas("canvas");
canvas.stateful = true;
function inside(p, vs) {
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i].x, yi = vs[i].y;
var xj = vs[j].x, yj = vs[j].y;
var intersect = yi > p.y !== yj > p.y && p.x < ((xj - xi) * (p.y - yi)) / (yj - yi) + xi;
if (intersect) inside = !inside;
}
return inside;
}
function getCoords(rect) {
var coords = []
coords.push(rect.aCoords.tl);
coords.push(rect.aCoords.tr);
coords.push(rect.aCoords.br);
coords.push(rect.aCoords.bl);
coords.push(rect.aCoords.tl);
return coords;
}
function objectMoving(e) {
var cCoords = getCoords(parent);
var inBounds = inside({ x: e.target.left + 30, y: e.target.top + 30 }, cCoords);
if (inBounds) {
e.target.setCoords();
e.target.saveState();
} else {
e.target.left = e.target._stateProperties.left;
e.target.top = e.target._stateProperties.top;
}
}
var boundary = new fabric.Rect({
width: 310, height: 170,
left: 5, top: 5,
selectable: false,
strokeDashArray: [5, 2],
stroke: "blue",
fill: "transparent"
});
var parent = new fabric.Rect({
width: 250, height: 110,
left: 35, top: 35,
selectable: false,
strokeDashArray: [2, 5],
stroke: "black",
fill: "transparent"
});
var child = new fabric.Circle({
radius: 30,
fill: "rgba(255,0,0,0.8)",
top: 50, left: 50,
hasControls: false,
});
canvas.add(boundary);
canvas.add(parent);
canvas.add(child);
canvas.on("object:moving", objectMoving);
<canvas id="canvas" width="400" height="180"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.2/fabric.min.js"></script>

function inside中,我使用的是光线投射算法,您可以在此处阅读更多信息:https://github.com/substack/point-in-polygon/blob/master/index.js
我更喜欢这种算法,因为它为以后允许更复杂的形状作为父边界打开了大门,它可以处理任何形状的多边形。

如果您需要对该代码进行任何澄清,请告诉我。


现在您确实需要将其集成到您的项目中,并在";JCrop";选择

最新更新