apply method
Write this frame's poses, ink passes and decor for slice into frame.
Implementation
@override
void apply(TextFrame frame, UnitSlice slice) {
if (slice.isEmpty) return;
final periodS = period.inMicroseconds / 1e6;
final phase = periodS <= 0 ? 0.0 : (frame.time / periodS) % 1.0;
final sweep = (1 - rest).clamp(0.15, 1.0);
final raw = phase / sweep;
if (raw >= 1) return; // resting — plain text, no layer, no shader
final b = band.clamp(0.02, 0.49);
final eased = KineticEase.sweep.transform(raw);
final rtl = frame.readsRtl(slice);
final centers = Sweep.centers(origin, eased, b, rtl: rtl);
final shaped = frame.shaped;
final bounds = shaped.boundsOf(slice.units);
if (bounds.width <= 0) return;
final appear = Sweep.appear(origin, eased);
if (pop != 0) {
for (final i in slice.units) {
final c = (shaped.units[i].rect.center.dx - bounds.left) / bounds.width;
var bump = 0.0;
for (final p in centers) {
final d = (p - c) / b;
bump = math.max(bump, math.exp(-d * d));
}
bump *= appear;
if (bump < 0.01) continue;
final pose = frame.pose(i);
pose.scale *= 1 + pop * bump;
pose.pivot = UnitPivot.baseline;
}
}
final k = intensity.clamp(0.0, 1.0) * appear;
final multi = colors;
for (var n = 0; n < centers.length; n++) {
final p = centers[n];
if (p + b <= 0 || p - b >= 1) continue; // off the slice
final List<Color> stopsColors;
final List<double> stops;
if (multi != null && multi.isNotEmpty) {
// The last colour leads: mirrored when this band runs leftwards.
final leftward = Sweep.travelsLeft(origin, rtl: rtl) != (n == 1);
final ordered = leftward ? multi.reversed.toList() : multi;
stopsColors = [
ordered.first.withValues(alpha: 0),
for (final c in ordered) c.withValues(alpha: c.a * k),
ordered.last.withValues(alpha: 0),
];
final inner = ordered.length;
stops = [
(p - b).clamp(0.0, 1.0),
for (var j = 0; j < inner; j++)
(p - b + (j + 1) / (inner + 1) * 2 * b).clamp(0.0, 1.0),
(p + b).clamp(0.0, 1.0),
];
} else {
stopsColors = [
for (final w in bandProfile) color.withValues(alpha: color.a * k * w),
];
stops = bandStops(p, b);
}
frame.ink.add(InkPass(
units: slice.units,
bounds: bounds,
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: stopsColors,
stops: stops,
),
blendMode: blendMode,
));
}
}