我正在尝试在有阴影的对象周围绘制一个边界框。 object.getBoundingRect()不考虑阴影。常规阴影很简单,但添加模糊时更难。
有没有办法获得界限?
https://jsfiddle.net/e77c0owf/
function getObjBounds(obj) {
var bounds = obj.getBoundingRect();
var shadow = obj.getShadow();
if (shadow !== null) {
var blur = shadow.blur;
var signX = shadow.offsetX >= 0.0 ? 1.0 : -1.0;
var signY = shadow.offsetY >= 0.0 ? 1.0 : -1.0;
var offsetX = (shadow.offsetX + (signX * blur)) * Math.abs(obj.scaleX);
var offsetY = (shadow.offsetY + (signY * blur)) * Math.abs(obj.scaleY);
if (offsetX > 0) {
bounds.width += offsetX;
} else if (offsetX < 0) {
bounds.width += Math.abs(offsetX);
bounds.left -= Math.abs(offsetX);
}
if (offsetY > 0) {
bounds.height += offsetY;
} else if (offsetY < 0) {
bounds.height += Math.abs(offsetY);
bounds.top -= Math.abs(offsetY);
}
}
return bounds;
}
答案 0 :(得分:1)
你必须检查fabricjs计算是否有模糊和缩放,另外你必须考虑阴影偏移小于模糊值的情况。
function getObjBounds(obj) {
var bounds = obj.getBoundingRect();
var shadow = obj.getShadow();
if (shadow !== null) {
var blur = shadow.blur;
var mBlur = blur * Math.abs(obj.scaleX + obj.scaleY) / 4
var signX = shadow.offsetX >= 0.0 ? 1.0 : -1.0;
var signY = shadow.offsetY >= 0.0 ? 1.0 : -1.0;
var mOffsetX = shadow.offsetX * Math.abs(obj.scaleX);
var mOffsetY = shadow.offsetY * Math.abs(obj.scaleY);
var offsetX = mOffsetX + (signX * mBlur);
var offsetY = mOffsetY + (signY * mBlur);
if (mOffsetX > mBlur) {
bounds.width += offsetX;
} else if (mOffsetX < -mBlur) {
bounds.width -= offsetX;
bounds.left += offsetX;;
} else {
bounds.width += mBlur * 2;
bounds.left -= mBlur - mOffsetX;
}
if (mOffsetY > mBlur) {
bounds.height += offsetY;
} else if (mOffsetY < -mBlur) {
bounds.height -= offsetY;
bounds.top += offsetY;
} else {
bounds.height += mBlur * 2;
bounds.top -= mBlur - mOffsetY;
}
}
return bounds;
}
产生的小提琴: https://jsfiddle.net/e77c0owf/1/
// ************************************
// Bounding box calculation logic
// ************************************
function getObjBounds(obj) {
var bounds = obj.getBoundingRect();
var shadow = obj.getShadow();
if (shadow !== null) {
var blur = shadow.blur;
var mBlur = blur * Math.abs(obj.scaleX + obj.scaleY) / 4
var signX = shadow.offsetX >= 0.0 ? 1.0 : -1.0;
var signY = shadow.offsetY >= 0.0 ? 1.0 : -1.0;
var mOffsetX = shadow.offsetX * Math.abs(obj.scaleX);
var mOffsetY = shadow.offsetY * Math.abs(obj.scaleY);
var offsetX = mOffsetX + (signX * mBlur);
var offsetY = mOffsetY + (signY * mBlur);
if (mOffsetX > mBlur) {
bounds.width += offsetX;
} else if (mOffsetX < -mBlur) {
bounds.width -= offsetX;
bounds.left += offsetX;;
} else {
bounds.width += mBlur * 2;
bounds.left -= mBlur - mOffsetX;
}
if (mOffsetY > mBlur) {
bounds.height += offsetY;
} else if (mOffsetY < -mBlur) {
bounds.height -= offsetY;
bounds.top += offsetY;
} else {
bounds.height += mBlur * 2;
bounds.top -= mBlur - mOffsetY;
}
}
return bounds;
}
// ************************************
// Draw a ton of test cases below here
// ************************************
// Create a canvas
var canvas = new fabric.Canvas('c', {
backgroundColor: '#FFFFFF'
});
canvas.add(new fabric.Rect({
fill: 'red',
left: 100,
top: 100,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 0,
offsetX: -20,
offsetY: -10
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 30,
top: 20,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 0,
offsetX: -20,
offsetY: 0
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 30,
top: 250,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 0,
offsetX: 60,
offsetY: -60
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 180,
top: 20,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 10,
offsetX: 20,
offsetY: 20
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 180,
top: 150,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 20,
offsetX: 0,
offsetY: 0
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 220,
top: 280,
width: 50,
height: 50,
shadow: {
color: 'black',
blur: 20,
offsetX: -10,
offsetY: -10
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 280,
top: 20,
width: 50,
height: 50,
scaleX: 2.3,
scaleY: 2.3,
shadow: {
color: 'black',
blur: 10,
offsetX: 20,
offsetY: 20
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 360,
top: 230,
width: 50,
height: 50,
scaleX: 0.5,
scaleY: 0.5,
shadow: {
color: 'black',
blur: 20,
offsetX: 0,
offsetY: 0
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 380,
top: 290,
width: 50,
height: 50,
scaleX: 2.0,
scaleY: 2.0,
shadow: {
color: 'black',
blur: 10,
offsetX: 0,
offsetY: 0
}
}));
canvas.add(new fabric.Rect({
fill: 'red',
left: 140,
top: 380,
width: 50,
height: 50,
scaleX: -4.0,
scaleY: 0.5,
shadow: {
color: 'black',
blur: 20,
offsetX: -10,
offsetY: -10
}
}));
// Draw bounding boxes
var objs = canvas.getObjects();
var boxes = [];
for (var i = 0; i < objs.length; i++) {
var box = getObjBounds(objs[i]);
boxes.push(new fabric.Rect({
fill: '',
stroke: 'blue',
strokeWidth: 1,
left: box.left,
top: box.top,
width: box.width,
height: box.height
}));
}
for (var j = 0; j < boxes.length; j++) {
canvas.add(boxes[j]);
}
canvas.renderAll();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.js"></script>
<canvas id="c" width="550" height="450"></canvas>