Three.js Scroll Wireframe Globe Spin — Disk-to-Sphere Reveal

Three.js Scroll Wireframe Globe Spin · Scroll · Plain HTML, CSS & JS · Live preview

What's included

Features

One wireframe IcosahedronGeometry sphere, scaled flat along one axis, doubles as both the starting disk and the finished globe
A matching RingGeometry edge outline reinforces the flat-disk read at the start and fades out as the globe spins up
Rotation speed scales with progress squared for a flywheel-style spin-up rather than constant angular velocity
City markers use a single InstancedMesh with fixed spherical-coordinate directions computed once at startup
Each city marker reveals at its own staggered progress threshold for a spread-out, sequential lighting-up effect
City InstancedMesh transform mirrors the globe mesh transform every frame, keeping markers glued to the wireframe surface
Live HUD readout tracks both spin-up percentage and the count of currently lit cities
Fully reversible pinned scroll animation — scrolling up flattens the globe and un-lights cities in reverse

About this UI Snippet

How to Build a Scroll-Driven Wireframe Globe Spin-Up With Three.js

Screenshot of the Three.js Scroll Wireframe Globe Spin snippet rendered live

The Three.js Scroll Wireframe Globe Spin Up snippet starts with a wireframe sphere squashed nearly flat along one axis — reading as a 2D disk — and, as the visitor scrolls through a pinned stage, scales it back up to a full sphere while its rotation speed ramps and small city markers light up one by one across its wireframe surface.

A squashed sphere reads convincingly as a flat disk

Rather than swapping between a separate 2D circle mesh and a 3D sphere mesh, this snippet uses one THREE.IcosahedronGeometry(4, 3) wireframe sphere for the entire effect, scaling its y axis down to a tiny fraction (flatness) at the start. A wireframe sphere viewed nearly edge-on along its flattened axis reads visually as a flat disk of crossing lines, and a matching RingGeometry edge outline reinforces that disk silhouette at the very start of the scroll, fading out as flatness grows back toward 1. This single-geometry approach avoids ever needing to swap meshes or cross-fade materials.

Spin-up speed scales with progress squared, not linearly

The globe's rotation increment each frame is multiplied by eased * eased, so the globe barely rotates while still flat and disk-like, and picks up meaningfully more spin speed only in the back half of the scroll range — a spin-up curve that feels like a physical flywheel accelerating rather than an object rotating at a constant rate throughout. The globe simultaneously tilts from a steep rotation.x angle back toward level as eased climbs, so the "flat disk" reads as being viewed nearly face-on at the start and levels out into a natural equatorial view once fully formed.

City markers placed once via spherical coordinates, lit progressively

Each of the forty-plus city markers gets a fixed direction vector computed once from a random latitude/longitude pair, converted to Cartesian coordinates on a unit sphere. Every frame, each marker's live position is that direction scaled to the globe's surface radius, and a marker only renders at visible scale once eased passes an individually staggered threshold (0.15 + cityT * 0.75) — meaning cities light up in a spread-out, sequential-feeling pattern across the whole second half of the scroll rather than all appearing simultaneously. This staggered-threshold reveal pattern is the same technique used per-panel in origami crane unfold, applied here to city points instead of paper panels.

City marker InstancedMesh mirrors the globe's own transform

Rather than recomputing flattening and rotation separately for the city markers, the city InstancedMesh's own rotation and scale are set to copy the globe mesh's rotation and scale every frame, so the cities stay glued to the globe's wireframe surface through the entire spin-up and flattening transition without any extra per-marker transform math.

Fully reversible spin-down

Because flatness, rotation speed, edge opacity, and every city's lit/unlit threshold are all direct functions of the same eased progress value, scrolling back up smoothly reverses every layer at once: cities wink out from the most-recently-lit backward, rotation slows back toward a near-standstill, and the globe visibly flattens back into a 2D-reading disk.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to reverse-engineer how a flat wireframe disk convincingly spins up into a full 3D globe with lighting-up cities. Paste this snippet's HTML, CSS, and JS into an AI assistant like Claude and ask it to explain why a single scaled sphere works better than swapping meshes, or how the staggered per-city litThreshold produces a sequential reveal from one progress value. The same assistant can help you extend it — ask it to add great-circle arc lines connecting lit cities, texture-map a real world outline onto the wireframe, or add a subtle atmosphere glow shell around the finished globe. Treat the code as a conversation starter, not a finished artifact.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll-scrubbed wireframe globe spin-up" in plain HTML, CSS, and JavaScript using Three.js, GSAP, and GSAP's ScrollTrigger plugin, all loaded from a CDN (no bundler, no build step).

