pub fn camera_pan_transition(
bg_a: &[u8],
bg_b: &[u8],
fg_a: &[u8],
fg_b: &[u8],
width: u32,
height: u32,
progress: f64,
dx: f32,
dy: f32,
easing: &EasingType,
pan_background: PanBackground,
) -> Vec<u8> ⓘExpand description
Camera pan transition: composited background + sliding foreground children.
bg_a/bg_b are the outgoing/incoming backgrounds, fg_a/fg_b are
children-only (transparent). fg_a slides out by (-dxt, -dyt), fg_b
slides in from (dx*(1-t), dy*(1-t)).
pan_background controls how the two backgrounds combine:
Static: neither travels nor scales — the backdrop holds its position, which is what keeps a shared ambience continuous across a beat when both scenes actually share the same background (the crossfade below is then a no-op, since blending a frame with itself returns that frame).Travel: each background moves locked to its own foreground, so the two beats read as different places rather than one space.
Both modes crossfade the two background layers in f32 rather than through
Skia’s Paint alpha, which quantizes to an 8-bit byte: while the byte
climbs, the premultiplied blend truncates ~1 LSB per channel across the
whole frame, and the instant it reaches 255 Skia takes the opaque fast
path and every pixel regains that level in a single frame — a visible
step at 40-80x the local per-frame rate. blend_fade already does this
crossfade correctly (see its doc); we render each background into its own
full-frame layer first (needed for Travel’s scale + translate), then
hand both raw buffers to it.