Transition animations for UI elements
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
Most animations in games are based on a timeline with keyframes: that is, you have some parameter which is being animated over a curve. Your options are to start, stop, or reverse the animation, but the control points are usually fixed.
However, a different kind of animation - one often seen in CSS - is an interpolation to a target value, often modulated by some mathematical easing function. (There are also physics-based animations, like mechanical spring simulations). These animations don't have a fixed timeline of keyframes, and in fact the target value can be changed in mid-animation.
These kinds of animations are very useful in UI work for things like popup menus, dialogs, sliding drawers, basically anything that has an "enter" and "exit" transition. "Interpolate to target" animations have an advantage over keyframe-based approaches because the animation is frequently interrupted: the popup menu may be closed before it has finished opening. It also works well for elements that have more than two states, such as a sidebar which might have "hidden", "collapsed" and "expanded" states. The problem with the keyframe approach is that restarting the animation track in mid-animation will cause an unsightly "pop".
A related requirement is that we need some way to poll when the animation is complete. Take for example a dialog or inventory screen: we don't want to keep around the entity hierarchy for the popup when it's not visible. But when the popup closes, we can't despawn the entities right away; we need to wait until the closing animation is complete. Typically this would be done by some conditional expression such as "if open || animation.running" where "running" means that the animation has not reached some quiescent state.
For UI work, it would be ideal to be able to do this by inserting a component into the Node entity, such that this component would continually modify the style and transform properties of the node.
(In my case, I would want to be able to rely on Bevy component change detection for the polling: in other words, I would like to be able to monitor the progress of the animation by looking for changed components. This would let me easily integrate it with my reactive framework.)
The kinds of properties we most frequently want to animate are:
* scale
* translation
* rotation
* color (background, border, outline or text)
* alpha
## What solution would you like?
I have prototyped a framework for this in bevy_reactor, however this was done over a year ago, and there have been a lot of developments in Bevy since then, and my code doesn't take advantage of any of those improvements. What I would like to see is a solution which integrates all of the various animation ideas that people have had in the last year.
Part of the motivation for this ticket is to start a discussion on what the API might look like.
## What alternative(s) have you considered?
I already have a working solution but it's less than ideal.
Contributor guide
Research direction
Start by reviewing the issue's requirements and the existing bevy_reactor prototype mentioned in the discussion. Survey the animation approaches developed in Bevy and determine an API for interruptible target interpolation, completion polling, and UI style or transform properties. Done means the design is agreed and an implementation scope is identified; no files or tests are named.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- design, game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100