From bc61527b4e63f8c42182b7dfd066e8c6896faa46 Mon Sep 17 00:00:00 2001 From: syoul Date: Mon, 23 Mar 2026 22:43:12 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20annuler=20les=20deux=20RAFs=20au=20clean?= =?UTF-8?q?up=20pour=20=C3=A9viter=20la=20double=20transition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le cleanup n'annulait que raf1. Si raf1 avait déjà tiré avant le cleanup React, raf2 restait en queue et déclenchait une deuxième transition (l'aller-retour visible à la fin de chaque frame). Fix : stocker raf2 dans la closure et l'annuler aussi. Co-Authored-By: Claude Sonnet 4.6 --- src/components/HeatMap.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/HeatMap.tsx b/src/components/HeatMap.tsx index 03cf5b5..4527dd6 100644 --- a/src/components/HeatMap.tsx +++ b/src/components/HeatMap.tsx @@ -114,8 +114,10 @@ export function HeatMap({ transactions }: HeatMapProps) { update(); // 5. Simultaneously: canvas fades in, overlay fades out → true crossfade - const raf = requestAnimationFrame(() => { - requestAnimationFrame(() => { + // Both RAF ids must be cancelled on cleanup to avoid double-transition + let raf2 = 0; + const raf1 = requestAnimationFrame(() => { + raf2 = requestAnimationFrame(() => { const DURATION = '0.55s ease-in-out'; canvas.style.transition = `opacity ${DURATION}`; canvas.style.opacity = '1'; @@ -124,7 +126,7 @@ export function HeatMap({ transactions }: HeatMapProps) { }); }); - return () => cancelAnimationFrame(raf); + return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); }; }, [transactions]); return (