Fabric.js: Objects not redrawn when calling canvas.getActiveGroup()

Created on 1 Feb 2018  路  13Comments  路  Source: fabricjs/fabric.js

In my use case I want to update all selected objects when a button is clicked. For this purpose I use canvas.getActiveObject() and canvas.getActiveGroup(). I noticed that updating the active object (got from canvas.getActiveObject()) and then calling canvas.getActiveGroup() causes the updated object not to be redrawn until the selection is cleared.

Version

2.0.0-rc.4

Test Case

http://jsfiddle.net/Da7SP/815/

Steps to reproduce

  1. Select the square.
  2. Click the button "Click me".

Expected Behavior

The square should change color.

Actual Behavior

The square's color is updated only when clicking anywhere in the canvas to clear the selection.
The problem is solved if deleting line 43.

Most helpful comment

I also add that setting dirty to true is not the solution that will solve everything.
The goal is minimize rendering execution and rendering when necessary.

All 13 comments

Hello @nickasd
Thanks for the fiddle.
Since fabric 2.0, activeGroup is removed.
Please follow this link to learn more:
http://fabricjs.com/v2-breaking-changes-2

Oh, now I see that in fact in my project I'm still using version 1.7.22 which seems to have a bug related to updating objects in a group. Fortunately it seems to have been fixed in 2.0.0-rc.4 and the issue I reported here is probably not related to it. Thanks!

There are no bugs ( i know of ) related to group in 1.7.22
Often is the updating logic that does not fit what fabricjs really needs.

Apart from naming rules, the group code is similar, so you will find probably the same bug.

Here is a fiddle showing the original bug I wanted to report for version 1.7.22: http://jsfiddle.net/Da7SP/816/

If you select one square and then click the button, its color is changed. If you select both squares and then click the button, they change color only when clicking on the canvas to deselect them.

You need to set dirty = true to group object. So object cache will render in next render call.
Here is updated fiddle.
And doc dirty.

Hmm ... this is a pity, because then statefullCache and cacheProperties are not really useful ... or are they?

Anyway, in version 2.0.0 this doesn't seem to happen anymore: http://jsfiddle.net/Da7SP/827/

So i think we fixed by chance in 2.0 ( i have to check )
What happens in 1.7 is that the default value of preserveObjectStacking is false.
So all the selected objects get rendererd as a group, in that case the statefull check is made just for the main object ( the selection ) and not the children.

If in your 1.7 fiddle you set in the canvas preserveObjectStacking to true, it works as expected.

( i would have kept the fiddle a little bit simpler using fill instead of myprop, but this is just a comment )

The statefull check is costly in my opinion and i always suggest people to use .set('myProp', value) if myProp is in the array of cacheProperties and is changed in value, it will trigger a re render in any situation.

The statefull cache is usefull and you are on an old application, you want the benefits of cache over complex designs but you do not want to rewrite much stuff.
In the long run learning to use the set and understanding the cache is the best way to use fabricjs for performances.

It all depends on the size of the project and how much time you have to dedicate to it.

I also add that setting dirty to true is not the solution that will solve everything.
The goal is minimize rendering execution and rendering when necessary.

The object caching documentation says:

cacheProperties Is an array of properties to be checked when statefullCache is on

so I was assuming that you have to enable both. From @asturur's comment I understand that cacheProperties works when used in conjunction with set(prop, value), is that right?

I wasn't aware of preserveObjectStacking, and probably it would be useful to mention it in the tutorial, but probably since this problem is resolved in version 2.0.0 it would be sufficient to add a link to the object caching guide.

no cache properties get checked at each render call, for each object.
Is a lazy alternative to setting manually the props you are changing.

They also get checked during set method, for a precise way to rise the dirty flag.

Before fabric 1.7 everyone was doing object.fill = value

I think also the resolve in the 2.0 has to been verified. the fiddle works, i still do not know why in 2.0 there is no this problem

Ok, if using set is sufficient then I will do it like this. That's why in the fiddle I used myProp instead of fill, because I knew that using setFill would work.

Probably the documentation should still be updated, since 't's mentioned twice that cacheProperties needs statefullCache to be enabled.

Right i should mention that set method inspect the the cahceProperties too.

Please try to use set(prop, value), since in newer versions, named setters have been made optional for security reasons ( use of eval and new function ) and are not part of the standard build.

My bad, I meant set('fill', value).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

urcoder picture urcoder  路  5Comments

keanass picture keanass  路  5Comments

bevacqua picture bevacqua  路  4Comments

AbhijitParate picture AbhijitParate  路  3Comments

zhangzhzh picture zhangzhzh  路  4Comments