Skip to content

Commit 996199a

Browse files
authored
Merge pull request #14 from panlukynek/claude/relaxed-faraday-ciyz2d
Add custom dot shapes/images, motion presets and color palettes
2 parents 2a7c2e2 + 48e8a7e commit 996199a

4 files changed

Lines changed: 582 additions & 69 deletions

File tree

README.md

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
- Parallax effect for depth perception
1616
- Fully customizable (colors, sizes, behavior...)
17+
- Custom dot shapes (squares, triangles, stars, your own images or draw functions)
18+
- Color palettes - dots pick random colors from a list you define
19+
- Motion presets - dots can flow in a stream or swirl in a vortex on their own
1720
- Dot stretching
1821
- Dot rotation smoothing
1922
- No dependencies
@@ -161,6 +164,121 @@ To configure DotWave when initializing, use the class options.
161164

162165
You can find the [list of all available attributes here](#option-list).
163166

167+
# Dot shapes & images
168+
169+
By default, DotWave draws circles. Use the `dotShape` option (or the `dot-shape` attribute) to change that:
170+
171+
| Value | Result |
172+
|--------------|-------------------------------------------------------------------|
173+
| `"circle"` | The classic dot (default) |
174+
| `"square"` | Square dots |
175+
| `"triangle"` | Triangle dots that point in the direction of travel when stretched |
176+
| `"star"` | Five-pointed stars |
177+
| `"image"` | Draws the image from the `dotImage` option instead of a shape |
178+
179+
```JavaScript
180+
// Star-shaped dots
181+
const dotwave = new DotWave({
182+
dotShape: 'star',
183+
dotMinSize: 2,
184+
dotMaxSize: 6,
185+
});
186+
187+
// Image dots (e.g. snowflakes, logos, sprites...)
188+
const snow = new DotWave({
189+
dotShape: 'image',
190+
dotImage: '/images/snowflake.png',
191+
dotMinSize: 4,
192+
dotMaxSize: 10,
193+
});
194+
```
195+
196+
```xml
197+
<dot-wave dot-shape="triangle"></dot-wave>
198+
<dot-wave dot-shape="image" dot-image="/images/snowflake.png" dot-min-size="4" dot-max-size="10"></dot-wave>
199+
```
200+
201+
Some notes on shapes and images:
202+
203+
- All built-in shapes support dot stretching - they rotate towards their direction of travel and stretch along it, just like circles do.
204+
- 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.
205+
- While the image is loading (or if it fails to load), dots are drawn as regular circles, so the canvas never appears empty.
206+
- Dot colors do not apply to images - the image keeps its own colors. Per-dot opacity still applies.
207+
208+
### Custom shape functions (JavaScript only)
209+
210+
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:
211+
212+
```JavaScript
213+
const dotwave = new DotWave({
214+
// A simple diamond shape
215+
dotShape: function(ctx, radius) {
216+
ctx.moveTo(0, -radius);
217+
ctx.lineTo(radius, 0);
218+
ctx.lineTo(0, radius);
219+
ctx.lineTo(-radius, 0);
220+
ctx.closePath();
221+
},
222+
});
223+
```
224+
225+
# Color palettes
226+
227+
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:
228+
229+
```JavaScript
230+
const dotwave = new DotWave({
231+
dotColors: ['#33a6ed', '#ed33a6', 'gold', 'rgb(166, 237, 51)'],
232+
});
233+
```
234+
235+
For the HTML element, use a comma-separated list:
236+
237+
```xml
238+
<dot-wave dot-colors="#33a6ed, #ed33a6, gold"></dot-wave>
239+
```
240+
241+
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.
242+
243+
# Motion presets
244+
245+
By default, dots just wander randomly (and react to your cursor). The `motion` option gives them a direction of their own:
246+
247+
| Value | Result |
248+
|------------|--------------------------------------------------------------|
249+
| `"none"` | Classic random wandering (default) |
250+
| `"stream"` | Dots constantly flow in one direction, like a river or snowfall |
251+
| `"vortex"` | Dots swirl around a configurable center point |
252+
253+
```JavaScript
254+
// A stream flowing to the bottom-right
255+
const stream = new DotWave({
256+
motion: 'stream',
257+
motionAngle: 45, // Direction in degrees: 0 = right, 90 = down, 180 = left, 270 = up
258+
motionStrength: 0.1, // How strong the flow is
259+
});
260+
261+
// A vortex swirling around the center
262+
const vortex = new DotWave({
263+
motion: 'vortex',
264+
motionStrength: 0.15,
265+
motionCenterX: 0.5, // Center as a fraction of the canvas size (0-1)
266+
motionCenterY: 0.5,
267+
});
268+
```
269+
270+
```xml
271+
<dot-wave motion="stream" motion-angle="270" motion-strength="0.08"></dot-wave>
272+
<dot-wave motion="vortex" motion-strength="0.15"></dot-wave>
273+
```
274+
275+
Notes on motion presets:
276+
277+
- Motion presets combine with everything else: cursor reactivity, random movement, friction and `maxSpeed` all still apply. For a perfectly uniform stream, set `randomFactor: 0`.
278+
- `motionStrength` is a continuous force, so its visible speed is balanced against `friction` and capped by `maxSpeed`.
279+
- For `vortex`, a negative `motionStrength` reverses the spin direction.
280+
- 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.
281+
164282
# Methods
165283

166284
```JavaScript
@@ -209,6 +327,14 @@ dotwave.destroy();
209327
| dot-max-stretch | dotMaxStretch | number | 20 | Maximum stretch amount |
210328
| rot-smoothing | rotSmoothing | boolean | false | Smoothly rotates dots instead of snapping |
211329
| rotsmoothingintensity | rotSmoothingIntensity | number | 150 | Rotation smoothing duration (ms) |
330+
| dot-shape | dotShape | string | "circle" | Dot shape: "circle", "square", "triangle", "star", "image"; JS also accepts a custom draw function |
331+
| dot-image | dotImage | string | null | Image URL used when dotShape is "image" |
332+
| dot-colors | dotColors | array | null | Color palette; each dot picks one at random (overrides dotColor). HTML: comma-separated list |
333+
| motion | motion | string | "none" | Autonomous motion preset: "none", "stream" or "vortex" |
334+
| motion-angle | motionAngle | number | 0 | Stream direction in degrees (0 = right, 90 = down) |
335+
| motion-strength | motionStrength | number | 0.05 | Strength of the motion preset force |
336+
| motion-center-x | motionCenterX | number | 0.5 | Vortex center X as a fraction of canvas width (0-1) |
337+
| motion-center-y | motionCenterY | number | 0.5 | Vortex center Y as a fraction of canvas height (0-1) |
212338

213339
## For HTML
214340

@@ -234,7 +360,15 @@ dotwave.destroy();
234360
dot-stretch-mult="10"
235361
dot-max-stretch="20"
236362
rot-smoothing="false"
237-
rot-smoothing-intensity="150">
363+
rot-smoothing-intensity="150"
364+
dot-shape="circle"
365+
dot-image=""
366+
dot-colors=""
367+
motion="none"
368+
motion-angle="0"
369+
motion-strength="0.05"
370+
motion-center-x="0.5"
371+
motion-center-y="0.5">
238372
</dot-wave>
239373
```
240374

@@ -263,7 +397,15 @@ const dotwave = new DotWave({
263397
dotStretchMult: 10, // How much to stretch the dots
264398
dotMaxStretch: 20, // Maximum stretch amount
265399
rotSmoothing: false, // Toggle for rotation smoothing of dots
266-
rotSmoothingIntensity: 150 // Rotation smoothing duration in milliseconds
400+
rotSmoothingIntensity: 150, // Rotation smoothing duration in milliseconds
401+
dotShape: 'circle', // Dot shape: 'circle', 'square', 'triangle', 'star', 'image' or a custom draw function
402+
dotImage: null, // Image URL used when dotShape is 'image'
403+
dotColors: null, // Array of colors; each dot picks one at random (overrides dotColor)
404+
motion: 'none', // Autonomous motion preset: 'none', 'stream' or 'vortex'
405+
motionAngle: 0, // Stream direction in degrees (0 = right, 90 = down)
406+
motionStrength: 0.05, // Strength of the motion preset force
407+
motionCenterX: 0.5, // Vortex center X as a fraction of canvas width (0-1)
408+
motionCenterY: 0.5 // Vortex center Y as a fraction of canvas height (0-1)
267409
});
268410
```
269411
> *Note, that `rotSmoothing: false` skips the rotation lerping calculations and is therefore more performant than using `rotSmoothingIntensity: 0`, same logic applies to `dotStretch`.*

examples/dotwave-new-features.html

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>DotWave Shapes, Motion & Color Palettes Example</title>
6+
7+
<style>
8+
body {
9+
margin: 0;
10+
font-family: 'Courier New', Courier, monospace;
11+
}
12+
13+
.demo {
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
height: 350px;
18+
}
19+
20+
.demo h2 {
21+
color: white;
22+
text-shadow: 0 0 8px black;
23+
}
24+
</style>
25+
</head>
26+
27+
<body>
28+
<!-- Star-shaped dots with a color palette -->
29+
<div id="demo-stars" class="demo">
30+
<h2>Stars with a color palette</h2>
31+
</div>
32+
33+
<!-- Stream motion: dots flow to the right on their own -->
34+
<div id="demo-stream" class="demo">
35+
<h2>Stream motion</h2>
36+
</div>
37+
38+
<!-- Vortex motion: dots swirl around the center -->
39+
<div id="demo-vortex" class="demo">
40+
<h2>Vortex motion</h2>
41+
</div>
42+
43+
<!-- DotWave element with the new attributes -->
44+
<dot-wave
45+
class="demo"
46+
dot-shape="triangle"
47+
dot-colors="#33a6ed, #ed33a6, #a6ed33"
48+
motion="stream"
49+
motion-angle="270"
50+
motion-strength="0.08">
51+
<h2>&lt;dot-wave&gt; element with triangles streaming upwards</h2>
52+
</dot-wave>
53+
54+
<script src="/src/dotwave.js"></script>
55+
<script src="/src/dotwave-element.js"></script>
56+
<script>
57+
// Star-shaped dots, each picking a random color from the palette
58+
new DotWave({
59+
container: '#demo-stars',
60+
dotShape: 'star',
61+
dotColors: ['#ffd700', '#ff6b6b', '#4ecdc4', '#c44dff'],
62+
dotMinSize: 2,
63+
dotMaxSize: 6,
64+
dotStretch: false,
65+
});
66+
67+
// Stream: a constant flow to the right (0 degrees)
68+
new DotWave({
69+
container: '#demo-stream',
70+
motion: 'stream',
71+
motionAngle: 0,
72+
motionStrength: 0.1,
73+
dotColors: ['#33a6ed', '#1c6fa3', '#7fc8f0'],
74+
});
75+
76+
// Vortex: dots swirl around the center of the container
77+
new DotWave({
78+
container: '#demo-vortex',
79+
motion: 'vortex',
80+
motionStrength: 0.15,
81+
motionCenterX: 0.5,
82+
motionCenterY: 0.5,
83+
dotColors: ['#ff9f43', '#ee5253', '#feca57'],
84+
});
85+
</script>
86+
</body>
87+
</html>

0 commit comments

Comments
 (0)