Skip to content

Commit ecdab05

Browse files
committed
Restructure: follow same order as Spec written in
Signed-off-by: Euclid Ye <[email protected]>
1 parent 1c402e7 commit ecdab05

File tree

1 file changed

+105
-99
lines changed

1 file changed

+105
-99
lines changed

style/animation.rs

Lines changed: 105 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,127 +1018,133 @@ impl ElementAnimationSet {
10181018
) {
10191019
let style = new_style.get_ui();
10201020
let allow_discrete = style.transition_behavior_mod(index) == TransitionBehavior::AllowDiscrete;
1021-
let not_transitionable = !property_declaration_id.is_animatable()
1022-
|| (!allow_discrete && property_declaration_id.is_discrete_animatable());
1023-
1024-
let mut start_new_transition = !not_transitionable;
1025-
1026-
let timing_function = style.transition_timing_function_mod(index);
1027-
let duration = style.transition_duration_mod(index).seconds() as f64;
1028-
let delay = style.transition_delay_mod(index).seconds() as f64;
1029-
let now = context.current_time_for_animations;
1030-
1031-
if duration + delay <= 0.0 {
1032-
start_new_transition = false;
1033-
}
1034-
10351021
// FIXME(emilio): Handle the case where old_style and new_style's writing mode differ.
10361022
let Some(from) = AnimationValue::from_computed_values(property_declaration_id, old_style) else {
10371023
return;
10381024
};
10391025
let Some(to) = AnimationValue::from_computed_values(property_declaration_id, new_style) else {
10401026
return;
10411027
};
1028+
let timing_function = style.transition_timing_function_mod(index);
1029+
let duration = style.transition_duration_mod(index).seconds() as f64;
1030+
let delay = style.transition_delay_mod(index).seconds() as f64;
1031+
let now = context.current_time_for_animations;
1032+
let transitionable = property_declaration_id.is_animatable()
1033+
&& (allow_discrete || !property_declaration_id.is_discrete_animatable());
1034+
let mut has_running_transition = false;
1035+
let mut has_completed_transition = false;
10421036

1043-
// Only start a new transition if the style actually changes between
1044-
// the old style and the new style.
1045-
if from == to {
1046-
start_new_transition = false;
1047-
}
1048-
1049-
// A property may have an animation type different than 'discrete', but still
1050-
// not be able to interpolate some values. In that case we would fall back to
1051-
// discrete interpolation, so we need to abort if `transition-behavior` doesn't
1052-
// allow discrete transitions.
1053-
if !allow_discrete && !from.interpolable_with(&to) {
1054-
start_new_transition = false;
1055-
}
1056-
1057-
// Step 4 in https://drafts.csswg.org/css-transitions/#starting
1058-
// "If the element has a running transition for the property, there is a matching
1059-
// transition-property value, and the end value of the running transition is not equal
1060-
// to the value of the property in the after-change style, then:"
1061-
let mut running_transition = None;
1062-
if let Some(old_transition) = self
1037+
let mut old_transition= None;
1038+
if let Some(uncanceled_transition) = self
10631039
.transitions
10641040
.iter_mut()
10651041
.filter(|transition| transition.state != AnimationState::Canceled)
10661042
.find(|transition| {
10671043
transition.property_animation.property_id() == property_declaration_id
10681044
})
10691045
{
1070-
if to != old_transition.property_animation.to {
1071-
if old_transition.state != AnimationState::Finished {
1072-
let current_val = old_transition.calculate_value(now);
1073-
let not_transitionable = not_transitionable||
1074-
(!allow_discrete && !current_val.interpolable_with(&to));
1075-
1076-
// Step 4.1
1077-
// > If the current value of the property in the running transition
1078-
// > is equal to the value of theproperty in the after-change style,
1079-
// > or if these two values are not transitionable, then
1080-
// > implementations must cancel the running transition.
1081-
if current_val == to || not_transitionable {
1082-
old_transition.state = AnimationState::Canceled;
1083-
self.dirty = true;
1084-
return;
1085-
}
1086-
// Step 4.2
1087-
// "Otherwise, if the combined duration is less than or equal to 0s, or if the current value of the property in the
1088-
// running transition is not transitionable with the value of the property in the after-change style,
1089-
// then implementations must cancel the running transition."
1090-
else if duration + delay <= 0.0 {
1091-
old_transition.state = AnimationState::Canceled;
1092-
self.dirty = true;
1093-
return;
1094-
}
1095-
running_transition = Some(old_transition);
1096-
}
1097-
}
1098-
// Per [1], don't trigger a new transition if the end state for that
1099-
// transition is the same as that of a transition that's running or
1100-
// completed. We don't take into account any canceled animations.
1101-
// [1]: https://drafts.csswg.org/css-transitions/#starting
1102-
else {
1103-
return;
1104-
}
1105-
}
1106-
1107-
// Step 1 + 4.3 + 4.4 in https://drafts.csswg.org/css-transitions/#starting
1108-
// We are going to start a new transition, but we might have to update
1109-
// it if we are replacing a reversed transition for step 4.3.
1110-
if start_new_transition {
1111-
let property_animation = PropertyAnimation {
1112-
from,
1113-
to,
1114-
timing_function,
1115-
duration,
1116-
};
1117-
1118-
let reversing_adjusted_start_value = property_animation.from.clone();
1119-
let mut new_transition = Transition {
1120-
start_time: now + delay,
1121-
delay,
1122-
property_animation,
1123-
state: AnimationState::Pending,
1124-
is_new: true,
1125-
reversing_adjusted_start_value,
1126-
reversing_shortening_factor: 1.0,
1046+
match uncanceled_transition.state {
1047+
AnimationState::Finished => has_completed_transition = true,
1048+
_ => has_running_transition = true,
11271049
};
1050+
old_transition = Some(uncanceled_transition);
1051+
}
11281052

1129-
// We always cancel any running transitions for the same property, according to step 4.
1130-
if let Some(old_transition) = running_transition {
1131-
old_transition.state = AnimationState::Canceled;
1132-
new_transition.update_for_possibly_reversed_transition(old_transition, delay, now);
1053+
// Step 1 in https://drafts.csswg.org/css-transitions/#starting
1054+
// > If all of the following are true:
1055+
// > 1. the element does not have a running transition for the property,
1056+
// > 2. the before-change style is different from the after-change style for that property,
1057+
// > and the values for the property are transitionable,
1058+
// > 4. there is a matching transition-property value, and
1059+
// > 5. the combined duration is greater than 0s,
1060+
if !has_running_transition && (transitionable && from != to) && (duration + delay > 0.0) {
1061+
// > 3. the element does not have a completed transition for the property or the end value
1062+
// > of the completed transition is different from the after-change style for the property
1063+
let mut start_new_transition = !has_completed_transition;
1064+
if has_completed_transition {
1065+
let completed_transition = old_transition.as_ref().unwrap();
1066+
start_new_transition = completed_transition.property_animation.to != to;
11331067
}
1068+
// > then implementations must remove the completed transition (if present) from
1069+
// > the set of completed transitions and start a transition...
1070+
if start_new_transition {
1071+
let property_animation = PropertyAnimation {
1072+
from: from.clone(),
1073+
to,
1074+
timing_function,
1075+
duration,
1076+
};
1077+
let new_transition = Transition {
1078+
start_time: now + delay,
1079+
delay,
1080+
property_animation,
1081+
state: AnimationState::Pending,
1082+
is_new: true,
1083+
reversing_adjusted_start_value: from.clone(),
1084+
reversing_shortening_factor: 1.0,
1085+
};
1086+
self.transitions.push(new_transition);
1087+
self.dirty = true;
1088+
return;
1089+
}
1090+
}
1091+
// Step 2 will be done later in `fn process_animations_for_style`
1092+
// Step 3 will be done later in `fn update_transitions_for_new_style`
11341093

1135-
self.transitions.push(new_transition);
1136-
self.dirty = true;
1094+
// Step 4 in https://drafts.csswg.org/css-transitions/#starting
1095+
// "If the element has a running transition for the property, there is a matching
1096+
// transition-property value, and the end value of the running transition is not equal
1097+
// to the value of the property in the after-change style, then:"
1098+
if has_running_transition {
1099+
let running_transition = old_transition.unwrap();
1100+
if running_transition.property_animation.to != to {
1101+
let current_val = running_transition.calculate_value(now);
1102+
let transitionable =
1103+
transitionable && (allow_discrete || current_val.interpolable_with(&to));
1104+
// Step 4.1
1105+
// > If the current value of the property in the running transition
1106+
// > is equal to the value of theproperty in the after-change style,
1107+
// > or if these two values are not transitionable, then
1108+
// > implementations must cancel the running transition.
1109+
if current_val == to || !transitionable {
1110+
running_transition.state = AnimationState::Canceled;
1111+
self.dirty = true;
1112+
}
1113+
// Step 4.2
1114+
// "Otherwise, if the combined duration is less than or equal to 0s,
1115+
// or if the current value of the property in the running transition is not
1116+
// transitionable with the value of the property in the after-change style,
1117+
// then implementations must cancel the running transition."
1118+
else if duration + delay <= 0.0 {
1119+
running_transition.state = AnimationState::Canceled;
1120+
self.dirty = true;
1121+
}
1122+
//step 4.3 + 4.4. Cancel running transition and start a new one.
1123+
else {
1124+
running_transition.state = AnimationState::Canceled;
1125+
let property_animation = PropertyAnimation {
1126+
from: from.clone(),
1127+
to,
1128+
timing_function,
1129+
duration,
1130+
};
1131+
let mut new_transition = Transition {
1132+
start_time: now + delay,
1133+
delay,
1134+
property_animation,
1135+
state: AnimationState::Pending,
1136+
is_new: true,
1137+
reversing_adjusted_start_value: from.clone(),
1138+
reversing_shortening_factor: 1.0,
1139+
};
1140+
new_transition.update_for_possibly_reversed_transition(running_transition, delay, now);
1141+
self.transitions.push(new_transition);
1142+
self.dirty = true;
1143+
}
1144+
}
11371145
}
11381146
}
11391147

1140-
1141-
11421148
/// Generate a `AnimationValueMap` for this `ElementAnimationSet`'s
11431149
/// transitions that depends on flag.
11441150
fn get_value_map_for_transitions(&self, now: f64, flag: IncludedTransitions) -> Option<AnimationValueMap> {

0 commit comments

Comments
 (0)