canvas

Globe

A Fresnel-lit globe with rim glow, haloed atmosphere, land mesh detail, and marker layers for data storytelling.


Installation

Install the component

Run the following command to install the component and its dependencies:
npx @motion-core/cli add globe

Import the component

Import the component into your Svelte file:
import { Globe } from "$lib/motion-core";
import { Globe } from "$lib/motion-core";

Usage

<script lang="ts">
	import { Globe, type GlobeMarker } from "motion-core";
	import { cn } from "$lib/utils/cn";

	const locations: (GlobeMarker & { name: string })[] = [
		{
			name: "Warsaw",
			location: [52.2297, 21.0122],
			label: "Warsaw",
			color: "#00c2a8",
		},
		{
			name: "New York",
			location: [40.7128, -74.006],
			label: "New York",
			color: "#ff2376",
		},
		{
			name: "Tokyo",
			location: [35.6762, 139.6503],
			label: "Tokyo",
			color: "#e6f0ff",
		},
	];

	let focusOn = $state<[number, number] | null>(null);
</script>

<Globe
	radius={3}
	pointCount={25000}
	class="h-full min-h-96 w-full"
	markers={locations}
	{focusOn}
	autoRotate={!focusOn}
	lockedPolarAngle={false}
/>
<div
	class="absolute bottom-4 left-1/2 z-10 flex w-fit -translate-x-1/2 justify-center gap-1 rounded-lg border border-border bg-background p-1 shadow-sm"
>
	<button
		class={cn(
			"gap-1.5 rounded-md px-3 py-1 text-xs font-medium tracking-wide whitespace-nowrap uppercase transition-colors duration-150 ease-out",
			focusOn === null
				? "bg-accent dark:text-foreground light:text-card"
				: "text-foreground/70 hover:text-foreground",
		)}
		onclick={() => (focusOn = null)}
	>
		Auto Rotate
	</button>
	{#each locations as loc (loc.name)}
		<button
			class={cn(
				"gap-1.5 rounded-md px-3 py-1 text-xs font-medium tracking-wide whitespace-nowrap uppercase transition-colors duration-150 ease-out",
				focusOn?.[0] === loc.location[0] && focusOn?.[1] === loc.location[1]
					? "bg-accent dark:text-foreground light:text-card"
					: "text-foreground/70 hover:text-foreground",
			)}
			onclick={() => (focusOn = loc.location)}
		>
			{loc.name}
		</button>
	{/each}
</div>

Props

Globe

PropTypeDefault
radius
number 2
fresnelConfig
FresnelConfig Default Fresnel
atmosphereConfig
AtmosphereConfig Default Atmosphere
pointCount
number 15000
landPointColor
THREE.ColorRepresentation "#f77114"
pointSize
number 0.05
autoRotate
boolean true
lockedPolarAngle
boolean true
markers
GlobeMarker[] []
focusOn
[number, number]null null
class
string ""

FresnelConfig

KeyTypeDefault
color
THREE.ColorRepresentation "#111113"
rimColor
THREE.ColorRepresentation "#FF6900"
rimPower
number 6
rimIntensity
number 1.5

AtmosphereConfig

KeyTypeDefault
color
THREE.ColorRepresentation "#FF6900"
scale
number 1.1
power
number 12.0
coefficient
number 0.9
intensity
number 2.0

GlobeMarker

KeyTypeDefault
location
[number, number] -
size
number 0.1
color
string "#ffffff"
label
string undefined
pinHeight
number 0.75
headRadius
number 0.1