PointerSmoke
Smoke off the cursor, spreading and thinning as it drifts.
Options
-
paper#fbfaf4 -
css colour
The paper the smoke drifts over.
-
smoke#b4afa4 -
css colour
The body of it, once it has spread. Keep it close to the paper: smoke is the absence of a clear view, not a dark shape, and a strong colour here reads as paint.
-
accent#bfae9e -
css colour
What warmth the freshest smoke carries, at the head of the trail. Only a little of the trail is ever this, so a saturated colour shows up as a bead following the cursor.
-
marks28 -
2 to 28
How many puffs the trail holds. The shader has room for 28; asking for more silently gives you 28, because the array is a fixed size and growing it means editing the shader as well.
-
size0.026 -
0.005 to 0.2
Radius of a fresh puff, as a share of the short side, so it keeps its proportion when the element changes shape.
-
spread2.4 -
0 to 4
How much wider a puff gets by the end of its life. Nothing holds smoke together, so this is the main thing that makes it read as smoke rather than as a cursor with a tail. At 0 you get a row of identical discs.
-
fade2.4 -
0.2 to 6
How quickly a puff gives up. Higher is a shorter trail with a cleaner end; lower leaves a tail that hangs about.
-
edge0.95 -
0 to 1
How much of a puff is its soft shoulder rather than its body. Smoke has no edge at all, so this wants to be near 1; at 0 you get plates of grey.
-
life0.45 -
0.1 to 3
Seconds a puff lasts, which is the length of the trail. This is measured in time rather than in frames, so the same gesture leaves the same trail on a 60Hz display and a 144Hz one. Past about a second the smoke starts to read as something heavy being dragged behind the cursor.
-
grain0.4 -
0 to 1
Paper tooth under the smoke.
What it needs
- Category
- Pointer, an effect
- Dependencies
- None at all
- Browser
- WEBGL2
- Frame budget
- ~1.2 ms · 1 context
- Pinned to
- v0.12.0
- An older puff is wider and fainter than a new one, because nothing holds smoke together. That is the opposite of a particle trail, where older means smaller
- The puffs multiply rather than compositing, so two that overlap are denser than either
- Every puff carries its own age in seconds rather than taking it from its place in the list. The list version worked out to one puff per frame, which left a third of a second of smoke on a 60Hz display and a sixth on a 120Hz one
- A trail needs history, which is not a function of t. When pointerPath is set the whole track is known in advance and the trail is read backwards off it instead of accumulated, so a recorded take is identical however the frames are asked for. A live pointer keeps its own stamps
- One WebGL2 context, one full-screen triangle, no buffers and no attributes
- One distance and one smoothstep per puff per pixel, and the loop stops at the number of puffs actually held
- The puff positions and ages are two array uniforms, uploaded once per frame
- Cost scales with the puff count rather than with how far the cursor has moved