Fabric.js边界框与模糊的阴影

时间:2016-01-17 06:29:42

标签: javascript fabricjs

我正在尝试在有阴影的对象周围绘制一个边界框。 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;
        }

1 个答案:

答案 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>