sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.45k stars 4.11k forks source link

Component Unmount: Allow non-duration based outro animations #3847

Open christiankaindl opened 4 years ago

christiankaindl commented 4 years ago

I am struggling to use a spring-based animation for component outros (unmounting the DOM element). As far as I can tell, the only way to defer/delay the unmount/outro of a component is to use the transition or out directive and return an transition object with a specified duration:

{
  duration: 400,
  easing: ...
}

This works great for easing functions, but I cannot use Svelte's spring() function for the outro transition, because it has no fixed duration.


Proposal/Potential solution

My proposed solution is for the transition, in and out directives to accept a function that optionally returns a Promise instead of a Transition object. Once the Promise fulfills (or rejects), Svelte can remove the element from the DOM.

Example REPL for illustration: https://svelte.dev/repl/cc1467f851284051a11ca0325c2efd97?version=3.12.1

Alternative I have considered

One alternative I've considered, is pre-calculating a duration for the spring and using that as the duration value in the transition object. This approach has one disadvantage: springs are inherently dynamic, so the animation distance changes how long the spring takes to finish (its duration), which makes a static pre-calculation (i.e. one pre-calculated duration per spring-config) of the spring not possible.

It may be be possible to predict the duration relatively accurately based on the spring config (damping, stiffness, mass, ...) and the travel distance, but that is a considerable amount of work for something which Just Works™ when using normal easing transitions.

Additional context

Svelte puts a lot of focus into "making UI interactions and animations as easy as possible". For that matter, Svelte even provides its own Spring-based animation API. So it would make sense to allow to use Svelte's spring() function (or third-party ones) for outro transitions.

If this addition is feasible and wanted, it may also make sense to revisit some of the built in animation functions like fade and slide to make it possible to use them also with a spring.

How important is this feature to me? Right now, I am trying to evaluate to port an existing project to Svelte. This existing project has spring-based outro animations in a few places (pages, menus). It's not a dealbreaker, but seems like an unfortunate limitation.

In my opinion, spring interactions and animations are superior to fixed (duration based) easings and feel more intuitive.

Similar "defered unmount" discussion over at React: https://github.com/reactjs/rfcs/issues/128

Potential drawback: One drawback of the Promise based approach as I proposed it above is, that the author has to handle the animation themselves. I.e. I have to get a reference to the DOM element and do stuff with it, instead of letting Svelte handle it. But this may be necessary nontheless when the author wants to use a third-party library, such as Popmotion.

What about Intro transitions: In general, my proposal is also about intro animations. But it is not such a big of a problem, because you can roll your own intro animation logic within an onMount() handler. In the case of the outro animation, there is no real workaround that I am aware of, which is why I primarily focused on that.

swyxio commented 4 years ago

just saw @pushkine's PR - i think i like this and cant find any objections! wonderful idea.

russellsamora commented 4 years ago

@sw-yx @pushkine any reason PR #4272 was closed and not merged? Also seems related to #4056

swyxio commented 4 years ago

idk man i dont run things

pushkine commented 4 years ago

@russellgoldenberg it will come built in to #4742

pushkine commented 4 years ago

I initially planned to get this implemented at the same time as spring transitions, those did not make it into #4742 so it'll come in a follow-up to that pr

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

minht11 commented 1 year ago

Is this still being considered? I want to use MotionOne animation library, because of it's great DX of orchestrating animations, but unfortunately without non duration based animations it is very hard to do it, I found this to be a major friction point, compared to other parts of svelte.