Skip to content

jsem-nerad/DotWave.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Preview screenshot

This is DotWave,

a lightweight JavaScript library for creating interactive and satisfying dot canvases.

Features

  • Parallax effect for depth perception
  • Fully customizable (colors, sizes, behavior...)
  • Custom dot shapes (squares, triangles, stars, your own images or draw functions)
  • Color palettes - dots pick random colors from a list you define
  • Motion presets - dots can flow in a stream or swirl in a vortex on their own
  • Dot stretching
  • Dot rotation smoothing
  • No dependencies
  • Lightweight (~8kB minified)

Importing

The recommended way to import DotWave is via the remote like this:

<script src="https://dotwave.jsem-nerad.cz/src/dotwave.min.js"></script>

Or You can also download it and include it in Your HTML:

<script src="/path/to/dotwave.min.js"></script>

For modifying the library itself, download the non-minified version.

Usage

HTML element

To use DotWave as a HTML element, you will first need to additionally import the dotwave-element.min.js extension for the core dotwave library:

<script src="https://dotwave.jsem-nerad.cz/src/dotwave.min.js"></script>
<script src="https://dotwave.jsem-nerad.cz/src/dotwave-element.min.js"></script> <!-- extension library -->

Then you can use the DotWave element simply like this:

<!-- This code example creates a basic DotWave canvas with the default options -->
<dot-wave></dot-wave>

The DotWave element can be used and customised as every other HTML element. You can use it and style it as as a container for other HTML elements.

/* Styling in CSS */
dot-wave {
  display: flex;
  align-items: center;
  justify-content: center;
}
<!-- Styling directly in the element style -->
<dot-wave style="width: 600px; height: 400px; border: 3px solid #33a6ed;">
  <!-- Using as a container for paragraph element -->
  <p style="color: #33a6ed;">This is DotWave element as a container with custom CSS.</p>
</dot-wave>

Configuring DotWave attributes

To configure the DotWave element, use the element attributes.

<dot-wave 
  num-dots="200" 
  dot-color="#FF0000" 
  background-color="#FFFFFF"
  influence-radius="150"
  dot-stretch="true"
  dot-stretch-mult="5"
  style="height: 500px;">
</dot-wave>

You can find the list of all available attributes here.

Configuring the DotWave element via JavaScript

In addition to the HTML element, you can still control the DotWave object using JavaScript including using functions and updating options

// Get reference to the element
const dotWaveElement = document.querySelector('dot-wave');

// Update properties via JavaScript
dotWaveElement.numDots = 500;
dotWaveElement.dotColor = '#00FF00';
dotWaveElement.reactive = false;

// Control animation
dotWaveElement.pause();
dotWaveElement.resume();

// Access the underlying DotWave instance for advanced control
const dotwave = dotWaveElement.getDotWaveInstance();
if (dotwave) {
  // Use any original DotWave methods
  dotwave.updateOptions({ friction: 0.95 });
}

// Clean up when done
dotWaveElement.destroy();

The DotWave element also supports dynamic creation in JavaScript

// Create element dynamically
const dotWave = document.createElement('dot-wave');
dotWave.setAttribute('num-dots', '300');
dotWave.setAttribute('dot-color', '#FF00FF');
dotWave.style.width = '100%';
dotWave.style.height = '500px';

document.body.appendChild(dotWave);

JavaScript library

<div id="dotwave-container" style="height: 400px;"></div>

<script src="https://dotwave.jsem-nerad.cz/src/dotwave.min.js"></script>
<script>
  // Creating a new DotWave instance with custom configuration
  const dotwave = new DotWave({container: '#dotwave-container'});
</script>

If you want to put your script tags at the top of Your HTML with the defer property, make sure to also do the same to the script containing the DotWave customization, otherwise it won't work.

Configuration Options

To configure DotWave when initializing, use the class options.

<script>
  // Creating a new DotWave instance with custom configuration
  const dotwave = new DotWave({
      container: '#dotwave-container', 
      numDots: 200,
      dotColor: '#FF0000',
      backgroundColor: '#FFFFFF',
      influenceRadius: 150,
      dotStretch: true,
      dotStretchMult: 5,
  });
</script>

You can find the list of all available attributes here.

Dot shapes & images

By default, DotWave draws circles. Use the dotShape option (or the dot-shape attribute) to change that:

Value Result
"circle" The classic dot (default)
"square" Square dots
"triangle" Triangle dots that point in the direction of travel when stretched
"star" Five-pointed stars
"image" Draws the image from the dotImage option instead of a shape
// Star-shaped dots
const dotwave = new DotWave({
  dotShape: 'star',
  dotMinSize: 2,
  dotMaxSize: 6,
});

