
Quartz Particles is a JavaScript particle engine that renders textured effects on a WebGL canvas.
It supports multiple emitters, custom particle textures, and controls for movement, size, color, and lifetime.
Features
- Emission rates and particle-count limits for each emitter.
- Random variation in spawn position, speed, and direction.
- Gravity, radial and tangential acceleration, and wave motion.
- Size, rotation, stretch, fade, and RGB color transitions.
- Support for existing canvases and engine-created canvases.
How To Use It
Installation
Import Quartz Particles as an ES module, using the hosted file below or a local copy from the GitHub repository. It imports TWGL 4 from a CDN and uses structuredClone() for default emitter settings.
Basic Usage
Initialize the engine on a canvas and create an emitter. An emitter created with no image URL uses the built-in white-square texture.
<canvas id="particles" width="640" height="360"></canvas>
<script type="module">
import QuartzParticles from "https://cdn.jsdelivr.net/gh/SharkPool-SP/Quartz-Particles/src/lib/quartz-particles.min.js";
const engine = new QuartzParticles();
engine.initializeFromCanvas(document.getElementById("particles"));
engine.createEmitter("spark");
function animate() {
engine.updateEngine();
animationId = requestAnimationFrame(animate);
}
let animationId = requestAnimationFrame(animate);
</script>Let The Engine Create A Canvas
initialize() creates the canvas and accepts its width and height. Append the canvas to the document and use the same emitter and update methods shown above.
const secondEngine = new QuartzParticles();
secondEngine.initialize({ width: 640, height: 360 });
document.body.appendChild(secondEngine.engine.canvas);
secondEngine.createEmitter("second");Customize An Emitter
Change an emitter’s opts to adjust a few settings. Each property uses val for its base value and inf for the random offset applied when a particle spawns.
const options = engine.emitters.get("spark").opts;
options.maxP.val = 120;
options.emission.val = 3;
options.speed = { val: 18, inf: 6 };
options.sCol.val = [255, 190, 60];
options.eCol.val = [255, 40, 30];Use A Custom Particle Texture
Pass an image URL as the third argument. You can also supply { texture, tWidth, tHeight } with a WebGLTexture created in the engine’s WebGL context and numeric texture dimensions. Images on another origin need CORS access.
engine.createEmitter("glow", [100, -40], "/images/glow.png");Emitter Configuration Reference
These are the default emitter settings when you omit the fourth argument to createEmitter().
| Option | Default and purpose |
|---|---|
maxP | { val: 50, inf: 0 }. Particle-count threshold for spawning. An emission batch can exceed it. |
emission | { val: 1, inf: 0 }. Particles emitted per update frame. |
time | { val: 0.4, inf: 0.1 }. Lifetime value, reduced by 0.01 per update when delta is 1. |
speed | { val: 15, inf: 0 }. Initial speed. |
xPos | { val: 10, inf: 0 }. Horizontal spawn offset. |
yPos | { val: 0, inf: 0 }. Vertical spawn offset. |
gravX | { val: 0, inf: 0 }. Horizontal gravity. |
gravY | { val: -1.5, inf: 0 }. Vertical gravity. |
sDir | { val: 0, inf: 25 }. Starting direction in degrees. |
eDir | { val: 0, inf: 0 }. Direction at the end of the lifetime. |
sSpin | { val: 0, inf: 0 }. Starting rotation in degrees. |
eSpin | { val: 45, inf: 135 }. Ending rotation in degrees. |
sSize | { val: 25, inf: 10 }. Starting size as a percentage of texture dimensions. |
eSize | { val: 15, inf: 5 }. Ending size as a percentage of texture dimensions. |
sStreX | { val: 100, inf: 0 }. Starting horizontal stretch, percent. |
eStreX | { val: 100, inf: 0 }. Ending horizontal stretch, percent. |
sStreY | { val: 100, inf: 0 }. Starting vertical stretch, percent. |
eStreY | { val: 100, inf: 0 }. Ending vertical stretch, percent. |
accelRad | { val: 0, inf: 0 }. Radial acceleration. |
accelTan | { val: 0, inf: 0 }. Tangential acceleration. |
sinW | { val: 0, inf: 0 }. Sine-wave displacement strength. |
cosW | { val: 0, inf: 0 }. Cosine-wave displacement strength. |
sinS | { val: 1, inf: 0 }. Sine-wave frequency. |
cosS | { val: 1, inf: 0 }. Cosine-wave frequency. |
fIn | { val: 0, inf: 5 }. Fade-in interval in update ticks. |
fOut | { val: 15, inf: 2 }. Fade-out interval in update ticks. |
sCol | { val: [255, 0, 255], inf: 0 }. Starting RGB color. |
eCol | { val: [0, 0, 255], inf: 0 }. Ending RGB color. |
Engine Initialization And Methods
| Method | Purpose |
|---|---|
new QuartzParticles() | Creates an engine instance. Call an initialization method before creating emitters. |
initialize(scale) | Creates a canvas and initializes rendering. scale supplies width and height. Default: 480 × 360. |
initializeFromCanvas(canvas, optScale) | Initializes rendering on the supplied canvas. Optional optScale sets its width and height. By default, the canvas dimensions are used. |
createEmitter(name, position, texturePath, options) | Creates a named emitter. Position defaults to [0, 0]. Texture accepts an image URL or { texture, tWidth, tHeight }. A supplied options object replaces the defaults and must include every configuration key. |
updateEngine(delta) | Advances and renders a frame. delta is a frame multiplier, default 1. |
resetEngineFlow() | Resets emitter frame counters. Existing particles are retained. |
disposeEmitter(name) | Removes a named emitter and deletes its loaded texture. |
disposeEngine() | Releases engine resources, removes the canvas, and clears the emitters map. |
Cleanup
Stop the animation loop before calling disposeEngine(). It also removes the canvas passed through initializeFromCanvas().
cancelAnimationFrame(animationId); engine.disposeEngine();
Alternatives And Related Resources
- Lightweight JS Library For Creating Interactive Particles – tsparticles
- Create Dynamic Particle Effects with Particulab JavaScript Library
- Canvas Confetti: Custom Confetti Bursts with JavaScript






