fix: vrai crossfade simultané — canvas masqué puis fade in+out en parallèle
ci/woodpecker/push/woodpecker Pipeline was successful

Canvas caché (opacity 0) avant update → overlay (frame A) fade out
et canvas (frame B) fade in simultanément sur 500ms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
syoul
2026-03-23 22:00:42 +01:00
parent 14d218e4ff
commit d7fef466f3
+12 -4
View File
@@ -91,25 +91,33 @@ export function HeatMap({ transactions }: HeatMapProps) {
return; return;
} }
// Freeze current frame in the overlay // 1. Hide canvas instantly (no transition)
canvas.style.transition = 'none';
canvas.style.opacity = '0';
// 2. Freeze current frame in the overlay
try { try {
overlay.src = canvas.toDataURL(); overlay.src = canvas.toDataURL();
} catch { } catch {
// canvas tainted (shouldn't happen with heatmap-only canvas) // canvas tainted (shouldn't happen with heatmap-only canvas)
canvas.style.opacity = '1';
update(); update();
return; return;
} }
overlay.style.transition = 'none'; overlay.style.transition = 'none';
overlay.style.opacity = '1'; overlay.style.opacity = '1';
// Update heatmap underneath immediately // 3. Update heatmap (invisible: canvas still at opacity 0)
update(); update();
// Then dissolve the overlay away // 4. Simultaneous crossfade: overlay fades out, canvas fades in
const raf = requestAnimationFrame(() => { const raf = requestAnimationFrame(() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
overlay.style.transition = 'opacity 0.5s ease-in-out'; const DURATION = '0.5s ease-in-out';
overlay.style.transition = `opacity ${DURATION}`;
overlay.style.opacity = '0'; overlay.style.opacity = '0';
canvas.style.transition = `opacity ${DURATION}`;
canvas.style.opacity = '1';
}); });
}); });