Unable to maintain thickness of strokeWidth while

2019-05-21 05:17发布

问题:

I am writing code to maintain same strokeWidth across all the objects in Fabricjs.

I am able to successfully maintain strokeWidth for normal Objects , let it be rectangle or ellipse(I wrote code to maintain both). But when I use group , I am unable to maintain the strokeWidth.

Here's the fiddle.

Steps to reproduce the issue ?
1)Open above fiddle link
2)resize the circle , check the size of border (thickness of border remains the same on re-sizing)
3)Now resize the rectangle and text(group) , expected result is thickness of border must be same throughout but that doesn't happens.

Code : `

var gCanvas = new fabric.Canvas('canvDraw');
gCanvas.setWidth(700);
gCanvas.setHeight(700);
var text = new fabric.Text('test', {  fontSize: 30, top: 100, left : 100, fill : 'red'});
// add some shapes - these are examples, others should work too
var myRectangle = new fabric.Rect({
left: 100,
top: 100,
fill: '#999999',
width: 120,
height: 120,
strokeWidth: 3,
fill: '',
stroke: '#000000'
});
var group = new fabric.Group([ myRectangle, text ], {borderColor: 'black', cornerColor: 'green', lockScalingFlip : true});
gCanvas.add(group);

var myEllipse = new fabric.Ellipse({
top: 250,
left: 100,
rx: 75,
ry: 50,
fill: '',
stroke: '#000000',
strokeWidth: 3
});
gCanvas.add(myEllipse);
gCanvas.observe('object:scaling', function (e) {
        e.target.resizeToScale();
    });


fabric.Object.prototype.resizeToScale = function () {
// resizes an object that has been scaled (e.g. by manipulating the handles), setting scale to 1 and recalculating bounding box where necessary
switch (this.type) {
    case "ellipse":
        this.rx *= this.scaleX;
        this.ry *= this.scaleY;
        this.width = this.rx * 2;
        this.height = this.ry * 2;
        this.scaleX = 1;
        this.scaleY = 1;
        break;

    case "rect":
        this.width *= this.scaleX;
        this.height *= this.scaleY;
        this.scaleX = 1;
        this.scaleY = 1;
    default:
        break;
}
}

`

回答1:

this approach will not work for all kind of shapes. when facing text or polygons you cannot recalculate everything.

you can do something like that:

fabric.Object.prototype.resizeToScale = function () {
  if  (this.type !=='group') {
    this.strokeWidth = this._origStrokeWidth / Math.max(this.scaleX, this.scaleY);
  }
  else {
    this._objects.forEach( function(obj){
      console.log(obj);
      obj.strokeWidth = obj._origStrokeWidth / Math.max(obj.group.scaleX, obj.group.scaleY);
    });
  }
}

if you prefer the effect of your solution (border is always uniform) put this line of code in the default case of your switch construct to handle all the types for wich you cannot find a resizing solution.

edit i added group handling. The point is to make smaller strokewidth when the group / object scale. Because when you will have polygons and polylines and paths, changing width / height /radius will not help.

http://jsfiddle.net/y344vs5s/4/