Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(animation): animations registry #7528

Merged
merged 31 commits into from
Jan 22, 2022
Merged

Conversation

ShaMan123
Copy link
Contributor

@ShaMan123 ShaMan123 commented Dec 1, 2021

Motivation

  1. There's a need to cleanup animations in applications.
    Currently the dev needs to implement something by themselves.
    For example in react while developing when react does a hot reload or whatever and fabric is animating an error raises because the canvas is trying to access the context which react just disposed.
  2. Another use case I can think of is with erasing. It makes sense to iterate over all animations before erasing starts to make the objects non erasable. (I wanted this to be default behavior but lacked the mechanism to do so)
    In general, knowing what is animating is crucial information for good UX/UI.

I think this should be handled by fabric.

gist

Exposed fabric.runningAnimations (is this a good name? is fabric the right level to hold this ref?
It is an array containing the options object passed to animate and the cancel function. This means that it can contain additional context if such is passed to animate allowing the dev freedom.
Exposed the following methods: cancelAll, finders
For example we could pass the object/canvas as context, this will make it very simple to cancel relevant animations.

IMO It makes sense that an object holds a ref to all it's running animations and that it's dispose method should cancel them.
What do you think?

@ShaMan123 ShaMan123 changed the title feat(animation): running animations registry feat(animation): animations registry Dec 2, 2021
src/util/animate.js Outdated Show resolved Hide resolved
src/util/animate.js Outdated Show resolved Hide resolved
src/util/animate.js Outdated Show resolved Hide resolved
@ShaMan123
Copy link
Contributor Author

ready

call `removeFromRegistry();` after logic to fit all calls
@ShaMan123
Copy link
Contributor Author

ShaMan123 commented Dec 5, 2021

is this a good name? is fabric the right level to hold this ref?

@asturur regarding fabric.runningAnimations

@ShaMan123
Copy link
Contributor Author

I have added current state to animation context so now it enables even more freedom of use

@stale stale bot added the stale Issue marked as stale by the stale bot label Dec 21, 2021
@ShaMan123
Copy link
Contributor Author

I remembered you mentioned there's a need to cleanup runningAnimations from object/canvas dispose.
So I'll commit that.

@ShaMan123
Copy link
Contributor Author

ShaMan123 commented Jan 19, 2022

  1. Once an animation ends it is removed from the registry
  2. added a target property to animation context
  3. all object animations get registered with target set (if called from object.animate)
  4. object dispose cancels the target's animations
  5. canvas dispose cancels all animations (should this be on Canvas or StaticCanvas?)

No memory leaks should exist

if (cancel) {
return;
}
if (abort(current, valuePerc, timePerc)) {
// remove this in 4.0
// remove this in 5.0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about this??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good to remove because then the option to pause an animation comes to play.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShaMan123
Copy link
Contributor Author

ShaMan123 commented Jan 19, 2022

There's something important!
When using object.animate you can't access the value returned by fabric.util.animate because the function is chainable.
Should we break? I think so. Because it is awkward trying to access the animation context without it. And it may lead to not using object.animate which is a good method or damage the purpose of the PR (making it simple to handle animations after they start).

There are a few more places such as this

865be3c, made it a single commit to easily revert

@@ -1200,6 +1200,7 @@
*/
dispose: function () {
var wrapper = this.wrapperEl;
fabric.runningAnimations.cancelAll();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be executed per canvas.
EIther you pass in the canvas as argument and cancelAll becomes a cancelAll by canvas, or in an application with 2 canvases this would stop everything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.
When an objects animates does it have to be attached to a canvas? I guess not. So I'm not sure how to do what you suggest.
I can add a canvas property to the animation context object but what if there's no canvas set to the object??
Or maybe we should iterate over all running animations and check at that moment who is attached to the canvas arg and cancel that?

@@ -13,8 +13,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
* @param {Function} [callbacks.onComplete] Invoked on completion
* @param {Function} [callbacks.onChange] Invoked on every step of animation
* @return {fabric.Canvas} thisArg
* @chainable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe i m wrong, but is chainability still cool to do?
I understand it saves typing and as a result bits in the final bundle.
But i find having half methods chainable and half not is weird. Maybe is something we should drop in the rewrite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Chaining is not worth the weirdness.
I say we drop it.

Copy link
Contributor Author

@ShaMan123 ShaMan123 Jan 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it is less breaking to have void return values that change (for future impl)

*/
_centerObject: function(object, center) {
object.setPositionByOrigin(center, 'center', 'center');
object.setCoords();
this.renderOnAddRemove && this.requestRenderAll();
return this;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would like to limit breaking changes in 5. Those are not part of the animation changes. What is the reason to remove chainability now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's as you said. I thought it's too weird to have the animated version not chainable while the regular one is.

@asturur
Copy link
Member

asturur commented Jan 22, 2022

i m going to merge this and open a following PR to restore some extra changes that are for now not needed and complicate the release note of 5.0

@ShaMan123
Copy link
Contributor Author

ShaMan123 commented Jan 22, 2022

BTW should I push a small commit for the delay option (#1719 ) or leave it for another PR?

@ShaMan123
Copy link
Contributor Author

ShaMan123 commented Jan 22, 2022

i m going to merge this and open a following PR to restore some extra changes that are for now not needed and complicate the release note of 5.0

If you think it's better to release v5 without this that's alright. We'll make it part of v6.

@asturur
Copy link
Member

asturur commented Jan 22, 2022

i m fine adding this now, i just don't want to remove the chaining operators that do not return animations.
I have seen the commit for the delay, i wonder what are we doing with the start option then? isn't the start a delay itself?

@asturur asturur merged commit 8a3d9b1 into fabricjs:master Jan 22, 2022
@ShaMan123
Copy link
Contributor Author

I don't see a start option. Or anything resembling a delay option

@asturur asturur mentioned this pull request Jan 26, 2022
rockerBOO pushed a commit to rockerBOO/fabric.js that referenced this pull request Jan 28, 2022
rockerBOO pushed a commit to rockerBOO/fabric.js that referenced this pull request May 2, 2022
@ShaMan123 ShaMan123 deleted the animation-store branch September 11, 2022 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants