Skip to content

Commit e46917b

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

File tree

1 file changed

+106
-99
lines changed

1 file changed

+106
-99
lines changed

style/animation.rs

Lines changed: 106 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,127 +1018,134 @@ 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+
&& (allow_discrete || from.interpolable_with(&to));
1035+
let mut has_running_transition = false;
1036+
let mut has_completed_transition = false;
10421037

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
1038+
let mut old_transition= None;
1039+
if let Some(uncanceled_transition) = self
10631040
.transitions
10641041
.iter_mut()
10651042
.filter(|transition| transition.state != AnimationState::Canceled)
10661043
.find(|transition| {
10671044
transition.property_animation.property_id() == property_declaration_id
10681045
})
10691046
{
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,
1047+
match uncanceled_transition.state {
1048+
AnimationState::Finished => has_completed_transition = true,
1049+
_ => has_running_transition = true,
11271050
};
1051+
old_transition = Some(uncanceled_transition);
1052+
}
11281053

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

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

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

0 commit comments

Comments
 (0)