canvas

Globe

A rotating Fresnel-shaded sphere with orbit controls, perfect for atmospheric hero blocks and loading states.


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