Particle Dissolve
Grind the frame into drifting grey dust and let the next scene coalesce back out of it
This transition post-processes the real pixels of both scenes through the experimental html-in-canvas browser API. The preview above shows the true effect in Chrome 149+ with chrome://flags/#canvas-draw-element enabled (nested canvases need 152.0.7944.0+). Every other browser — Safari, Firefox, Chrome without the flag — falls back to a CSS approximation of the same cut, so the page and your video still play.
Rendering is supported through the CLI, Studio, Lambda and SSR with --gl=angle, or --gl=swangle on a machine without a GPU. Chrome may change or discontinue the API; the CSS fallback is what keeps your composition renderable if that happens.
Installation
$ pnpm dlx shadcn@latest add @remocn/particle-dissolveUsage
particleDissolve() is a Remotion transition presentation. Pass it to a
TransitionSeries.Transition between two sequences. The frame is ground into
fine dust: each speck wanders away from the pixel it came from, colour drains
out of it as it goes, and the specks shimmer while they hang in the air. Then
the motion reverses — the dust gathers, colour returns, and it settles into the
next scene.
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { particleDissolve } from "@/components/remocn/particle-dissolve";
export const MyVideo = () => (
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60}>
<SceneA />
</TransitionSeries.Sequence>
<TransitionSeries.Transition
timing={linearTiming({ durationInFrames: 36 })}
presentation={particleDissolve()}
/>
<TransitionSeries.Sequence durationInFrames={60}>
<SceneB />
</TransitionSeries.Sequence>
</TransitionSeries>
);Why this one needs the canvas
- Bright content throws its dust furthest. How far a speck wanders is set by the luminance of the pixel it came from, so highlights and text disintegrate before flat background does. The scatter field is a function of the picture.
- Every speck carries a real fragment. It samples the scene at the coordinate it drifted in from, not an average of what sits beneath it.
- The dust separates colour. Red and blue are sampled at slightly different offsets while a speck is airborne, so the grain fringes as it flies and resolves clean as it lands.
- Motes catch the light. Each speck has its own size and its own brightness, twinkling on its own phase, and the material thins between them. This is what makes the effect work on flat areas: displacing a uniform colour returns the same colour, so without light of their own the specks would be invisible everywhere except over content, and only the text would appear to dissolve.
None of that survives a mask: a CSS version could only fade a grid of squares tinted by whatever is underneath them.
The entrance mirrors the exit
There is one continuous arc per speck rather than two effects bolted together: dust rises to a peak and falls away again, and the scene swap happens at the peak where the frame is least legible. Played backwards it reads as the same effect applied to the other scene — the incoming frame is assembled out of the same dust that the outgoing one became.
direction sets the order the arc sweeps in. "reveal" starts at the centre
and travels outward, so the next scene surfaces in the middle and grows;
an axis sweeps the dust across the frame instead.
Determinism
Each speck's heading, wander distance, shimmer phase, and stagger are seeded from its cell coordinate and evaluated as closed-form functions of the transition's progress — no per-frame simulation, no wall-clock time, nothing carried between frames. The same frame renders identically in every chunk of a parallel render.
Fallback
Where html-in-canvas is unavailable the presentation renders a desaturating blur crossfade — the picture loses colour and definition on the way out and recovers both on the way in, which is the shape of the effect without the grain. The dust needs the outgoing scene's pixels, so none of the props apply there.
Props
particleDissolve(props) accepts:
| Prop | Type | Default | Description |
|---|---|---|---|
particleSize | number | 4 | Grain size in pixels, measured against the composition height. Small values give true dust; above roughly 10 the frame reads as breaking into tiles instead. |
scatter | number | 0.08 | How far a speck can wander from home, as a fraction of the frame, before luminance scaling. Higher values throw the picture further apart at the peak. |
shimmer | number | 0.6 | How much the specks jitter and catch the light while airborne. This is what carries the effect over flat areas of the frame, where displacement alone shows nothing — turn it down over busy footage, up over plain backgrounds. 0 leaves a still, dark scatter. |
aberration | number | 0.5 | Colour separation on a speck in flight. 0 keeps the grain neutral; higher values fringe it red and blue at the peak of the dissolve. |
direction | "reveal" | "up" | "down" | "left" | "right" | "reveal" | The order the dissolve sweeps in. "reveal" runs outward from the centre; an axis sweeps the arc across the frame from that edge. |
stagger | number | 0.55 | How far apart specks start their arc, as a share of the transition. 0 dissolves the whole frame as one plane; high values leave a long tail of stragglers still airborne. |