Requirements:
- A pinned section containing a full-size canvas, with a WebGLRenderer and PerspectiveCamera sized to the canvas element (not window.innerWidth/innerHeight) and updated on window resize including aspect ratio.
- Create one wireframe sphere mesh (e.g. THREE.IcosahedronGeometry with a MeshBasicMaterial using wireframe: true) and scale it down to a small fraction on one axis at rest so it reads visually as a flat 2D disk, plus a thin RingGeometry outline mesh reinforcing that disk edge.
- Compute a fixed set of city marker positions once at startup using random latitude/longitude pairs converted to Cartesian direction vectors on a unit sphere, and render all markers through a single THREE.InstancedMesh.
- Register a GSAP tween on a ScrollTrigger targeting the pinned section, with pin: true, start at top top, a numeric scrub, and a multi-hundred-percent end, animating a single plain progress value from 0 to 1 with linear easing.
- Every animation frame, apply smoothstep easing to the scrubbed progress, then scale the globe's flattened axis back up toward 1 by that eased value, tilt it from a steep starting angle back toward level, and increase its rotation speed using eased raised to a power greater than 1 so spin-up accelerates rather than staying linear.
- Fade out the disk-edge ring's opacity as the globe un-flattens.
- Give each city marker its own individually staggered reveal threshold derived from its index (so cities light up spread across the scroll range rather than all at once), scale each marker toward zero when the live progress is below its threshold and toward a visible size once above it, and make the city InstancedMesh copy the globe mesh's own rotation and scale every frame so markers stay glued to the wireframe surface.
- Track and display both an overall spin-up percentage and a live count of currently lit cities.
- Confirm scrolling back up reverses every layer smoothly: cities wink out, rotation slows, and the globe flattens back into a 2D-reading disk, since every property is a direct function of the shared progress value.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<section class="wgs-stage" id="wgsStage">
  <div class="wgs-intro-overlay"><p>Scroll ↓ to spin the flat disk up into a wireframe globe</p></div>
  <canvas id="wgsCanvas"></canvas>
  <div class="wgs-hud"><span id="wgsPct">0</span>% spun up · <span id="wgsCities">0</span> cities online</div>
</section>
<section class="wgs-bottom"><p>A fully rotating wireframe globe, cities lit across every continent.</p></section>

Step by step

How to Use

  1. 1
    Load all three CDN scriptsAdd three.min.js, gsap.min.js, and ScrollTrigger.min.js from the CDN panel, in that order.
  2. 2
    Paste HTML, CSS, and JSA flat wireframe disk appears inside a pinned 3D stage with a live "% spun up" and city count read-out.
  3. 3
    Scroll downThe disk scales up into a full wireframe globe, rotation speed ramps up, and city markers light up progressively.
  4. 4
    Scroll back upThe globe flattens back into a disk and cities wink out in reverse, since every layer is a function of one progress value.
  5. 5
    Retune the globeChange CITY_COUNT for more or fewer markers, or the IcosahedronGeometry detail level for a finer or coarser wireframe.
  6. 6
    Adjust the pacingChange the ScrollTrigger end value (+=450%) or the per-city litThreshold formula to retime the reveal.

Real-world uses

Common Use Cases

Global SaaS and logistics landing pages
Open a company's "global presence" or worldwide-network section with a globe that spins up and lights city hubs.
Network and infrastructure dashboards
Use a fully-spun static state as an ambient visual for uptime, CDN, or server-map dashboards.
Travel and logistics brand intros
A globe spin-up suits airlines, shipping, or travel-tech hero sections better than a static world map.
Geography and astronomy education
Pair with scroll number odometer counters for a data-driven world-facts explainer page.
Scroll-story chapter breaks
Use the spin-up as a mid-page transition, similar in spirit to the scroll tunnel bridge.
Strategy or simulation game menus
A rotating wireframe globe reads well as an ambient title-screen or campaign-map backdrop element.

Got questions?

Frequently Asked Questions

Swapping between two different meshes (a flat circle and a 3D sphere) would require cross-fading materials or opacity to hide the transition seam. Scaling a single wireframe IcosahedronGeometry down to near-zero on one axis produces a convincing flat-disk silhouette using the exact same geometry that becomes the full globe, so there is only ever one mesh to animate and no seam to hide.

Multiplying the per-frame rotation increment by eased * eased means the globe barely spins while still flat and disk-shaped, and only picks up meaningfully faster rotation in roughly the back half of the scroll range. This reads as a flywheel spinning up rather than an object rotating at a constant, unchanging rate the entire time, which would look mechanical rather than physical.

Each city marker's InstancedMesh transform (rotation and scale) is set to directly copy the globe mesh's own rotation and scale every frame, after the marker's local position is already placed on the unit-sphere surface. This means the markers automatically inherit the same flattening and spin as the globe without any separate per-marker flattening math.

Each city index computes its own litThreshold as 0.15 + (index / CITY_COUNT) * 0.75, spreading thresholds across most of the scroll range. A marker only renders at visible scale once the live eased progress exceeds its own threshold, so cities light up in a staggered, spread-out sequence rather than all popping in simultaneously at one point in the scroll.

Yes. Click JSX for a React component, Vue for a Vue 3 SFC, Angular for a standalone component, or Tailwind for a React + Tailwind version. Build the globe geometry, city InstancedMesh, and GSAP ScrollTrigger inside a mount effect keyed to a canvas ref, and on unmount kill the ScrollTrigger instance, dispose geometries/materials, and call renderer.dispose().