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');
}
// Do not start transitions during the element's first style flush while
// connected. Per spec, initial computed values should apply immediately.
if (!_didFlushStyleWhileConnected) {
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info('[transition][check] property=$property skip: initial-style');
}
return false;
}
// 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 Map<String, List> transitions = effectiveTransitions;
final bool configured =
transitions.containsKey(key) || transitions.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 = transitions[key] ?? transitions[ALL];
cssLogger.info(
'[transition][check] property=$property key=$key opts=${opts != null ? '{duration: ${opts[0]}, easing: ${opts[1]}, delay: ${opts[2]}}' : 'null'}');
}
final bool shouldTransition = hasRunnableTransitions;
if (DebugFlags.shouldLogTransitionForProp(property)) {
cssLogger.info(
'[transition][check] property=$property configured key=$key result=$shouldTransition');
}
return shouldTransition;
}