setTargetsForNids method
void
setTargetsForNids(})
Re-targets the preview to exactly targets, mapping nid to held
offset.
- A nid whose existing target equals its new target is left UNTOUCHED, so its animation or hold continues. Re-resolving to the same slot must not restart motion.
- A nid with a different target re-baselines from its CURRENT value (no visual jump).
- Active nids absent from
targetsare released toward zero and removed on arrival. snapapplies everything instantly (global animations disabled or zero duration) and notifies once so paint refreshes.
Implementation
void setTargetsForNids(
Map<int, double> targets, {
required Duration duration,
required Curve curve,
required bool snap,
}) {
if (snap) {
_entries.clear();
for (final entry in targets.entries) {
if (entry.value == 0.0) {
continue;
}
_entries[entry.key] = _PreviewEntry(
start: entry.value,
current: entry.value,
target: entry.value,
startElapsed: Duration.zero,
duration: Duration.zero,
curve: curve,
done: true,
);
}
_ticker?.stop();
_onTick();
return;
}
if (_ticker == null || !_ticker!.isActive) {
_lastTickElapsed = Duration.zero;
}
var anyAnimating = false;
// Retarget / install the requested nids.
for (final requested in targets.entries) {
final nid = requested.key;
final target = requested.value;
final existing = _entries[nid];
if (existing != null) {
if (existing.target == target) {
if (!existing.done) {
anyAnimating = true;
}
continue;
}
existing.start = existing.current;
existing.target = target;
existing.startElapsed = _lastTickElapsed;
existing.duration = duration;
existing.curve = curve;
existing.done = false;
anyAnimating = true;
} else {
if (target == 0.0) {
continue;
}
_entries[nid] = _PreviewEntry(
start: 0.0,
current: 0.0,
target: target,
startElapsed: _lastTickElapsed,
duration: duration,
curve: curve,
);
anyAnimating = true;
}
}
// Release everything this batch no longer wants.
final toRemove = <int>[];
for (final entry in _entries.entries) {
if (targets.containsKey(entry.key)) {
continue;
}
final e = entry.value;
if (e.current == 0.0) {
toRemove.add(entry.key);
continue;
}
if (e.target != 0.0 || e.done) {
e.start = e.current;
e.target = 0.0;
e.startElapsed = _lastTickElapsed;
e.duration = duration;
e.curve = curve;
e.done = false;
}
anyAnimating = true;
}
for (final nid in toRemove) {
_entries.remove(nid);
}
if (!anyAnimating) {
return;
}
final ticker = _ticker ??= _vsync.createTicker(_onPreviewTick);
if (!ticker.isActive) {
ticker.start();
}
}