92 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
'use client';
 | 
						|
import React, { useEffect, useRef, useState } from 'react';
 | 
						|
import createGlobe from 'cobe';
 | 
						|
import { cn } from '@/lib/utils';
 | 
						|
interface EarthProps {
 | 
						|
  className?: string;
 | 
						|
  theta?: number;
 | 
						|
  dark?: number;
 | 
						|
  scale?: number;
 | 
						|
  diffuse?: number;
 | 
						|
  mapSamples?: number;
 | 
						|
  mapBrightness?: number;
 | 
						|
  baseColor?: [number, number, number];
 | 
						|
  markerColor?: [number, number, number];
 | 
						|
  glowColor?: [number, number, number];
 | 
						|
}
 | 
						|
const Earth: React.FC<EarthProps> = ({
 | 
						|
  className,
 | 
						|
  theta = 0.25,
 | 
						|
  dark = 1,
 | 
						|
  scale = 1.1,
 | 
						|
  diffuse = 1.2,
 | 
						|
  mapSamples = 40000,
 | 
						|
  mapBrightness = 6,
 | 
						|
  baseColor = [0.4, 0.6509, 1],
 | 
						|
  markerColor = [1, 0, 0],
 | 
						|
  glowColor = [0.2745, 0.5765, 0.898],
 | 
						|
}) => {
 | 
						|
  const canvasRef = useRef<HTMLCanvasElement>(null);
 | 
						|
 | 
						|
  useEffect(() => {
 | 
						|
    let width = 0;
 | 
						|
    const onResize = () =>
 | 
						|
      canvasRef.current && (width = canvasRef.current.offsetWidth);
 | 
						|
    window.addEventListener('resize', onResize);
 | 
						|
    onResize();
 | 
						|
    let phi = 0;
 | 
						|
 | 
						|
    onResize();
 | 
						|
    const globe = createGlobe(canvasRef.current!, {
 | 
						|
      devicePixelRatio: 2,
 | 
						|
      width: width * 2,
 | 
						|
      height: width * 2,
 | 
						|
      phi: 0,
 | 
						|
      theta: theta,
 | 
						|
      dark: dark,
 | 
						|
      scale: scale,
 | 
						|
      diffuse: diffuse,
 | 
						|
      mapSamples: mapSamples,
 | 
						|
      mapBrightness: mapBrightness,
 | 
						|
      baseColor: baseColor,
 | 
						|
      markerColor: markerColor,
 | 
						|
      glowColor: glowColor,
 | 
						|
      opacity: 1,
 | 
						|
      offset: [0, 0],
 | 
						|
      markers: [
 | 
						|
        // longitude latitude
 | 
						|
      ],
 | 
						|
      onRender: (state: Record<string, any>) => {
 | 
						|
        // Called on every animation frame.
 | 
						|
        // `state` will be an empty object, return updated params.\
 | 
						|
        state.phi = phi;
 | 
						|
        phi += 0.003;
 | 
						|
      },
 | 
						|
    });
 | 
						|
 | 
						|
    return () => {
 | 
						|
      globe.destroy();
 | 
						|
    };
 | 
						|
  }, []);
 | 
						|
 | 
						|
  return (
 | 
						|
    <div
 | 
						|
      className={cn(
 | 
						|
        'flex items-center justify-center z-[10] w-full max-w-[350px] mx-auto',
 | 
						|
        className
 | 
						|
      )}
 | 
						|
    >
 | 
						|
      <canvas
 | 
						|
        ref={canvasRef}
 | 
						|
        style={{
 | 
						|
          width: '100%',
 | 
						|
          height: '100%',
 | 
						|
          maxWidth: '100%',
 | 
						|
          aspectRatio: '1',
 | 
						|
        }}
 | 
						|
      />
 | 
						|
    </div>
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
export default Earth; |