shouldTransition method
Implementation
bool shouldTransition(String property, String? prevValue, String nextValue) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info('[transition][check] property=$property prev=${prevValue ?? 'null'} next=$nextValue');
}
// Custom properties (CSS variables) are not animatable. Their changes may
// indirectly drive transitions on animatable properties (e.g., transform)
// via the CSSVariableMixin path. Skip here to avoid confusing logs.
if (CSSVariable.isCSSSVariableProperty(property)) {
return false;
}
// When begin propertyValue is AUTO, skip animation and trigger style update directly.
prevValue = (prevValue == null || prevValue.isEmpty) ? CSSInitialValues[property] : prevValue;
// If the serialized values are identical, skip scheduling here. Var-driven
// changes may be handled by the CSSVariableMixin path that schedules a
// transition with an explicit prev substitution.
if (prevValue == nextValue) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info('[transition][check] property=$property skip: same-serialized');
}
return false;
}
if (CSSLength.isAuto(prevValue) || CSSLength.isAuto(nextValue)) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info('[transition][check] property=$property skip: auto');
}
return false;
}
// Transition does not work when renderBoxModel has not been layout yet
// or when we don't have a transition handler for this property.
final bool hasRenderBoxModel = hasRenderBox();
final bool hasBoxSize = isBoxModelHaveSize();
final bool hasHandler = CSSTransitionHandlers[property] != null;
if (!hasRenderBoxModel || !hasBoxSize || !hasHandler) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
final String reason;
if (!hasRenderBoxModel || !hasBoxSize) {
reason = 'no-layout (hasRenderBox=$hasRenderBoxModel hasSize=$hasBoxSize)';
} else {
reason = 'no-handler';
}
cssLogger.info('[transition][check] property=$property skip: $reason');
}
return false;
}
final String key = _canonicalTransitionKey(property);
final bool configured = effectiveTransitions.containsKey(key) || effectiveTransitions.containsKey(ALL);
if (!configured) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger
.info('[transition][check] property=$property skip: not-configured (key=$key)');
}
return false;
}
if (DebugFlags.shouldLogTransitionForProp(property)) {
final List? opts = effectiveTransitions[key] ?? effectiveTransitions[ALL];
cssLogger.info(
'[transition][check] property=$property key=$key opts=${opts != null ? '{duration: ${opts[0]}, easing: ${opts[1]}, delay: ${opts[2]}}' : 'null'}');
}
bool shouldTransition = false;
// Transition will be disabled when all transition has transitionDuration as 0.
effectiveTransitions.forEach((String transitionKey, List transitionOptions) {
int? duration = CSSTime.parseTime(transitionOptions[0]);
if (duration != null && duration != 0) {
shouldTransition = true;
}
});
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info(
'[transition][check] property=$property configured key=$key result=$shouldTransition');
}
return shouldTransition;
}