fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser
http://fabricjs.com
Other
29.03k stars 3.51k forks source link

Padding of objects in group is reset #6989

Open dellvolk opened 3 years ago

dellvolk commented 3 years ago

Version

4.2.0

Test Case

https://jsfiddle.net/dellvolk/c8zas7th/12/

Expected Behavior

I need that when objects form group padding remained

Actual Behavior

Padding in objects is -10, but when they form group, the padding changes to 0

2021-04-02 15-34-23

asturur commented 3 years ago

Hi @dellvolk there are 2 issues here: 1) negative padding is not supported. Maybe we should state it clearly in the docs. 2) you are defining padding at object level, when an active obejct is created, that is a new object and the setting is not.

Try to add the padding value on the prototype if you want it everywhere.

Object.prototype.padding = -10.

dellvolk commented 3 years ago

Hi @asturur

I don't need to set a padding for the group. Only for elements in this group. That the stroke of the group remained as it is, and the black stroke of the elements of the group was like the padding of the elements themselves image

asturur commented 3 years ago

There is no padding for elements in the group. Is not calculated, considered at all.

dellvolk commented 3 years ago

How can this be solved?

asturur commented 3 years ago

It can't. You have to modify the internal functions to handle the objects control boxes. You can try of course but i can't support you.

dellvolk commented 3 years ago

Solution found:

The method that handles the border size calculation for objects in a group is drawBordersInGroup (see http://fabricjs.com/docs/fabric.Object.html#drawBordersInGroup).

The following should work as a drop-in replacement for this method in order to factor padding into the size calculation:

https://jsfiddle.net/melchiar/bw384o2n/


//drop in replacement for drawBordersInGroup method
fabric.Object.prototype.drawBordersInGroup = function(ctx, options, styleOverride) {
  styleOverride = styleOverride || {};
  var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options),
    strokeWidth = this.strokeWidth,
    strokeUniform = this.strokeUniform,
    //borderScaleFactor = this.borderScaleFactor,
    //adds object padding to border scale calculation
    borderScaleFactor = this.borderScaleFactor + this.padding * 2,
    width =
    bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,
    height =
    bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;
  ctx.save();
  this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);
  ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
  ctx.strokeRect(
    -width / 2,
    -height / 2,
    width,
    height
  );
  ctx.restore();
  return this;
};
asturur commented 3 years ago

how does it compare to the actual function. can you higlight the diff?

dellvolk commented 3 years ago

Any. But without explicitly prescribing this prototype, it does not work