@@ -57,30 +57,6 @@ impl PropertyAnimation {
57
57
self . from . id ( )
58
58
}
59
59
60
- fn from_property_declaration (
61
- property_declaration : & PropertyDeclarationId ,
62
- timing_function : TimingFunction ,
63
- duration : f64 ,
64
- old_style : & ComputedValues ,
65
- new_style : & ComputedValues ,
66
- ) -> Option < PropertyAnimation > {
67
- // FIXME(emilio): Handle the case where old_style and new_style's writing mode differ.
68
- let property_declaration = property_declaration. to_physical ( new_style. writing_mode ) ;
69
- let from = AnimationValue :: from_computed_values ( property_declaration, old_style) ?;
70
- let to = AnimationValue :: from_computed_values ( property_declaration, new_style) ?;
71
-
72
- if from == to {
73
- return None ;
74
- }
75
-
76
- Some ( PropertyAnimation {
77
- from,
78
- to,
79
- timing_function,
80
- duration,
81
- } )
82
- }
83
-
84
60
/// The output of the timing function given the progress ration of this animation.
85
61
fn timing_function_output ( & self , progress : f64 ) -> f64 {
86
62
let epsilon = 1. / ( 200. * self . duration ) ;
@@ -1022,142 +998,129 @@ impl ElementAnimationSet {
1022
998
if !transitioning_properties. contains ( transition_property_id) {
1023
999
transition. state = AnimationState :: Canceled ;
1024
1000
self . dirty = true ;
1025
- continue ;
1026
- }
1027
-
1028
- let after_change_to = AnimationValue :: from_computed_values ( transition_property_id, & after_change_style) . unwrap ( ) ;
1029
- // Step 4
1030
- // "If the element has a running transition for the property, there is a matching transition-property value,
1031
- // and the end value of the running transition is not equal to the value of the property in the after-change style, then:"
1032
- if transition. property_animation . to != after_change_to {
1033
- // index for after-change transition declaration
1034
- let index = after_change_style. transition_properties ( ) . position ( |declared_transition| declared_transition. property
1035
- . as_borrowed ( )
1036
- . to_physical ( after_change_style. writing_mode ) == transition_property_id) . unwrap ( ) ;
1037
-
1038
- let now = context. current_time_for_animations ;
1039
- let after_change_style = after_change_style. get_ui ( ) ;
1040
- let allow_discrete = after_change_style. transition_behavior_mod ( index) == TransitionBehavior :: AllowDiscrete ;
1041
- let current_val = transition. calculate_value ( now) ;
1042
- let not_transitionable =
1043
- ( !transition_property_id. is_animatable ( ) || ( !allow_discrete && transition_property_id. is_discrete_animatable ( ) ) )
1044
- || ( !allow_discrete && !current_val. interpolable_with ( & after_change_to) ) ;
1045
-
1046
- let combined_duration = after_change_style. transition_duration_mod ( index) . seconds ( ) + after_change_style. transition_delay_mod ( index) . seconds ( ) ;
1047
-
1048
- // Step 4.1
1049
- //"If the current value of the property in the running transition is equal
1050
- // to the value of the property in the after-change style,
1051
- // or if these two values are not transitionable, then implementations must cancel the running transition."
1052
- if current_val == after_change_to || not_transitionable {
1053
- transition. state = AnimationState :: Canceled ;
1054
- self . dirty = true ;
1055
- continue ;
1056
- }
1057
- // Step 4.2
1058
- // "Otherwise, if the combined duration is less than or equal to 0s, or if the current value of the property in the
1059
- // running transition is not transitionable with the value of the property in the after-change style,
1060
- // then implementations must cancel the running transition."
1061
- else if combined_duration <= 0.0 {
1062
- transition. state = AnimationState :: Canceled ;
1063
- self . dirty = true ;
1064
- continue ;
1065
- }
1066
-
1067
- //Step 4.3, 4.4 have been done in `fn start_transition_if_applicable`
1068
1001
}
1002
+ // Step 4 was done in `fn start_transition_if_applicable`
1069
1003
}
1070
1004
}
1071
1005
1072
1006
fn start_transition_if_applicable (
1073
1007
& mut self ,
1074
1008
context : & SharedStyleContext ,
1075
- property_declaration_id : & PropertyDeclarationId ,
1009
+ property_declaration : PropertyDeclarationId ,
1076
1010
index : usize ,
1077
1011
old_style : & ComputedValues ,
1078
1012
new_style : & Arc < ComputedValues > ,
1079
1013
) {
1080
1014
let style = new_style. get_ui ( ) ;
1081
1015
let allow_discrete = style. transition_behavior_mod ( index) == TransitionBehavior :: AllowDiscrete ;
1082
-
1083
- if !property_declaration_id. is_animatable ( )
1084
- || ( !allow_discrete && property_declaration_id. is_discrete_animatable ( ) )
1085
- {
1086
- return ;
1087
- }
1016
+ let not_transitionable = !property_declaration. is_animatable ( ) ||
1017
+ ( !allow_discrete && property_declaration. is_discrete_animatable ( ) ) ;
1018
+
1019
+ let mut start_new_transition = !not_transitionable;
1088
1020
1089
1021
let timing_function = style. transition_timing_function_mod ( index) ;
1090
1022
let duration = style. transition_duration_mod ( index) . seconds ( ) as f64 ;
1091
1023
let delay = style. transition_delay_mod ( index) . seconds ( ) as f64 ;
1092
1024
let now = context. current_time_for_animations ;
1093
1025
1094
1026
if duration + delay <= 0.0 {
1095
- return ;
1027
+ start_new_transition = false ;
1096
1028
}
1097
1029
1030
+ // FIXME(emilio): Handle the case where old_style and new_style's writing mode differ.
1031
+ let Some ( from) = AnimationValue :: from_computed_values ( property_declaration, old_style) else {
1032
+ return ;
1033
+ } ;
1034
+ let Some ( to) = AnimationValue :: from_computed_values ( property_declaration, new_style) else {
1035
+ return ;
1036
+ } ;
1037
+
1098
1038
// Only start a new transition if the style actually changes between
1099
1039
// the old style and the new style.
1100
- let property_animation = match PropertyAnimation :: from_property_declaration (
1101
- property_declaration_id,
1102
- timing_function,
1103
- duration,
1104
- old_style,
1105
- new_style,
1106
- ) {
1107
- Some ( property_animation) => property_animation,
1108
- None => return ,
1109
- } ;
1040
+ if from == to {
1041
+ start_new_transition = false ;
1042
+ }
1110
1043
1111
1044
// A property may have an animation type different than 'discrete', but still
1112
1045
// not be able to interpolate some values. In that case we would fall back to
1113
1046
// discrete interpolation, so we need to abort if `transition-behavior` doesn't
1114
1047
// allow discrete transitions.
1115
- if !allow_discrete && !property_animation . from . interpolable_with ( & property_animation . to ) {
1116
- return ;
1048
+ if !allow_discrete && !from. interpolable_with ( & to) {
1049
+ start_new_transition = false ;
1117
1050
}
1118
1051
1119
- // Per [1], don't trigger a new transition if the end state for that
1120
- // transition is the same as that of a transition that's running or
1121
- // completed. We don't take into account any canceled animations.
1122
- // [1]: https://drafts.csswg.org/css-transitions/#starting
1123
- if self
1052
+ // Step 4 in https://drafts.csswg.org/css-transitions/#starting
1053
+ // "If the element has a running transition for the property, there is a matching transition-property value,
1054
+ let mut running_transition = None ;
1055
+ if let Some ( old_transition) = self
1124
1056
. transitions
1125
- . iter ( )
1057
+ . iter_mut ( )
1126
1058
. filter ( |transition| transition. state != AnimationState :: Canceled )
1127
- . any ( |transition| transition. property_animation . to == property_animation. to )
1059
+ . find ( |transition| {
1060
+ transition. property_animation . property_id ( ) == property_declaration
1061
+ } )
1128
1062
{
1129
- return ;
1063
+ // and the end value of the running transition is not equal to the value of the property in the after-change style, then:"
1064
+ if to != old_transition. property_animation . to {
1065
+ let current_val = old_transition. calculate_value ( now) ;
1066
+ let not_transitionable = not_transitionable||
1067
+ ( !allow_discrete && !current_val. interpolable_with ( & to) ) ;
1068
+
1069
+ // Step 4.1
1070
+ //"If the current value of the property in the running transition is equal
1071
+ // to the value of the property in the after-change style,
1072
+ // or if these two values are not transitionable, then implementations must cancel the running transition."
1073
+ if current_val == to || not_transitionable {
1074
+ old_transition. state = AnimationState :: Canceled ;
1075
+ self . dirty = true ;
1076
+ start_new_transition = false ;
1077
+ }
1078
+ // Step 4.2
1079
+ // "Otherwise, if the combined duration is less than or equal to 0s, or if the current value of the property in the
1080
+ // running transition is not transitionable with the value of the property in the after-change style,
1081
+ // then implementations must cancel the running transition."
1082
+ else if duration + delay <= 0.0 {
1083
+ old_transition. state = AnimationState :: Canceled ;
1084
+ self . dirty = true ;
1085
+ start_new_transition = false ;
1086
+ }
1087
+ } else {
1088
+ start_new_transition = false ;
1089
+ }
1090
+ running_transition = Some ( old_transition) ;
1130
1091
}
1131
1092
1132
1093
// Step 1 + 4.3 + 4.4 in https://drafts.csswg.org/css-transitions/#starting
1133
1094
// We are going to start a new transition, but we might have to update
1134
1095
// it if we are replacing a reversed transition.
1135
- let reversing_adjusted_start_value = property_animation. from . clone ( ) ;
1136
- let mut new_transition = Transition {
1137
- start_time : now + delay,
1138
- delay,
1139
- property_animation,
1140
- state : AnimationState :: Pending ,
1141
- is_new : true ,
1142
- reversing_adjusted_start_value,
1143
- reversing_shortening_factor : 1.0 ,
1144
- } ;
1096
+ if start_new_transition {
1097
+ let property_animation = PropertyAnimation {
1098
+ from,
1099
+ to,
1100
+ timing_function,
1101
+ duration,
1102
+ } ;
1103
+
1104
+ let reversing_adjusted_start_value = property_animation. from . clone ( ) ;
1105
+ let mut new_transition = Transition {
1106
+ start_time : now + delay,
1107
+ delay,
1108
+ property_animation,
1109
+ state : AnimationState :: Pending ,
1110
+ is_new : true ,
1111
+ reversing_adjusted_start_value,
1112
+ reversing_shortening_factor : 1.0 ,
1113
+ } ;
1145
1114
1146
- if let Some ( old_transition) = self
1147
- . transitions
1148
- . iter_mut ( )
1149
- . filter ( |transition| transition. state == AnimationState :: Running )
1150
- . find ( |transition| {
1151
- transition. property_animation . property_id ( ) == * property_declaration_id
1152
- } )
1153
- {
1154
1115
// We always cancel any running transitions for the same property.
1155
- old_transition. state = AnimationState :: Canceled ;
1156
- new_transition. update_for_possibly_reversed_transition ( old_transition, delay, now) ;
1157
- }
1116
+ if let Some ( old_transition) = running_transition {
1117
+ old_transition. state = AnimationState :: Canceled ;
1118
+ new_transition. update_for_possibly_reversed_transition ( old_transition, delay, now) ;
1119
+ }
1158
1120
1159
- self . transitions . push ( new_transition) ;
1160
- self . dirty = true ;
1121
+ self . transitions . push ( new_transition) ;
1122
+ self . dirty = true ;
1123
+ }
1161
1124
}
1162
1125
1163
1126
/// Generate a `AnimationValueMap` for this `ElementAnimationSet`'s
@@ -1370,7 +1333,7 @@ pub fn start_transitions_if_applicable(
1370
1333
properties_that_transition. insert ( physical_property) ;
1371
1334
animation_state. start_transition_if_applicable (
1372
1335
context,
1373
- & physical_property,
1336
+ physical_property,
1374
1337
transition. index ,
1375
1338
old_style,
1376
1339
new_style,
0 commit comments