2

About the issue

I'm working on a graphics editor built with konva.js
After hours of research, I cannot get the transformer to adjust to the clipped size of a group

Details

I have a group that defines a simple clip area, and within this there are 2 rectangles of the exact same size and position, stacked on top of each other.

The clipped group works well; however, this application is dynamic, so, it takes input from the user to set a clip area. When I call group.clip() and layer.batchDraw() it does the clipping, but the bounding rectangle (transformer) does not update, even after I call transformer.forceUpdate() on it, no luck.

What I've tried

When I destroy the transformer and re-create it, it still indicates the full-size (not the clipped size) and the clipped-off region still remains.

Here's a screen-shot for clarity: Screenshot-20191008-153503.png

Some code

I doubt if this would even help, the code is in separate files and the values come from user-input as mentioned. For what it's worth, this is for you:

let grp = new Konva.Group({x:o.x,y:o.y,draggable:o.draggable,clip:{x:0,y:0,width:o.width,height:o.height}});

Any other code I paste here will just confuse the hect out of us all, it's A LOT, and I know people run when they see that, so, if I should add more code, please let me know in the comments?

I will appreciate any help, thanks.

mika
  • 49
  • 8

2 Answers2

2

While lavtron's answer could work, a more direct approach solves the issue:

Bug Patch

(function()
{
    let func = Konva.Group.prototype.getClientRect;
    let orig = {enumerable:false, configurable:false, writable:false, value:func};
    let altr = {enumerable:false, configurable:false, writable:false, value:function(t)
    {
        let attr = this.attrs;
        let resl = this.getOrigClientRect(t);
        if(attr.hasOwnProperty('clipWidth')){resl.width=attr.clipWidth};
        if(attr.hasOwnProperty('clipHeight')){resl.height=attr.clipHeight};
        return resl;
    }};
    Object.defineProperty(Konva.Group.prototype,'getOrigClientRect', orig);
    Object.defineProperty(Konva.Group.prototype,'getClientRect', altr);
})();


How to implement

To implement this patch:

  • either add this in your own JavaScript - after the konva.js script loaded in the DOM,
  • or paste this directly into the konva.js source

If you're using RequireJS to load KonvaJS, you should name your imported object accordingly and/or update the code above, -OR- just keep it as Konva (note the uppercase K).

Technical details

This works by using the original getClientRect method's result and updating it with the clipWidth and clipHeight of the clipped-group - only if it has these attributes; else it returns the result unmodified.

This is tested and works well; however, it would be better if the the distribution source code of the konva.js repository could be updated accordingly.

argon
  • 449
  • 4
  • 11
1

Unfortunately, for the current moment with konva@4.0.13, Konva.Transformer doesn't support clipping. It just doesn't know about it so you see it in the "old" place.

The tricky workaround is:

  1. Create a transparent rectangle with the size of the clipped area
  2. Attach Konva.Transformer into that rectangle.
  3. On transform or transformend events resize group or its children manually.
lavrton
  • 18,973
  • 4
  • 30
  • 63