vasturiano / react-globe.gl

React component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/react-globe.gl/example/world-population/
MIT License
818 stars 150 forks source link

Worldcoin example #170

Open kamami opened 3 months ago

kamami commented 3 months ago

How can I achieve an animating globe like on the worldcoin page? https://worldcoin.org

image

I am in particular interested in the extruding dots. I already managed to get the dotted continents, but I am not able to make them animate and change the altitude... Any ideas?

This is my code so far:

"use client";
import { useRef, useEffect, useState } from "react";
import Globe from "react-globe.gl";

export default function World() {
  const globeEl = useRef();
  const [countries, setCountries] = useState({ features: [] });

  useEffect(() => {
    fetch("ne_110m_admin_0_countries.geojson")
      .then((res) => res.json())
      .then(setCountries);
  }, []);

  useEffect(() => {
    // Auto-rotate
    globeEl.current.controls().enableZoom = false;
    globeEl.current.controls().autoRotate = true;
    globeEl.current.controls().autoRotateSpeed = 0.5;
  }, []);

  return (
    <Globe
      ref={globeEl}
      width={window.innerWidth - 64}
      height={window.innerWidth - 64}
      backgroundColor="#fff"
      atmosphereColor="#f0f0f0"
      atmosphereAltitude={0.5}
      showGlobe={true}
      globeImageUrl="white.jpg"
      hexPolygonsData={countries.features}
      hexPolygonResolution={3}
      hexPolygonMargin={0.3}
      hexPolygonUseDots={true}
      hexPolygonColor={(d) =>
        d.properties.REGION_UN == "Americas" ? "#dbdbdb" : "#000"
      } // Verwende hexColors für die Farben
    />
  );
}
vasturiano commented 3 months ago

@kamami for that I would focus on the hex bin layer.

kamami commented 3 months ago

@vasturiano I already experimented with it and sticked to this example: https://github.com/vasturiano/react-globe.gl/blob/master/example/world-population/index.html

Would you rather update the popData and increase/decrease the "pop" property of each object. Or would you update the hexAltitude to change the height of the pillars?

vasturiano commented 3 months ago

It depends. If you're visualizing actual data changes with your pillar height changes, then I would keep changing the data according to your time series, and feed it into the component frame by frame.

If on the other hand you just want to animate the pillars more for "visual effect", then I would simply adjust the accessor functions. You can play with either hexBinPointWeight or hexAltitude to get that effect.

kamami commented 3 months ago

Ok thanks, I think I am on a good way! Is it possible to transition the color of the hexBins based on the altitude? I am using this code, but when the hexBins are retracting, because the pop value is set to 0, they immediately get black. I want the color to transition smoothly just like in the world coin example.

  useEffect(() => {
    const intervalId = setInterval(() => {
      setPopData(currentData =>
        currentData.map(data => ({
          ...data,
          pop: increasePop ? data.originalPop * 1.5 : 0, // Wechsle zwischen originalPop und originalPop * 1.5
        }))
      );
      setIncreasePop(prevState => !prevState); // Wechsle den Zustand bei jedem Interval
    }, 2000); // Wechsle alle 2 Sekunden

    return () => clearInterval(intervalId);
  }, [increasePop, popData]);

  const weightColor = d3
    .scaleSequentialSqrt(d3.interpolateRgb("black", "green"))
    .domain([0, 1e6]);
vasturiano commented 3 months ago

@kamami if you're using hexTransitionDuration, that only affects the altitude and radius of the poles.

kamami commented 3 months ago

@vasturiano So a transition of the hexSideColor is not possible, correct? Just trying to make sure so that I am not wasting any time on trying to find the solution.

vasturiano commented 2 months ago

@kamami correct, that's not available with the built-in animation. But you can always achieve the same result by tweening your own color changes and passing new values at every frame to the component, via hexSideColor.