2016-01-17 4 views
0

Я пытаюсь нарисовать рамку вокруг объектов, имеющих тень. object.getBoundingRect() не учитывает тени. Обычные тени просты, но при размытии это сложнее.Ограничительная коробка Fabric.js с размытыми тенями

Есть ли способ получить оценки?

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

Вы должны проверить 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>

+0

Wow! Спасибо, это потрясающе. –

Смежные вопросы