[eric] canvas: the background can never paint raw white, tint underlay + opaque wash + compositor grid parallax

This commit is contained in:
ciregenz
2026-08-04 16:43:21 -07:00
parent 43e1028123
commit a7c95813e3
3 changed files with 37 additions and 6 deletions
@@ -13,6 +13,28 @@ export function washBackgroundUrl(stops: string[], washOpacity: number): string
return `url("data:image/svg+xml,${svg.replace(/#/g, '%23').replace(/'/g, '%27')}")`;
}
function mixHex(a: string, b: string, t: number): string {
const pa = parseInt(a.slice(1), 16);
const pb = parseInt(b.slice(1), 16);
const ch = (shift: number): number => Math.round(((pa >> shift) & 0xff) * (1 - t) + ((pb >> shift) & 0xff) * t);
return `#${((ch(16) << 16) | (ch(8) << 8) | ch(0)).toString(16).padStart(6, '0')}`;
}
// The canvas wash, pre-blended over the page color so the layer is OPAQUE: identical pixels to the translucent version, but Chromium can then paint the declared background-color for any tile it evicted or hasn't rastered yet, instead of raw page white/black.
export function washOpaqueBackgroundUrl(stops: string[], washOpacity: number, pageBg: string): string {
const alpha = Math.max(0, Math.min(1, washOpacity));
const blended = stops.map((hex) => mixHex(pageBg, hex, alpha));
return washBackgroundUrl(blended, 1);
}
// What an evicted/unrastered wash tile should paint as: the wash's mean tint, never raw page color.
export function washUnderlayColor(stops: string[], washOpacity: number, pageBg: string): string {
const alpha = Math.max(0, Math.min(1, washOpacity));
if (stops.length === 0) return pageBg;
const mean = stops.reduce((acc, hex, i) => (i === 0 ? hex : mixHex(acc, hex, 1 / (i + 1))), stops[0]);
return mixHex(pageBg, mean, alpha);
}
// Stock wallpaper when the user hasn't picked an accent yet: a designed blue-to-cream-to-pink
// gradient (contrasting stops), so a fresh install and the onboarding stage never look flat/white.
export const DEFAULT_WASH_STOPS = ['#B7CDEA', '#EFE0D2', '#E7BDD1'];