// Image dots (e.g. snowflakes, logos, sprites...)
const snow = new DotWave({
  dotShape: 'image',
  dotImage: '/images/snowflake.png',
  dotMinSize: 4,
  dotMaxSize: 10,
});
<dot-wave dot-shape="triangle"></dot-wave>
<dot-wave dot-shape="image" dot-image="/images/snowflake.png" dot-min-size="4" dot-max-size="10"></dot-wave>

Some notes on shapes and images:

  • All built-in shapes support dot stretching - they rotate towards their direction of travel and stretch along it, just like circles do.
  • Images keep their aspect ratio and are scaled so their larger side matches the dot diameter. Since the default dot sizes (1-3) are quite small, you will usually want to increase dotMinSize/dotMaxSize for image dots.
  • While the image is loading (or if it fails to load), dots are drawn as regular circles, so the canvas never appears empty.
  • Dot colors do not apply to images - the image keeps its own colors. Per-dot opacity still applies.

Custom shape functions (JavaScript only)

For full control, dotShape also accepts a function that traces a path centered at (0, 0). DotWave handles position, rotation, stretching and filling for you:

const dotwave = new DotWave({
  // A simple diamond shape
  dotShape: function(ctx, radius) {
    ctx.moveTo(0, -radius);
    ctx.lineTo(radius, 0);
    ctx.lineTo(0, radius);
    ctx.lineTo(-radius, 0);
    ctx.closePath();
  },
});

Color palettes

Instead of a single dotColor, you can pass an array of colors with dotColors. Each dot picks one color from the palette at random when it is created:

const dotwave = new DotWave({
  dotColors: ['#33a6ed', '#ed33a6', 'gold', 'rgb(166, 237, 51)'],
});

For the HTML element, use a comma-separated list:

<dot-wave dot-colors="#33a6ed, #ed33a6, gold"></dot-wave>

When dotColors is set (and not empty), it takes precedence over dotColor. Updating dotColor or dotColors via updateOptions() re-rolls the colors of all existing dots without resetting their positions. All CSS color formats supported by dotColor (named, hex, RGB/RGBA) work in the palette too.

Motion presets

By default, dots just wander randomly (and react to your cursor). The motion option gives them a direction of their own:

Value Result
"none" Classic random wandering (default)
"stream" Dots constantly flow in one direction, like a river or snowfall
"vortex" Dots swirl around a configurable center point
// A stream flowing to the bottom-right
const stream = new DotWave({
  motion: 'stream',
  motionAngle: 45,       // Direction in degrees: 0 = right, 90 = down, 180 = left, 270 = up
  motionStrength: 0.1,   // How strong the flow is
});

// A vortex swirling around the center
const vortex = new DotWave({
  motion: 'vortex',
  motionStrength: 0.15,
  motionCenterX: 0.5,    // Center as a fraction of the canvas size (0-1)
  motionCenterY: 0.5,
});
<dot-wave motion="stream" motion-angle="270" motion-strength="0.08"></dot-wave>
<dot-wave motion="vortex" motion-strength="0.15"></dot-wave>

Notes on motion presets:

  • Motion presets combine with everything else: cursor reactivity, random movement, friction and maxSpeed all still apply. For a perfectly uniform stream, set randomFactor: 0.
  • motionStrength is a continuous force, so its visible speed is balanced against friction and capped by maxSpeed.
  • For vortex, a negative motionStrength reverses the spin direction.
  • The vortex center is relative to the canvas size, so 0.5/0.5 always stays in the middle, even after resizing. Values outside 0-1 place the center off-canvas, which works too.

Methods

// Initialize
const dotwave = new DotWave(options);

// Pause animation
dotwave.pause();

// Resume animation
dotwave.resume();

// Update options
dotwave.updateOptions({
  dotColor: 'blue',
  numDots: 300
});

// Clean up when done
dotwave.destroy();

Option list

