paintOrbFrame function
void
paintOrbFrame(})
Draws frame onto canvas: stroked lines first, then dots far → near.
Each dot is painted in ink, leaned toward its own tint when it has one,
then faded by its ink and alpha channels — toward transparent, or toward
background when that is given. offset shifts the whole frame; the
two paints are reused across calls so nothing is allocated per dot.
Implementation
void paintOrbFrame(
Canvas canvas,
OrbFrame frame, {
required Color ink,
required Color? background,
required Offset offset,
required Paint dotPaint,
required Paint linePaint,
}) {
final dx = offset.dx;
final dy = offset.dy;
final order = frame.order;
final data = frame.data;
const stride = OrbFrame.stride;
final lines = frame.lines;
for (var i = 0; i < frame.lineCount; i++) {
final b = i * OrbFrame.lineStride;
linePaint
..color = _inkFor(ink, background, lines[b + 4], lines[b + 5])
..strokeWidth = lines[b + 6];
canvas.drawLine(
Offset(lines[b] + dx, lines[b + 1] + dy),
Offset(lines[b + 2] + dx, lines[b + 3] + dy),
linePaint,
);
}
for (var k = 0; k < order.length; k++) {
final base = order[k] * stride;
final radius = data[base + 3];
if (radius <= 0.01) {
continue;
}
final tint = data[base + 9];
final dotInk = tint <= 0
? ink
: Color.lerp(
ink,
Color.from(
alpha: ink.a,
red: data[base + 6],
green: data[base + 7],
blue: data[base + 8],
),
tint.clamp(0.0, 1.0),
) ??
ink;
dotPaint.color = _inkFor(
dotInk,
background,
data[base + 4],
data[base + 5],
);
canvas.drawCircle(
Offset(data[base] + dx, data[base + 1] + dy),
radius,
dotPaint,
);
}
}