fabricjs / fabric.js

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

Aligning with Web Core API #8224

Open ShaMan123 opened 2 years ago

ShaMan123 commented 2 years ago

Aligning with Web Core API

migrate Observable to EventTarget?

The last PRs have made Observable much more friendly. Returning a disposer is my favorite, cuts down a lot of boilerplate code. Maybe we want to take it a bit further? EventTarget is implemented in all browsers and in node>15. Should we make Observable a subclass of EventTarget?

There is of course the amazing EventEmitter of node.

DOMMatrix

An amazing interface that is able to do so many useful things and is a drop replacement for the simple array used currently preTransform and postTransform are 2 concepts that are so important. We can subclass it and add qrDecompose applyToObject etc. making it a powerful key player. It is available on in node via polyfill or via node-canvas I am really enthusiastic about it.

ShaMan123 commented 2 years ago

EventTarget relies on Event so I don't think it is suitable. However, having a preventDefault option on fabric events is a desired feature. We should look into that. It could replace all lockXXX props and do much more.

ShaMan123 commented 2 years ago

EventTarget relies on Event so I don't think it is suitable.

I now think it is suitable. Node has a custom event class. We can consider migrating to use Event, preventDefault is a MAJOR benefit. We can use it in events with the before prefix and check if the event was prevented.

The only real blocker is that the spec doesn't expose a way to get all listeners but browsers have implemented getEventListeners(evTarget) so we can use that if it's fully compatible.

ShaMan123 commented 2 years ago

Rethinking... What if we call preventDefault on the native event? and test that? Is there anything that shouldn't be prevented?


EDITED We can't there is blocking stuff

DaxGama commented 6 months ago

@ShaMan123 what do think will be performance impact of using DOMMatrix?

ShaMan123 commented 6 months ago

Great question I didn't consider this at all Colleagues (@jiayihu ) have been reporting that each frame in apps with extensive usage of controls and objects call too much GC. @jiayihu pointed out the matrix multiplication, creating a lot of arrays. With DOMMatrix we could use multiplySelf, that might reduce more than half of the space complexity. Any thoughts?

jiayihu commented 6 months ago

Yes it could work. It should not take much time to give it a try for a few methods like composeMatrix and multiplyTransformMatrices. I wonder also if DOMMatrix operations are ran quicker in the GPU or in general quicker than doing them in JS, because it would be the underlying browser C implementation that does them.

asturur commented 6 months ago

I m sceptical they can use less memory for memory multiplication. I m also sceptical in tackling something like GC reductions by trying to swap a function with an array with a class and moving from returning a new matrix to reusing another ( that internally has to create a new array anyway ) hoping that the internal browser code memory handling doesn't effect the GC.

Of course you do what you want with your free time, but if you had an actual reproducible case of a crowded fabricJS situtation that can trigger GC often to the point that it bothers performances, that would be very useful because then we could tackle that specific problem

When i think of GCs issues i more more scared of the work we do with the Point class rather than the array creation in the matrix multiplication.

jiayihu commented 6 months ago

I m also sceptical in tackling something like GC reductions by trying to swap a function with an array with a class and moving from returning a new matrix to reusing another ( that internally has to create a new array anyway ) hoping that the internal browser code memory handling doesn't effect the GC.

The difference it seems is that you'd mutate and return the same object reference, instead of creating and multiplying multiple arrays on-the-fly as composeMatrix does. Also a JS-level array is un unbounded vector, a C-level matrix can just be a fixed-size array.

With that being said, I think you're right as I don't expect much difference with DOMMatrix. From the examples I've seen, it doesn't seem to be designed for high-speed canvas use, rather convenient simple CSS transforms. However what we could do is to create our own Matrix class to benefit from instance mutations instead of on-the-fly arrays. You'd need to keep only one fixed array at time and mutate the values. Pixi seems to be doing that: https://api.pixijs.io/@pixi/math/PIXI/Matrix.html