mirror of
https://github.com/rybbit-io/rybbit.git
synced 2025-05-11 12:25:36 +02:00
Fix hexagon flickering on the globe during zoom
Implemented a mechanism for deferred change of the height of the base hexagons, depending on the distance from the globe.
This commit is contained in:
parent
bca5cc92ee
commit
8e5f47d565
1 changed files with 41 additions and 2 deletions
|
@ -4,8 +4,8 @@ import { useQuery } from "@tanstack/react-query";
|
||||||
import { useWindowSize } from "@uidotdev/usehooks";
|
import { useWindowSize } from "@uidotdev/usehooks";
|
||||||
import { scaleSequentialSqrt } from "d3-scale";
|
import { scaleSequentialSqrt } from "d3-scale";
|
||||||
import { interpolateYlOrRd } from "d3-scale-chromatic";
|
import { interpolateYlOrRd } from "d3-scale-chromatic";
|
||||||
import { memoize } from "lodash";
|
import { memoize, debounce } from "lodash";
|
||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useMemo, useRef, useState, useCallback } from "react";
|
||||||
import Globe from "react-globe.gl";
|
import Globe from "react-globe.gl";
|
||||||
import { MeshPhongMaterial } from "three";
|
import { MeshPhongMaterial } from "three";
|
||||||
import { useGetLiveSessionLocations } from "../../../../api/analytics/useGetLiveSessionLocations";
|
import { useGetLiveSessionLocations } from "../../../../api/analytics/useGetLiveSessionLocations";
|
||||||
|
@ -53,6 +53,44 @@ export const World = ({ width }: { width: number }) => {
|
||||||
}
|
}
|
||||||
}, [globeEl.current]);
|
}, [globeEl.current]);
|
||||||
|
|
||||||
|
const [hexAltitude, setHexAltitude] = useState(0.001);
|
||||||
|
|
||||||
|
// Debounced updateAltitude handler: fires once, 200ms after the last 'end' event
|
||||||
|
const updateAltitude = useCallback(
|
||||||
|
debounce(() => {
|
||||||
|
if (!globeEl.current) return;
|
||||||
|
|
||||||
|
const controls = globeEl.current.controls();
|
||||||
|
const distance = Math.round(controls.getDistance());
|
||||||
|
|
||||||
|
const low = 0.001, mid = 0.005, high = 0.02;
|
||||||
|
const near = 300, far = 600;
|
||||||
|
const nextAlt =
|
||||||
|
distance <= near ? low :
|
||||||
|
distance >= far ? high :
|
||||||
|
mid;
|
||||||
|
|
||||||
|
// set only if changed
|
||||||
|
if (nextAlt !== hexAltitude) {
|
||||||
|
setHexAltitude(nextAlt);
|
||||||
|
}
|
||||||
|
}, 200),
|
||||||
|
[globeEl, hexAltitude, setHexAltitude]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!globeEl.current) return;
|
||||||
|
const controls = globeEl.current.controls();
|
||||||
|
// Limit distance maximal distance
|
||||||
|
controls.maxDistance = 900;
|
||||||
|
// Subscribe on change event
|
||||||
|
controls.addEventListener('end', updateAltitude);
|
||||||
|
return () => {
|
||||||
|
controls.removeEventListener('end', updateAltitude);
|
||||||
|
updateAltitude.cancel(); // cancel any pending call
|
||||||
|
};
|
||||||
|
}, [globeEl, updateAltitude]);
|
||||||
|
|
||||||
const oceanBlueMaterial = useMemo(
|
const oceanBlueMaterial = useMemo(
|
||||||
() =>
|
() =>
|
||||||
new MeshPhongMaterial({
|
new MeshPhongMaterial({
|
||||||
|
@ -106,6 +144,7 @@ export const World = ({ width }: { width: number }) => {
|
||||||
hexPolygonMargin={0.2}
|
hexPolygonMargin={0.2}
|
||||||
hexBinResolution={3}
|
hexBinResolution={3}
|
||||||
hexBinPointsData={liveSessionLocationsData}
|
hexBinPointsData={liveSessionLocationsData}
|
||||||
|
hexPolygonAltitude={hexAltitude}
|
||||||
hexBinMerge={true}
|
hexBinMerge={true}
|
||||||
hexBinPointWeight={"count"}
|
hexBinPointWeight={"count"}
|
||||||
backgroundColor="rgba(0, 0, 0, 0)"
|
backgroundColor="rgba(0, 0, 0, 0)"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue