mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Implement animationiteration event
This event is triggered when an animation iterates. This change also moves iteration out of style calculation to an "update animations" which is the next part of having animation event handling match the HTML spec.
This commit is contained in:
parent
f02aba1ed2
commit
873cdd1336
12 changed files with 93 additions and 80 deletions
|
@ -156,12 +156,10 @@ pub enum AnimationState {
|
|||
/// have to keep track the current iteration and the max iteration count.
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub enum KeyframesIterationState {
|
||||
/// Infinite iterations, so no need to track a state.
|
||||
Infinite,
|
||||
/// Infinite iterations with the current iteration count.
|
||||
Infinite(f64),
|
||||
/// Current and max iterations.
|
||||
/// TODO: Everything else in this file uses f64, so perhaps this should
|
||||
/// be as well.
|
||||
Finite(f32, f32),
|
||||
Finite(f64, f64),
|
||||
}
|
||||
|
||||
/// A CSS Animation
|
||||
|
@ -227,26 +225,26 @@ impl Animation {
|
|||
|
||||
/// Given the current time, advances this animation to the next iteration,
|
||||
/// updates times, and then toggles the direction if appropriate. Otherwise
|
||||
/// does nothing.
|
||||
pub fn iterate_if_necessary(&mut self, time: f64) {
|
||||
/// does nothing. Returns true if this animation has iterated.
|
||||
pub fn iterate_if_necessary(&mut self, time: f64) -> bool {
|
||||
if !self.iteration_over(time) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only iterate animations that are currently running.
|
||||
if self.state != AnimationState::Running {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if let KeyframesIterationState::Finite(ref mut current, max) = self.iteration_state {
|
||||
// If we are already on the final iteration, just exit now.
|
||||
// NB: This prevent us from updating the direction, which might be
|
||||
// needed for the correct handling of animation-fill-mode.
|
||||
if (max - *current) <= 1.0 {
|
||||
return;
|
||||
// If we are already on the final iteration, just exit now. This prevents
|
||||
// us from updating the direction, which might be needed for the correct
|
||||
// handling of animation-fill-mode and also firing animationiteration events
|
||||
// at the end of animations.
|
||||
*current = (*current + 1.).min(max);
|
||||
if *current == max {
|
||||
return false;
|
||||
}
|
||||
|
||||
*current += 1.0;
|
||||
}
|
||||
|
||||
// Update the next iteration direction if applicable.
|
||||
|
@ -262,6 +260,8 @@ impl Animation {
|
|||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn iteration_over(&self, time: f64) -> bool {
|
||||
|
@ -285,8 +285,8 @@ impl Animation {
|
|||
// If we have a limited number of iterations and we cannot advance to another
|
||||
// iteration, then we have ended.
|
||||
return match self.iteration_state {
|
||||
KeyframesIterationState::Finite(current, max) if (max - current) <= 1.0 => true,
|
||||
KeyframesIterationState::Finite(..) | KeyframesIterationState::Infinite => false,
|
||||
KeyframesIterationState::Finite(current, max) => max == current,
|
||||
KeyframesIterationState::Infinite(..) => false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -347,13 +347,11 @@ impl Animation {
|
|||
}
|
||||
|
||||
/// Calculate the active-duration of this animation according to
|
||||
/// https://drafts.csswg.org/css-animations/#active-duration. active-duration
|
||||
/// is not really meaningful for infinite animations so we just return 0
|
||||
/// here in that case.
|
||||
/// https://drafts.csswg.org/css-animations/#active-duration.
|
||||
pub fn active_duration(&self) -> f64 {
|
||||
match self.iteration_state {
|
||||
KeyframesIterationState::Finite(_, max) => self.duration * (max as f64),
|
||||
KeyframesIterationState::Infinite => 0.,
|
||||
KeyframesIterationState::Finite(current, _) |
|
||||
KeyframesIterationState::Infinite(current) => self.duration * current,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,11 +782,6 @@ impl ElementAnimationSet {
|
|||
}
|
||||
|
||||
maybe_start_animations(element, &context, &new_style, self);
|
||||
|
||||
// When necessary, iterate our running animations to the next iteration.
|
||||
for animation in self.animations.iter_mut() {
|
||||
animation.iterate_if_necessary(context.current_time_for_animations);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update our transitions given a new style, canceling or starting new animations
|
||||
|
@ -1039,8 +1032,8 @@ pub fn maybe_start_animations<E>(
|
|||
let delay = box_style.animation_delay_mod(i).seconds();
|
||||
let animation_start = context.current_time_for_animations + delay as f64;
|
||||
let iteration_state = match box_style.animation_iteration_count_mod(i) {
|
||||
AnimationIterationCount::Infinite => KeyframesIterationState::Infinite,
|
||||
AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0.0, n),
|
||||
AnimationIterationCount::Infinite => KeyframesIterationState::Infinite(0.0),
|
||||
AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0.0, n.into()),
|
||||
};
|
||||
|
||||
let animation_direction = box_style.animation_direction_mod(i);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue