feat: fondu entre les frames de l'animation heatmap
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
Fade out 250ms → mise à jour des données → fade in 250ms sur le canvas Leaflet.heat. Aucun état React supplémentaire — manipulation directe du canvas interne via _canvas. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-13
@@ -64,25 +64,40 @@ export function HeatMap({ transactions }: HeatMapProps) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Update heatmap data when transactions change
|
||||
// Update heatmap data with fade transition when transactions change
|
||||
useEffect(() => {
|
||||
if (!heatRef.current || !mapRef.current) return;
|
||||
|
||||
// Normalize amounts for intensity (log scale feels better visually)
|
||||
const maxAmount = Math.max(...transactions.map((t) => t.amount), 1);
|
||||
const canvas = (heatRef.current as unknown as { _canvas?: HTMLCanvasElement })._canvas;
|
||||
|
||||
const points: L.HeatLatLngTuple[] = transactions.map((tx) => [
|
||||
tx.lat,
|
||||
tx.lng,
|
||||
Math.min(Math.log1p(tx.amount) / Math.log1p(maxAmount), 1),
|
||||
]);
|
||||
const update = () => {
|
||||
const maxAmount = Math.max(...transactions.map((t) => t.amount), 1);
|
||||
const points: L.HeatLatLngTuple[] = transactions.map((tx) => [
|
||||
tx.lat,
|
||||
tx.lng,
|
||||
Math.min(Math.log1p(tx.amount) / Math.log1p(maxAmount), 1),
|
||||
]);
|
||||
try {
|
||||
heatRef.current?.setLatLngs(points);
|
||||
} catch {
|
||||
// map was torn down (React StrictMode double-invoke), ignore
|
||||
}
|
||||
};
|
||||
|
||||
// Guard: only update if the heat layer is still attached to the map
|
||||
try {
|
||||
heatRef.current.setLatLngs(points);
|
||||
} catch {
|
||||
// map was torn down (React StrictMode double-invoke), ignore
|
||||
if (!canvas) {
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
canvas.style.transition = 'opacity 0.25s ease-in-out';
|
||||
canvas.style.opacity = '0';
|
||||
|
||||
const t = setTimeout(() => {
|
||||
update();
|
||||
canvas.style.opacity = '1';
|
||||
}, 250);
|
||||
|
||||
return () => clearTimeout(t);
|
||||
}, [transactions]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user