Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Replace previous
Style
,ComputedStyle
,Animation
andAnimatedProp
with dynamically computed styles and animations using closures.First some API usage examples.
Examples
The API for static styles is just as before
but you can run any code, also using the previous style
Styles and style animations are implemented using the same closures, taking and modifying an
StyleAnimCtx
. The value holds thestyle
, a booleanblend_style
whether to blend with the previous style, and ananimation_value
, typically representing the animation progress from 0.0 to 1.0.This allows styles like this, with a fixed
animation_value
:But can also be used for state animations:
1_hover.mov
By using code we can also have more complicated logic, like keyframes:
keyframes.mov
I also implemented
.passes(count)
to run the following animationcount
times.alternating_anim()
to animate back to the initial style, after reaching ananimation_value
of 0.5..ease(mut self, mode: EasingMode, func: EasingFn)
to apply the previously implemented easing functions to theanimation_value
It is also possible to animate more (all) values of the style, like the
font_size
. Values which can not be interpolated, like theflex_direction
could also be changed in the middle of the animation.There is the trait
AnimDriver
, which producesanimation_value
s, and currently 2 implementors:FixedAnimDriver
for fixed animations, used for static styles.TimedAnimDriver
for animating between 0.0 and 1.0 based on whether it is enabled or not.Looping is also possible with the
TimedAnimDriver
:Notice the position of
.blend()
. Everything before is applied all the time, everything afterwards is animated.looping.mov
Motivation and implementation notes
Modern UIs use animations a lot. Ideally I would like floem to support the following:
transition
✅AnimDriver
and named theanimation_value
notanimation_progress
and forced it to be within[0.0, 1.0]
. This could be used right now to animate some other value like,download_speed
when implementingAnimDriver
StyleAnimGroupId
which can be used to set animations.custom_anim(id, driver, |s|...)
and then be enabled, disabled for all views. Maybe there should be additional triggers which wake up the animation, like when the scroll position changes. The animation driver could decide whether it starts animating.I think the previous the implementation made sense, coming from CSS/HTML. Define what should be done, and let the core do it. Because we are using rust, and not CSS, doing it directly is as simple, more flexible, and should be just as fast. This is similar to the way views are defined with code, and not markup.
Interaction with reactivity system
I am not sure how much the reactivity system can/should be used here. To me a pull based system makes sense, since animations should run once per frame, not once a value like
download_speed
is updated, but I think this could also be achieved in a different way. They should also be able to run without changes in a signal. Currently when using reactive values in animations and styles they are replaced when it changes, as the calls are wrapped increate_effect
.Reviewing guide
Best start with checking the following files for the most important changes:
Style
andStyleAnimCtx
definition.StyleAnimFn
andAnimDriver
traits.TimedAnimDriver
.compute_style
in context.rsUnrelated changes
BoxShadow
toShadow
, as it is shorter and just as clearShadows
, this also changes the(box)_shadow_x
APIvger
theblur_radius
has no effect.StyleSelector
for the base, main, and override style. This felt easier, and extends nicely to custom animations.Hope you like this, no worries if not, I can also work on this for my own projects. Feel free to change what you like, or tell me what should be different. There is not much wich could be done in a separate PR, as this all works together.