Initial commit
This commit is contained in:
70
components/widgets/GlobeCard.tsx
Normal file
70
components/widgets/GlobeCard.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
'use client';
|
||||
|
||||
import createGlobe from 'cobe';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Globe } from 'lucide-react';
|
||||
|
||||
export function GlobeCard() {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let phi = 0;
|
||||
|
||||
if (!canvasRef.current) return;
|
||||
|
||||
const globe = createGlobe(canvasRef.current, {
|
||||
devicePixelRatio: 2,
|
||||
width: 600 * 2,
|
||||
height: 600 * 2,
|
||||
phi: 0,
|
||||
theta: 0,
|
||||
dark: 1,
|
||||
diffuse: 1.2,
|
||||
mapSamples: 16000,
|
||||
mapBrightness: 6,
|
||||
baseColor: [0.3, 0.3, 0.3],
|
||||
markerColor: [0.1, 0.8, 1],
|
||||
glowColor: [0.1, 0.1, 0.2],
|
||||
markers: [
|
||||
// Mock data points
|
||||
{ location: [40.7128, -74.0060], size: 0.05 }, // NY
|
||||
{ location: [51.5074, -0.1278], size: 0.05 }, // London
|
||||
{ location: [35.6762, 139.6503], size: 0.05 }, // Tokyo
|
||||
{ location: [22.3193, 114.1694], size: 0.05 }, // HK
|
||||
{ location: [-33.8688, 151.2093], size: 0.05 }, // Sydney
|
||||
],
|
||||
onRender: (state) => {
|
||||
// Called on every animation frame.
|
||||
// `state` will be an empty object, return updated params.
|
||||
state.phi = phi;
|
||||
phi += 0.01;
|
||||
},
|
||||
});
|
||||
|
||||
return () => {
|
||||
globe.destroy();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="col-span-1 md:col-span-2 lg:col-span-2 row-span-2 bg-neutral-900 border border-neutral-800 rounded-xl relative overflow-hidden group hover:border-neutral-700 transition-colors">
|
||||
<div className="absolute top-6 left-6 z-10 pointer-events-none">
|
||||
<div className="flex items-center gap-2 text-neutral-400">
|
||||
<Globe size={18} />
|
||||
<span className="text-sm font-medium">Active Visitors</span>
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
<span className="text-2xl font-bold text-white tracking-tight">1,240</span>
|
||||
<span className="text-xs text-neutral-500 ml-2 font-mono">LIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute inset-0 flex items-center justify-center opacity-80 mt-10">
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
style={{ width: 600, height: 600, maxWidth: '100%', aspectRatio: 1 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user