In an HTML canvas, a bunch of floating particles connected with lines when they approach each other. Creating a fun and interactive background. Colors, interaction and gravity can be customized!
Showcase
Import
Implementation
Class Instantiation
Options
Manually creating particles
One Pager Example
If you dont like reading documentation this website is for you:
https://khoeckman.github.io/canvasparticles-js/
Particles will be drawn onto a <canvas> element.
<canvas id="my-canvas"></canvas>npm install canvasparticles-js
# or
pnpm add canvasparticles-jsES Module import
import CanvasParticles from 'canvasparticles-js'If you don't have a bundler:
import CanvasParticles from './node_modules/canvasparticles-js/dist/index.mjs'Global import
<script src="./node_modules/canvasparticles-js/dist/index.umd.js" defer></script>No import required in each JavaScript file!
ES Module import
import CanvasParticles from 'https://cdn.jsdelivr.net/npm/canvasparticles-js/dist/index.min.mjs'Global import
<script src="https://cdn.jsdelivr.net/npm/canvasparticles-js/dist/index.umd.min.js" defer></script>const selector = '#my-canvas' // Query Selector for the canvas
const options = { ... } // See #options
new CanvasParticles(selector, options).start()const particles = new CanvasParticles(selector, options)
particles.start()
particles.stop()To keep the last frame visible when stopping the animation:
particles.stop({ clear: false }) // Default: trueGracefully destroy the instance and remove the canvas element.
particles.destroy()
delete particles // Optionalconst selector = '#my-canvas'
const options = {}
const canvasElement = document.querySelector(selector)
let instance, canvas
// Basic instantiation
instance = new CanvasParticles(selector)
instance = new CanvasParticles(canvasElement)
// Instantiation with custom options
instance = new CanvasParticles(selector, options)
instance = new CanvasParticles(canvasElement, options)You can chain .start() for a cleaner syntax:
instance = new CanvasParticles(selector).start()
// Access the canvas directly
canvas = new CanvasParticles(selector).canvas
canvas = new CanvasParticles(selector).start().canvasIf you prefer not to chain methods, you can instantiate first and start later:
instance = new CanvasParticles(selector)
instance.start()
canvas = instance.canvasThe following will not return the expected value because CanvasParticles only supports method chaining for .start():
instance = new CanvasParticles(selector).anyOtherMethod()
canvas = new CanvasParticles(selector).anyOtherMethod().canvasOptions to change the particles and their behavior aswell as what happens on MouseMove or Resize events.
Play around with these values in the Sandbox.
The default value will be used when an option is assigned an invalid value.
TypeScript Usage:
Both float and integer mean number.
integer is used to specify that the number is internally floored to a whole number.
| Option | Type | Default | Description |
|---|---|---|---|
background |
string | false |
false |
Canvas background. Any valid CSS background value. Ignored when strictly false. |
It's best to not touch these values if it's unclear what it does.
| Option | Type | Default | Description |
|---|---|---|---|
animation.startOnEnter |
boolean |
true |
Start animation when the canvas enters the viewport. |
animation.stopOnLeave |
boolean |
true |
Stop animation when the canvas leaves the viewport. |
| Option | Type | Default | Description |
|---|---|---|---|
mouse.interactionType |
0 | 1 | 2 |
2 |
Mouse interaction mode.0 = NONE, 1 = SHIFT, 2 = MOVE. |
mouse.connectDistMult |
float |
2/3 |
Multiplier applied to particles.connectDistance to compute mouse interaction distance. |
mouse.distRatio |
float |
2/3 |
Controls how strongly particles are pulled toward the mouse. Keep equal to or above mouse.connectDistMult. |
Interaction types (enum)
NONE (0)– No interactionSHIFT (1)– Visual displacement onlyMOVE (2)– Actual particle movement (default)
| Option | Type | Default | Description |
|---|---|---|---|
particles.generationType |
0 | 1 | 2 |
false |
Auto-generate particles on initialization and when the canvas resizes. 1 = OFF, 2 = MATCH |
particles.color |
string |
'black' |
Particle and connection color. Any CSS color format. |
particles.ppm |
integer |
100 |
Particles per million pixels. |
particles.max |
integer |
Infinity |
Maximum number of particles allowed. |
particles.maxWork |
integer |
Infinity |
Maximum total connection length per particle. Lower values stabilize performance but may flicker. |
particles.connectDistance |
integer |
150 |
Maximum distance for particle connections (px). |
particles.relSpeed |
float |
1 |
Relative particle speed multiplier. |
particles.relSize |
float |
1 |
Relative particle size multiplier. |
particles.rotationSpeed |
float |
2 |
Direction change speed. |
particles.drawLines |
boolean |
true |
Whether to draw lines between particles. |
Generation types (enum)
OFF (0)– Never auto-generate particlesNEW (1)– Generate all particles from scratchMATCH (2)– Add or remove some particles to match the new count (default)
Enabling gravity (repulsive or pulling > 0) performs an extra O(n²) gravity computations per frame.
| Option | Type | Default | Description |
|---|---|---|---|
gravity.repulsive |
float |
0 |
Repulsive force between particles. |
gravity.pulling |
float |
0 |
Attractive force between particles. Requires sufficient repulsion to avoid clustering. |
gravity.friction |
float |
0.8 |
Damping factor applied to gravitational velocity each update (0.0 – 1.0). |
gravity.maxVelocity |
float |
Infinity |
Clamp the velocity of each particle to this value to prevent explosions under heavy pulling gravity. |
Intended for development and debugging. Can be useful to understand internal behavior.
| Option | Type | Default | Description |
|---|---|---|---|
debug.drawGrid |
boolean |
false |
Renders the spatial grid used for partitioning. |
debug.drawIndexes |
boolean |
false |
Displays particle indices on the canvas. |
You can update every option while an instance is animating and it works great; but some options require an extra step.
These options are the only ones that have and require a dedicated setter to ensure proper integration:
backgroundmouse.connectDistMultparticles.color
const instance = new CanvasParticles(selector, options)
// Use the setters to update these specific options
instance.setBackground('red')
instance.setMouseConnectDistMult(0.8)
instance.setParticleColor('hsl(149, 100%, 50%)')After updating the following options, the number of particles is not automatically adjusted:
particles.ppmparticles.max
// Note: the backing field is called `option` not `options`!
instance.option.particles.ppm = 100
instance.option.particles.max = 300The changes are only applied when one of the following methods is called:
instance.newParticles() // Remove all particles and create the correct amount of new ones
instance.matchParticleCount() // Add or remove some particles to match the countAfter updating the following options, the particles are not automatically updated:
particles.relSizeparticles.relSpeed
// Note: the backing field is called `option` not `options`!
instance.option.particles.relSize = 2
instance.option.particles.relSpeed = 3The changes are only applied when the following method is called:
instance.updateParticles() // Updates the particle.speed and particle.size properties without regenerating any particlesAll other options can be updated by only modifying the option internal field properties, with changes taking effect immediately.
The new option values are not validated. Assigning invalid values will lead to unexpected behavior. It is therefore recommended to use the options setter.
// Note: the backing field is called `option` not `options`!
instance.option.mouse.interactionType = 0
instance.option.particles.connectDist = 200
instance.option.gravity.repulsive = 1To reinitialize all options, pass a new options object to the options setter.
Existing particles their properties will not be updated automatically. Changing particle properties
instance.options = { ... }createParticle(posX?: number, posY?: number, dir?: number, speed?: number, size?: number)By default particles.ppm and particles.max are used to auto-generate random particles. To turn this off, set at least one of these properties to 0 or set particles.generationType to OFF (0) (slightly more efficient).
const canvas = '#my-canvas'
const options = {
particles: {
generationType: CanvasParticles.generationType.OFF, // = 0
rotationSpeed: 0,
},
}
const instance = new CanvasParticles(canvas, options).start()
// Create a horizontal line of particles moving down
for (let x = 0; x < instance.width; x += 4) {
instance.createParticle(x, 100, 0, 1, 5)
}
// Keep automatically generated particles and remove manually created ones
instance.newParticles({ keepAuto: true, keepManual: false })<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
#canvas-particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
</style>
</head>
<body>
<canvas id="canvas-particles"></canvas>
<script src="https://cdn.jsdelivr.net/npm/canvasparticles-js/dist/index.umd.js"></script>
<script>
const selector = '#canvas-particles'
const options = {
background: 'hsl(125, 42%, 35%)',
mouse: {
interactionType: CanvasParticles.interactionType.SHIFT, // = 1
},
particles: {
color: 'rgba(150, 255, 105, 0.95)',
max: 200,
},
}
new CanvasParticles(selector, options).start()
</script>
</body>
</html>