HTML Attribute JavaScript option Type Default Description
- container string body Container selector or DOM element
num-dots numDots number 400 Total number of dots rendered
dot-color dotColor string "white" Dot color; supports named, hex, RGB/RGBa CSS color values
background-color backgroundColor string "black" Canvas fill color; use "transparent" to disable fill
dot-min-size dotMinSize number 1 Minimum dot radius
dot-max-size dotMaxSize number 3 Maximum dot radius
dot-min-opacity dotMinOpacity number 0.5 Minimum dot opacity at far depth for fade effect
dot-max-opacity dotMaxOpacity number 1 Maximum dot opacity at near depth for vivid foreground
influence-radius influenceRadius number 100 Cursor effect radius in pixels for interactive push/pull
influence-strength influenceStrength number 0.5 Multiplier for cursor velocity influence on dots
random-factor randomFactor number 0.05 Random dot movement factor
friction friction number 0.97 Dot movement friction to slow dots down
max-speed maxSpeed number 3 Clamp for dot speed after all influences
reactive reactive boolean true Enables/disables cursor reactivity entirely
z-index zIndex number -1 Canvas z-index
mouse-speed-decay mouseSpeedDecay number 0.85 How quickly mouse speed decays
max-mouse-speed maxMouseSpeed number 15 Caps cursor velocity to avoid spikes
dot-stretch dotStretch: true boolean true When enabled, dots stretch when moving
dot-stretch-mult dotStretchMult number 10 How much to stretch dots
dot-max-stretch dotMaxStretch number 20 Maximum stretch amount
rot-smoothing rotSmoothing boolean false Smoothly rotates dots instead of snapping
rotsmoothingintensity rotSmoothingIntensity number 150 Rotation smoothing duration (ms)
dot-shape dotShape string "circle" Dot shape: "circle", "square", "triangle", "star", "image"; JS also accepts a custom draw function
dot-image dotImage string null Image URL used when dotShape is "image"
dot-colors dotColors array null Color palette; each dot picks one at random (overrides dotColor). HTML: comma-separated list
motion motion string "none" Autonomous motion preset: "none", "stream" or "vortex"
motion-angle motionAngle number 0 Stream direction in degrees (0 = right, 90 = down)
motion-strength motionStrength number 0.05 Strength of the motion preset force
motion-center-x motionCenterX number 0.5 Vortex center X as a fraction of canvas width (0-1)
motion-center-y motionCenterY number 0.5 Vortex center Y as a fraction of canvas height (0-1)

For HTML

<dot-wave 
  num-dots="400"
  dot-color="white"
  background-color="black"
  dot-min-size="1"
  dot-max-size="3"
  dot-min-opacity="0.5"
  dot-max-opacity="1"
  influence-radius="100"
  influence-strength="0.5"
  random-factor="0.05"
  friction="0.97"
  max-speed="3"
  reactive="true"
  z-index="-1"
  mouse-speed-decay="0.85"
  max-mouse-speed="15"
  dot-stretch="true"
  dot-stretch-mult="10"
  dot-max-stretch="20"
  rot-smoothing="false"
  rot-smoothing-intensity="150"
  dot-shape="circle"
  dot-image=""
  dot-colors=""
  motion="none"
  motion-angle="0"
  motion-strength="0.05"
  motion-center-x="0.5"
  motion-center-y="0.5">
</dot-wave>

For JavaScript

const dotwave = new DotWave({
  container: 'body',           // Container selector or DOM element
  numDots: 400,                // Number of dots
  dotColor: 'white',           // Dot color (CSS color)
  backgroundColor: 'black',    // Background color
  dotMinSize: 1,               // Minimum dot size
  dotMaxSize: 3,               // Maximum dot size
  dotMinOpacity: 0.5,          // Minimum dot opacity
  dotMaxOpacity: 1,            // Maximum dot opacity
  influenceRadius: 100,        // Mouse influence radius
  influenceStrength: 0.5,      // Mouse influence strength
  randomFactor: 0.05,          // Random movement factor
  friction: 0.97,              // Movement friction
  maxSpeed: 3,                 // Maximum dot speed
  reactive: true,              // Toggle for cursor reactivity
  zIndex: -1,                  // Canvas z-index
  mouseSpeedDecay: 0.85,       // How quickly mouse speed decays
  maxMouseSpeed: 15,           // Maximum mouse speed to prevent jumps
  dotStretch: true,            // Enable dot stretching based on velocity
  dotStretchMult: 10,          // How much to stretch the dots
  dotMaxStretch: 20,           // Maximum stretch amount
  rotSmoothing: false,         // Toggle for rotation smoothing of dots
  rotSmoothingIntensity: 150,  // Rotation smoothing duration in milliseconds
  dotShape: 'circle',          // Dot shape: 'circle', 'square', 'triangle', 'star', 'image' or a custom draw function
  dotImage: null,              // Image URL used when dotShape is 'image'
  dotColors: null,             // Array of colors; each dot picks one at random (overrides dotColor)
  motion: 'none',              // Autonomous motion preset: 'none', 'stream' or 'vortex'
  motionAngle: 0,              // Stream direction in degrees (0 = right, 90 = down)
  motionStrength: 0.05,        // Strength of the motion preset force
  motionCenterX: 0.5,          // Vortex center X as a fraction of canvas width (0-1)
  motionCenterY: 0.5           // Vortex center Y as a fraction of canvas height (0-1)
});

Note, that rotSmoothing: false skips the rotation lerping calculations and is therefore more performant than using rotSmoothingIntensity: 0, same logic applies to dotStretch.

This is still WIP!

Currently, DotWave targets 100 FPS and adjusts to the client frame rate using delta time for smooth motion scaling. Lower frame rates should work.

Contributing

Contributions are welcome! Please feel free to submit a pull request or an issue. Feature requests are also welcome!

AI usage declaration

Some parts of the code for this project were generated by an LLM to save time

About

A JavaScript library for making cool star effect reacting to mouse cursor

Topics

Resources

License

Stars

Watchers

Forks

Contributors