webdevpuneet.com

Three.js Scroll Particle Assembly — GSAP Effect

Three.js Scroll Particle Assembly · Scroll · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<section class="pas-top"><p>Scroll ↓ to assemble</p></section>
<section class="pas-stage" id="pasStage">
  <canvas id="pasCanvas"></canvas>
  <h2 class="pas-label" id="pasLabel">Scattered</h2>
</section>
<section class="pas-bottom"><p>Every point found its place.</p></section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Two pre-computed positions per particle (scattered + target) blended by a single scrubbed 0–1 value
Fibonacci-sphere target distribution via the golden angle for an even, un-clumped assembled shape
Smooth-step easing (p*p*(3-2p)) so particles settle into place instead of crossing at a constant rate
Single Float32Array BufferAttribute rewritten in place — one geometry upload per frame at any count
Additive blending with depthWrite off for a glowing, artifact-free transparent point cloud
Per-particle color set once from height, never recomputed, keeping per-frame work to position math
Live status caption driven by ScrollTrigger onUpdate self.progress
Fully reversible and pinned — scrolling back up dissolves the sphere with no extra code

About this UI Snippet

How to Build a Scroll-Driven Particle Assembly Effect With Three.js and GSAP

Screenshot of the Three.js Scroll Particle Assembly snippet rendered live

The Three.js Scroll Particle Assembly snippet starts with a cloud of 2,600 scattered points and pulls each one into an ordered sphere as the visitor scrolls — the scrollbar drives the assembly progress directly, not a timer — using a Three.js Points cloud and GSAP's ScrollTrigger plugin, both loaded from a CDN.

Two positions per particle, blended by one number

The core idea is that every particle carries two pre-computed 3D coordinates: a random "scattered" position in a loose box of noise, and an ordered "target" position on the surface of a sphere. Neither is ever recomputed. Scroll only moves a single value p from 0 to 1, and each frame the live position is a straight linear interpolation between the two stored coordinates. This is dramatically cheaper than physics or per-particle easing, because the expensive random layout is done once at startup and every frame is just addition and multiplication.

A Fibonacci sphere for an even assembled shape

If the target positions were random points on a sphere, the assembled form would look clumpy and uneven. Instead the targets use the golden-angle spiral (a Fibonacci sphere): each particle's Y is stepped evenly from top to bottom and its angle advances by the golden angle of about 2.39963 radians. This spreads the points across the surface with almost no clustering, so the moment of full assembly reads as a clean, deliberate sphere rather than a noisy blob.

Smooth-step so the assembly eases

The raw scrubbed progress is passed through the classic smooth-step curve p * p * (3 - 2p) before it drives the interpolation. This means the particles accelerate out of the scattered state and decelerate into the assembled state, rather than crossing at a constant, mechanical rate. The visitor feels the shape "settling" into place at the end of the scroll, which a linear blend never achieves.

One BufferAttribute updated in place

All 2,600 positions live in a single Float32Array backing a BufferAttribute. Each frame the loop rewrites that array in place and sets needsUpdate = true, so there is exactly one geometry upload per frame regardless of particle count. Colors are set once at startup from each particle's height and never touched again, keeping the per-frame work to position math only.

Additive blending for a glowing cloud

The PointsMaterial uses additive blending with depthWrite disabled, so where particles overlap their colors add toward white and the cloud glows from within. Disabling depth writes prevents the sorting artifacts that otherwise plague large transparent point clouds, and the slight constant Y rotation keeps the shape alive even when the visitor pauses mid-scroll.

scrub: 0.5 and a live status label

A small numeric scrub smooths the assembly against noisy input, and ScrollTrigger's onUpdate callback reads self.progress to swap a caption between "Scattered", "Assembling…", and "Assembled". This same scatter-to-target pattern powers the scroll text grid snippet, which targets a flat grid instead of a sphere. Contrast it with the physically-simulated magnetic particles or pair it with a starfield warp intro.

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 scattered cloud of glowing particles appears in a pinned 3D stage with a status label.
  3. 3
    Scroll downThe particles migrate from their scattered positions into an ordered sphere, tied to scroll.
  4. 4
    Scroll back upThe sphere dissolves back into the cloud exactly, since the progress value is fully scrubbed.
  5. 5
    Change the target shapeReplace the Fibonacci-sphere math in the target loop to assemble a cube, ring, or text layout instead.
  6. 6
    Tune density and paceAdjust COUNT for more or fewer particles and the ScrollTrigger end value for a longer or shorter assembly.

Real-world uses

Common Use Cases

Hero reveals for tech brands
Let a scattered cloud resolve into a logo, planet, or product silhouette as the page loads and scrolls.
Data-story openers
Assemble thousands of points to imply a dataset coming into focus before a chart section begins.
Teaching buffer-geometry animation
A minimal, readable example of interpolating a BufferAttribute in place instead of per-particle tweens.
Loading and intro transitions
Use the assembly as a scroll-gated intro before revealing a horizontal gallery.
Science and space themes
The glowing sphere suits astronomy, biotech, and particle-physics landing pages.
Generative art sections
Swap the target for any parametric surface to assemble bespoke generative forms on scroll.

Got questions?

Frequently Asked Questions

Each particle keeps a fixed scattered coordinate and a fixed target coordinate, both computed once at startup. Scroll only moves one value p, and the live position is a linear blend between the two. This avoids per-particle easing objects or physics entirely, so even thousands of points cost only a little addition and multiplication per frame.

It distributes points on a sphere by stepping Y evenly and rotating each point by the golden angle (~2.39963 radians). Compared with random spherical points, it spreads particles almost uniformly with no visible clumping, so the assembled shape reads as a clean, deliberate sphere at the end of the scroll.

The raw scrubbed progress is linear. Running it through p*p*(3-2p) makes the particles accelerate away from the scattered state and decelerate into the assembled state, so the shape appears to settle into place. A linear blend, by contrast, moves every particle at a constant, mechanical rate the whole way.

All positions share one Float32Array behind a single BufferAttribute. The animation loop rewrites that array in place and flags needsUpdate once, producing exactly one geometry upload per frame no matter how many particles there are. Colors are written once at startup and never recomputed, so per-frame work is limited to position interpolation.

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. Allocate the typed arrays and build the Points cloud and GSAP timeline inside a mount effect against a canvas ref, and on cleanup kill the ScrollTrigger, call geometry.dispose() and renderer.dispose(), so buffers and the WebGL context are freed on unmount.