scheduleRunTransitionAnimations method
void
scheduleRunTransitionAnimations(
- String propertyName,
- String? prevValue,
- String currentValue
)
Implementation
void scheduleRunTransitionAnimations(String propertyName, String? prevValue, String currentValue) {
if (DebugFlags.shouldLogTransitionForProp(propertyName)) {
cssLogger.info('[transition][queue] ${tagName}.$propertyName prev=${prevValue ?? 'null'} -> curr=$currentValue');
}
if (_pendingTransitionProps.contains(propertyName)) {
// Already scheduled this property in current frame; coalesce by updating
// the pending item's current (end) value so we run once with the latest
// destination. For color properties, prefer the most recent, fully
// resolved previous value (from computed style) instead of the earlier
// raw serialized text (which may still contain var(...)).
for (int i = _pendingTransitionQueue.length - 1; i >= 0; i--) {
final item = _pendingTransitionQueue[i];
if (item.property == propertyName) {
String? mergedPrev = item.prev;
// Color-bearing properties where we want the last, concrete
// previous value (e.g., 'rgb(...)' or 'rgba(...)') to win
// over earlier var(...) strings like 'rgb(... / null)'.
final bool isColorProp = propertyName == COLOR ||
propertyName == BACKGROUND_COLOR ||
propertyName == TEXT_DECORATION_COLOR ||
propertyName == BORDER_LEFT_COLOR ||
propertyName == BORDER_TOP_COLOR ||
propertyName == BORDER_RIGHT_COLOR ||
propertyName == BORDER_BOTTOM_COLOR;
if (isColorProp && prevValue != null && prevValue.isNotEmpty) {
mergedPrev = prevValue;
}
_pendingTransitionQueue[i] = (property: propertyName, prev: mergedPrev, curr: currentValue);
if (DebugFlags.shouldLogTransitionForProp(propertyName)) {
cssLogger.info('[transition][queue] coalesce property=$propertyName prevOld=${item.prev ?? 'null'} prevNew=${prevValue ?? 'null'} mergedPrev=${mergedPrev ?? 'null'} new-curr=$currentValue');
}
break;
}
}
return;
}
_pendingTransitionProps.add(propertyName);
_pendingTransitionQueue.add((property: propertyName, prev: prevValue, curr: currentValue));
if (_queuedTransitionBatch) return;
_queuedTransitionBatch = true;
SchedulerBinding.instance.addPostFrameCallback((_) {
// Drain queue in insertion order so related properties (e.g., width, left, transform)
// start in the same frame, improving sync.
final items = List<({String property, String? prev, String curr})>.from(_pendingTransitionQueue);
_pendingTransitionQueue.clear();
_queuedTransitionBatch = false;
for (final item in items) {
if (DebugFlags.shouldLogTransitionForProp(item.property)) {
cssLogger.info('[transition][drain] run property=${item.property} prev=${item.prev ?? 'null'} curr=${item.curr}');
}
renderStyle.runTransition(item.property, item.prev, item.curr);
_pendingTransitionProps.remove(item.property);
}
});
SchedulerBinding.instance.scheduleFrame();
}