@labcat2020/p5.audioreactive 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/package.json +49 -0
- package/patches/p5.sound@0.2.0.patch +11 -0
- package/src/p5.Polar.min.js +3 -0
- package/src/p5.audioReact.js +221 -0
- package/src/p5.colorGenerator.js +205 -0
- package/src/p5.pattern.js +944 -0
- package/src/p5.polygon.js +71 -0
- package/src/p5.randomColor.README.md +95 -0
- package/src/p5.randomColor.js +302 -0
- package/src/p5.setGlobalP5.js +3 -0
- package/src/p5.soundBoot.js +2 -0
- package/src/sacredGeometry.js +198 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
|
|
3
|
+
// p5.polygon.js
|
|
4
|
+
// A polygon drawing library for p5.js
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Helper function to draw any regular polygon
|
|
8
|
+
* @param {Number} x - x-coordinate of the polygon
|
|
9
|
+
* @param {Number} y - y-coordinate of the polygon
|
|
10
|
+
* @param {Number} radius - radius of the polygon
|
|
11
|
+
* @param {Number} sides - number of sides
|
|
12
|
+
* @param {Number} startAngle - starting angle (optional)
|
|
13
|
+
*/
|
|
14
|
+
p5.prototype.polygon = function(x, y, radius, sides, startAngle = 0) {
|
|
15
|
+
this.angleMode(this.RADIANS);
|
|
16
|
+
const angle = this.TWO_PI / sides;
|
|
17
|
+
this.beginShape();
|
|
18
|
+
for (let a = startAngle; a < this.TWO_PI + startAngle; a += angle) {
|
|
19
|
+
let sx = x + this.cos(a) * radius;
|
|
20
|
+
let sy = y + this.sin(a) * radius;
|
|
21
|
+
this.vertex(sx, sy);
|
|
22
|
+
}
|
|
23
|
+
this.endShape(this.CLOSE);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Draw a pentagon shape
|
|
28
|
+
* @param {Number} x - x-coordinate of the pentagon
|
|
29
|
+
* @param {Number} y - y-coordinate of the pentagon
|
|
30
|
+
* @param {Number} width - width of the pentagon
|
|
31
|
+
* @param {Number} height - height of the pentagon (optional, defaults to width)
|
|
32
|
+
*/
|
|
33
|
+
p5.prototype.pentagon = function(x, y, width, height = width) {
|
|
34
|
+
// Fixed: Remove the radius division by 2 since we're already providing the full width/height
|
|
35
|
+
// Fixed: Adjust starting angle to point upward (-PI/2 or -90 degrees)
|
|
36
|
+
const radius = Math.min(width, height) / 2;
|
|
37
|
+
this.polygon(x, y, radius, 5, -this.PI/2);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Draw a hexagon shape
|
|
42
|
+
* @param {Number} x - x-coordinate of the hexagon
|
|
43
|
+
* @param {Number} y - y-coordinate of the hexagon
|
|
44
|
+
* @param {Number} radius - radius of the hexagon
|
|
45
|
+
*/
|
|
46
|
+
p5.prototype.hexagon = function(x, y, radius) {
|
|
47
|
+
// For consistency, also remove the radius division here
|
|
48
|
+
this.polygon(x, y, radius / 2, 6, 0);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Draw an octagon shape
|
|
53
|
+
* @param {Number} x - x-coordinate of the octagon
|
|
54
|
+
* @param {Number} y - y-coordinate of the octagon
|
|
55
|
+
* @param {Number} radius - radius of the octagon
|
|
56
|
+
*/
|
|
57
|
+
p5.prototype.octagon = function(x, y, radius) {
|
|
58
|
+
// For consistency, also remove the radius division here
|
|
59
|
+
this.polygon(x, y, radius / 2, 8, this.TWO_PI / 16);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Draw an equilateral triangle shape
|
|
64
|
+
* @param {Number} x - x-coordinate of the triangle
|
|
65
|
+
* @param {Number} y - y-coordinate of the triangle
|
|
66
|
+
* @param {Number} radius - radius of the triangle
|
|
67
|
+
*/
|
|
68
|
+
p5.prototype.equilateral = function(x, y, radius) {
|
|
69
|
+
// Match the exact same pattern as pentagon, hexagon, and octagon
|
|
70
|
+
this.polygon(x, y, radius / 2, 3, -this.PI/2);
|
|
71
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# p5.randomColor
|
|
2
|
+
|
|
3
|
+
A p5.js library for generating attractive random colors. A p5-aware port of [randomColor](https://randomcolor.lllllllllllllllll.com) by David Merfield (CC0).
|
|
4
|
+
|
|
5
|
+
This library augments `p5.prototype` with a `randomColor()` method that uses p5's RNG and returns a `p5.Color` object.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Include the script in your HTML file after p5.js:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<script src="p5.js"></script>
|
|
13
|
+
<script src="p5.randomColor.js"></script>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Basic Usage
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
function setup() {
|
|
20
|
+
createCanvas(400, 400);
|
|
21
|
+
|
|
22
|
+
// Generate a random attractive color
|
|
23
|
+
let c = randomColor();
|
|
24
|
+
fill(c);
|
|
25
|
+
rect(0, 0, width, height);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Options
|
|
30
|
+
|
|
31
|
+
You can pass an options object to influence the type of color it produces:
|
|
32
|
+
|
|
33
|
+
**`hue`** – Controls the hue of the generated color. You can pass a string representing a color name: `red`, `orange`, `yellow`, `green`, `blue`, `purple`, `pink` and `monochrome` are currently supported.
|
|
34
|
+
|
|
35
|
+
**`luminosity`** – Controls the luminosity of the generated color. You can specify a string containing `bright`, `light`, `dark`, or `random`.
|
|
36
|
+
|
|
37
|
+
**`count`** – An integer which specifies the number of colors to generate. Returns an array of `p5.Color` objects.
|
|
38
|
+
|
|
39
|
+
**`alpha`** – A decimal between 0 and 1. Controls the alpha channel of the generated color.
|
|
40
|
+
|
|
41
|
+
**Note:** This library always returns a `p5.Color` object. There is no `format` option. Seeding is handled by p5's `randomSeed()` function, not through options.
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Returns a random attractive color
|
|
47
|
+
let color = randomColor();
|
|
48
|
+
|
|
49
|
+
// Returns an array of ten green colors
|
|
50
|
+
let greens = randomColor({
|
|
51
|
+
count: 10,
|
|
52
|
+
hue: 'green'
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Returns a light blue color
|
|
56
|
+
let lightBlue = randomColor({
|
|
57
|
+
luminosity: 'light',
|
|
58
|
+
hue: 'blue'
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Returns a bright color
|
|
62
|
+
let bright = randomColor({
|
|
63
|
+
luminosity: 'bright'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Returns a dark color with alpha
|
|
67
|
+
let dark = randomColor({
|
|
68
|
+
luminosity: 'dark',
|
|
69
|
+
alpha: 0.8
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Returns a 'truly random' color
|
|
73
|
+
let random = randomColor({
|
|
74
|
+
luminosity: 'random',
|
|
75
|
+
hue: 'random'
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Using with p5's randomSeed for reproducible results
|
|
79
|
+
function setup() {
|
|
80
|
+
randomSeed(42);
|
|
81
|
+
let color1 = randomColor({ hue: 'blue' });
|
|
82
|
+
|
|
83
|
+
randomSeed(42);
|
|
84
|
+
let color2 = randomColor({ hue: 'blue' });
|
|
85
|
+
// color1 and color2 will be the same
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Differences from vanilla randomColor
|
|
90
|
+
|
|
91
|
+
- Always returns a `p5.Color` object (no hex strings or format options)
|
|
92
|
+
- Uses p5's RNG (use `randomSeed()` for seeding, not a `seed` option)
|
|
93
|
+
- Works seamlessly with p5's color system
|
|
94
|
+
- Only intended for use within p5 sketches
|
|
95
|
+
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview p5.randomColor.js
|
|
5
|
+
* A p5-aware port of randomColor (original by David Merfield, CC0)
|
|
6
|
+
* This module augments p5.prototype with `randomColor(options)` which
|
|
7
|
+
* mirrors the original API but uses p5's RNG and returns a p5.Color.
|
|
8
|
+
*/
|
|
9
|
+
const colorDictionary = {};
|
|
10
|
+
const colorRanges = [];
|
|
11
|
+
|
|
12
|
+
loadColorBounds();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generates a random color using p5's RNG
|
|
16
|
+
* @param {Object} options - Configuration options
|
|
17
|
+
* @param {string|number} [options.hue] - Hue range (color name or 0-360)
|
|
18
|
+
* @param {string} [options.luminosity] - "bright", "light", "dark", or "random"
|
|
19
|
+
* @param {number} [options.alpha] - Alpha value (0-1)
|
|
20
|
+
* @param {number} [options.count] - Number of colors to generate
|
|
21
|
+
* @returns {p5.Color|p5.Color[]} A p5.Color or array of p5.Colors
|
|
22
|
+
*/
|
|
23
|
+
p5.prototype.randomColor = function (options) {
|
|
24
|
+
const p = this;
|
|
25
|
+
options = options || {};
|
|
26
|
+
|
|
27
|
+
function generateOne() {
|
|
28
|
+
const H = pickHueForP(p, options);
|
|
29
|
+
const S = pickSaturation(H, options, p);
|
|
30
|
+
const B = pickBrightness(H, S, options, p);
|
|
31
|
+
return colorFromHSV([H, S, B], options, p);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (options.count !== null && options.count !== undefined) {
|
|
35
|
+
const totalColors = options.count;
|
|
36
|
+
const colors = [];
|
|
37
|
+
for (let i = 0; i < totalColors; i++) colorRanges.push(false);
|
|
38
|
+
const singleOptions = { ...options };
|
|
39
|
+
delete singleOptions.count;
|
|
40
|
+
while (colors.length < totalColors) colors.push(p.randomColor(singleOptions));
|
|
41
|
+
return colors;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return generateOne();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Picks a hue value based on options
|
|
49
|
+
* @param {p5} p - p5 instance
|
|
50
|
+
* @param {Object} options - Options object
|
|
51
|
+
* @returns {number} Hue value (0-360)
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
function pickHueForP(p, options) {
|
|
55
|
+
if (colorRanges.length > 0) {
|
|
56
|
+
let hueRange = getRealHueRange(options.hue);
|
|
57
|
+
let hue = p.random(hueRange[0], hueRange[1]);
|
|
58
|
+
|
|
59
|
+
const step = (hueRange[1] - hueRange[0]) / colorRanges.length;
|
|
60
|
+
let j = parseInt((hue - hueRange[0]) / step);
|
|
61
|
+
|
|
62
|
+
if (colorRanges[j] === true) {
|
|
63
|
+
j = (j + 2) % colorRanges.length;
|
|
64
|
+
} else {
|
|
65
|
+
colorRanges[j] = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const min = (hueRange[0] + j * step) % 359;
|
|
69
|
+
const max = (hueRange[0] + (j + 1) * step) % 359;
|
|
70
|
+
hueRange = [min, max];
|
|
71
|
+
|
|
72
|
+
hue = p.random(hueRange[0], hueRange[1]);
|
|
73
|
+
if (hue < 0) hue = 360 + hue;
|
|
74
|
+
return hue;
|
|
75
|
+
} else {
|
|
76
|
+
const hueRange = getHueRange(options.hue);
|
|
77
|
+
let hue = p.random(hueRange[0], hueRange[1]);
|
|
78
|
+
if (hue < 0) hue = 360 + hue;
|
|
79
|
+
return hue;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Picks a saturation value based on hue and options
|
|
85
|
+
* @param {number} hue - Hue value
|
|
86
|
+
* @param {Object} options - Options object
|
|
87
|
+
* @param {p5} p - p5 instance
|
|
88
|
+
* @returns {number} Saturation value (0-100)
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
function pickSaturation(hue, options, p) {
|
|
92
|
+
if (options && options.hue === "monochrome") return 0;
|
|
93
|
+
if (options && options.luminosity === "random") return p.random(0, 100);
|
|
94
|
+
|
|
95
|
+
const saturationRange = getSaturationRange(hue);
|
|
96
|
+
let sMin = saturationRange[0], sMax = saturationRange[1];
|
|
97
|
+
|
|
98
|
+
switch (options && options.luminosity) {
|
|
99
|
+
case "bright":
|
|
100
|
+
sMin = 55;
|
|
101
|
+
break;
|
|
102
|
+
case "dark":
|
|
103
|
+
sMin = sMax - 10;
|
|
104
|
+
break;
|
|
105
|
+
case "light":
|
|
106
|
+
sMax = 55;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return p.random(sMin, sMax);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Picks a brightness value based on hue, saturation, and options
|
|
115
|
+
* @param {number} H - Hue value
|
|
116
|
+
* @param {number} S - Saturation value
|
|
117
|
+
* @param {Object} options - Options object
|
|
118
|
+
* @param {p5} p - p5 instance
|
|
119
|
+
* @returns {number} Brightness value (0-100)
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
function pickBrightness(H, S, options, p) {
|
|
123
|
+
let bMin = getMinimumBrightness(H, S), bMax = 100;
|
|
124
|
+
switch (options && options.luminosity) {
|
|
125
|
+
case "dark":
|
|
126
|
+
bMax = bMin + 20;
|
|
127
|
+
break;
|
|
128
|
+
case "light":
|
|
129
|
+
bMin = (bMax + bMin) / 2;
|
|
130
|
+
break;
|
|
131
|
+
case "random":
|
|
132
|
+
bMin = 0;
|
|
133
|
+
bMax = 100;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
return p.random(bMin, bMax);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Creates a p5.Color from HSB values
|
|
141
|
+
* @param {number[]} hsv - Array of [H, S, B] values
|
|
142
|
+
* @param {Object} options - Options object
|
|
143
|
+
* @param {p5} p - p5 instance
|
|
144
|
+
* @returns {p5.Color} p5.Color object
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
147
|
+
function colorFromHSV(hsv, options, p) {
|
|
148
|
+
options = options || {};
|
|
149
|
+
const H = hsv[0];
|
|
150
|
+
const S = hsv[1];
|
|
151
|
+
const B = hsv[2];
|
|
152
|
+
const alpha = options.alpha === undefined ? 1 : Math.max(0, Math.min(1, options.alpha));
|
|
153
|
+
p.push();
|
|
154
|
+
p.colorMode(p.HSB, 360, 100, 100, 1);
|
|
155
|
+
const c = p.color(H, S, B, alpha);
|
|
156
|
+
p.pop();
|
|
157
|
+
return c;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Calculates minimum brightness for a given hue and saturation
|
|
162
|
+
* @param {number} H - Hue value
|
|
163
|
+
* @param {number} S - Saturation value
|
|
164
|
+
* @returns {number} Minimum brightness value
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
function getMinimumBrightness(H, S) {
|
|
168
|
+
const lowerBounds = getColorInfo(H).lowerBounds;
|
|
169
|
+
for (let i = 0; i < lowerBounds.length - 1; i++) {
|
|
170
|
+
const s1 = lowerBounds[i][0], v1 = lowerBounds[i][1];
|
|
171
|
+
const s2 = lowerBounds[i + 1][0], v2 = lowerBounds[i + 1][1];
|
|
172
|
+
if (S >= s1 && S <= s2) {
|
|
173
|
+
const m = (v2 - v1) / (s2 - s1), b = v1 - m * s1;
|
|
174
|
+
return m * S + b;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Gets hue range for a color input
|
|
182
|
+
* @param {string|number} colorInput - Color name or hue value
|
|
183
|
+
* @returns {number[]} Array of [min, max] hue range
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
function getHueRange(colorInput) {
|
|
187
|
+
if (!isNaN(parseInt(colorInput))) {
|
|
188
|
+
const number = parseInt(colorInput);
|
|
189
|
+
if (number < 360 && number > 0) return [number, number];
|
|
190
|
+
}
|
|
191
|
+
if (typeof colorInput === "string") {
|
|
192
|
+
if (colorDictionary[colorInput]) {
|
|
193
|
+
const color = colorDictionary[colorInput];
|
|
194
|
+
if (color.hueRange) return color.hueRange;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return [0, 360];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Gets saturation range for a hue value
|
|
202
|
+
* @param {number} hue - Hue value
|
|
203
|
+
* @returns {number[]} Array of [min, max] saturation range
|
|
204
|
+
* @private
|
|
205
|
+
*/
|
|
206
|
+
function getSaturationRange(hue) {
|
|
207
|
+
return getColorInfo(hue).saturationRange;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Gets color information for a hue value
|
|
212
|
+
* @param {number} hue - Hue value
|
|
213
|
+
* @returns {Object} Color info with hueRange, lowerBounds, saturationRange, brightnessRange
|
|
214
|
+
* @private
|
|
215
|
+
*/
|
|
216
|
+
function getColorInfo(hue) {
|
|
217
|
+
if (hue >= 334 && hue <= 360) hue -= 360;
|
|
218
|
+
for (const colorName in colorDictionary) {
|
|
219
|
+
const color = colorDictionary[colorName];
|
|
220
|
+
if (
|
|
221
|
+
color.hueRange &&
|
|
222
|
+
hue >= color.hueRange[0] &&
|
|
223
|
+
hue <= color.hueRange[1]
|
|
224
|
+
) {
|
|
225
|
+
return colorDictionary[colorName];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return { lowerBounds: [[0,0]], saturationRange: [0,100] };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Defines a color in the color dictionary
|
|
233
|
+
* @param {string} name - Color name
|
|
234
|
+
* @param {number[]|null} hueRange - Hue range array or null
|
|
235
|
+
* @param {number[][]} lowerBounds - Array of [saturation, brightness] pairs
|
|
236
|
+
* @private
|
|
237
|
+
*/
|
|
238
|
+
function defineColor(name, hueRange, lowerBounds) {
|
|
239
|
+
const sMin = lowerBounds[0][0], sMax = lowerBounds[lowerBounds.length - 1][0];
|
|
240
|
+
const bMin = lowerBounds[lowerBounds.length - 1][1], bMax = lowerBounds[0][1];
|
|
241
|
+
colorDictionary[name] = {
|
|
242
|
+
hueRange: hueRange,
|
|
243
|
+
lowerBounds: lowerBounds,
|
|
244
|
+
saturationRange: [sMin, sMax],
|
|
245
|
+
brightnessRange: [bMin, bMax],
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Loads color bounds into the color dictionary
|
|
251
|
+
* @private
|
|
252
|
+
*/
|
|
253
|
+
function loadColorBounds() {
|
|
254
|
+
defineColor("monochrome", null, [ [0,0], [100,0] ]);
|
|
255
|
+
|
|
256
|
+
defineColor("red", [-26, 18], [
|
|
257
|
+
[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]
|
|
258
|
+
]);
|
|
259
|
+
|
|
260
|
+
defineColor("orange", [18,46], [
|
|
261
|
+
[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]
|
|
262
|
+
]);
|
|
263
|
+
|
|
264
|
+
defineColor("yellow", [46,62], [
|
|
265
|
+
[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
defineColor("green", [62,178], [
|
|
269
|
+
[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]
|
|
270
|
+
]);
|
|
271
|
+
|
|
272
|
+
defineColor("blue", [178,257], [
|
|
273
|
+
[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]
|
|
274
|
+
]);
|
|
275
|
+
|
|
276
|
+
defineColor("purple", [257,282], [
|
|
277
|
+
[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]
|
|
278
|
+
]);
|
|
279
|
+
|
|
280
|
+
defineColor("pink", [282,334], [
|
|
281
|
+
[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]
|
|
282
|
+
]);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Gets the real hue range when generating multiple colors
|
|
287
|
+
* @param {string|number} colorHue - Color name or hue value
|
|
288
|
+
* @returns {number[]} Array of [min, max] hue range
|
|
289
|
+
* @private
|
|
290
|
+
*/
|
|
291
|
+
function getRealHueRange(colorHue) {
|
|
292
|
+
if (!isNaN(colorHue)) {
|
|
293
|
+
const number = parseInt(colorHue);
|
|
294
|
+
if (number < 360 && number > 0) return getColorInfo(colorHue).hueRange;
|
|
295
|
+
} else if (typeof colorHue === 'string') {
|
|
296
|
+
if (colorDictionary[colorHue]) {
|
|
297
|
+
const color = colorDictionary[colorHue];
|
|
298
|
+
if (color.hueRange) return color.hueRange;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return [0,360];
|
|
302
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
|
|
3
|
+
// Sacred Geometry Library
|
|
4
|
+
// Shared functions for drawing sacred geometry patterns using p5.Polar
|
|
5
|
+
/**
|
|
6
|
+
* Draws the vesica piscis pattern
|
|
7
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
8
|
+
* @param {number} size - Size of the pattern
|
|
9
|
+
*/
|
|
10
|
+
p5.prototype.drawVesicaPiscis = function(currentShapeType, size) {
|
|
11
|
+
if (currentShapeType === 'polarEllipse') {
|
|
12
|
+
this.polarEllipse(0, size, size);
|
|
13
|
+
this.polarEllipse(0, size / 2, size /2);
|
|
14
|
+
this.polarEllipse(0, size / 4 * 3, size / 4 * 3, size / 4);
|
|
15
|
+
this.polarEllipse(0, size / 4 * 3, size / 4 * 3, -size / 4);
|
|
16
|
+
} else {
|
|
17
|
+
this[currentShapeType](0, size);
|
|
18
|
+
this[currentShapeType](0, size / 2);
|
|
19
|
+
this[currentShapeType](0, size / 4 * 3, -size / 4);
|
|
20
|
+
this[currentShapeType](180, size / 4 * 3, -size / 4);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Draws the seed of life pattern
|
|
26
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
27
|
+
* @param {number} size - Size of the pattern
|
|
28
|
+
*/
|
|
29
|
+
p5.prototype.drawSeedOfLife = function(currentShapeType, size) {
|
|
30
|
+
const shapeSize = size / 2;
|
|
31
|
+
if (currentShapeType === 'polarEllipse') {
|
|
32
|
+
this.polarEllipse(0, shapeSize, shapeSize);
|
|
33
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this[currentShapeType](0, shapeSize);
|
|
37
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Draws the egg of life pattern
|
|
43
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
44
|
+
* @param {number} size - Size of the pattern
|
|
45
|
+
*/
|
|
46
|
+
p5.prototype.drawEggOfLife = function(currentShapeType, size) {
|
|
47
|
+
const shapeSize = size / 3;
|
|
48
|
+
if (currentShapeType === 'polarEllipse') {
|
|
49
|
+
this.polarEllipse(0, shapeSize, shapeSize);
|
|
50
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize * 2);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this[currentShapeType](0, shapeSize);
|
|
54
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize * 2);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Draws the flower of life pattern
|
|
60
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
61
|
+
* @param {number} size - Size of the pattern
|
|
62
|
+
*/
|
|
63
|
+
p5.prototype.drawFlowerOfLife = function(currentShapeType, size) {
|
|
64
|
+
const shapeSize = size / 3;
|
|
65
|
+
if (currentShapeType === 'polarEllipse') {
|
|
66
|
+
this.polarEllipse(0, size, size);
|
|
67
|
+
this.polarEllipse(0, shapeSize, shapeSize);
|
|
68
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize);
|
|
69
|
+
this.polarEllipses(12, shapeSize, shapeSize, shapeSize * 2);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this[currentShapeType](0, size);
|
|
73
|
+
this[currentShapeType](0, shapeSize);
|
|
74
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize);
|
|
75
|
+
this[`${currentShapeType}s`](12, shapeSize, shapeSize * 2);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Draws the fruit of life pattern
|
|
81
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
82
|
+
* @param {number} size - Size of the pattern
|
|
83
|
+
*/
|
|
84
|
+
p5.prototype.drawFruitOfLife = function(currentShapeType, size) {
|
|
85
|
+
const shapeSize = size / 5;
|
|
86
|
+
if (currentShapeType === 'polarEllipse') {
|
|
87
|
+
this.polarEllipse(0, shapeSize, shapeSize);
|
|
88
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize * 2);
|
|
89
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize * 4);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this[currentShapeType](0, shapeSize);
|
|
93
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize * 2);
|
|
94
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize * 4);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Draws Metatrons Cube pattern
|
|
100
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
101
|
+
* @param {number} size - Size of the pattern
|
|
102
|
+
*/
|
|
103
|
+
p5.prototype.drawMetatronsCube = function(currentShapeType, size) {
|
|
104
|
+
const shapeSize = size / 5;
|
|
105
|
+
if (currentShapeType === 'polarEllipse') {
|
|
106
|
+
this.polarEllipse(0, shapeSize, shapeSize);
|
|
107
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize * 2);
|
|
108
|
+
this.polarEllipses(6, shapeSize, shapeSize, shapeSize * 4);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this[currentShapeType](0, shapeSize);
|
|
112
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize * 2);
|
|
113
|
+
this[`${currentShapeType}s`](6, shapeSize, shapeSize * 4);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const originalStrokeWeight = this.drawingContext.lineWidth;
|
|
117
|
+
this.strokeWeight(originalStrokeWeight / 4);
|
|
118
|
+
|
|
119
|
+
const linePositions = [];
|
|
120
|
+
for (let i = 0; i < 6; i++) {
|
|
121
|
+
const angle = this.TWO_PI / 6 * i + this.PI / 6;
|
|
122
|
+
linePositions.push({
|
|
123
|
+
x: this.cos(angle) * shapeSize * 2,
|
|
124
|
+
y: this.sin(angle) * shapeSize * 2
|
|
125
|
+
});
|
|
126
|
+
linePositions.push({
|
|
127
|
+
x: this.cos(angle) * shapeSize * 4,
|
|
128
|
+
y: this.sin(angle) * shapeSize * 4
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < linePositions.length; i++) {
|
|
133
|
+
for (let j = i + 1; j < linePositions.length; j++) {
|
|
134
|
+
this.line(linePositions[i].x, linePositions[i].y, linePositions[j].x, linePositions[j].y);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.strokeWeight(originalStrokeWeight);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Draws the tree of life pattern
|
|
142
|
+
* @param {string} currentShapeType - Current shape type being used
|
|
143
|
+
* @param {number} size - Size of the pattern
|
|
144
|
+
*/
|
|
145
|
+
p5.prototype.drawTreeOfLife = function(currentShapeType, size) {
|
|
146
|
+
const shapeSize = size / 2;
|
|
147
|
+
const points = [];
|
|
148
|
+
|
|
149
|
+
for (let i = 0; i < 6; i++) {
|
|
150
|
+
const angle = (i * 60 + 30) * Math.PI / 180;
|
|
151
|
+
const x = Math.cos(angle) * shapeSize;
|
|
152
|
+
const y = Math.sin(angle) * shapeSize - shapeSize;
|
|
153
|
+
points.push({x, y});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < 6; i++) {
|
|
157
|
+
if (i === 0 || i === 2) continue;
|
|
158
|
+
const angle = (i * 60 + 30) * Math.PI / 180;
|
|
159
|
+
const x = Math.cos(angle) * shapeSize;
|
|
160
|
+
const y = Math.sin(angle) * shapeSize + shapeSize;
|
|
161
|
+
points.push({x, y});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
points.push({x: 0, y: shapeSize});
|
|
165
|
+
|
|
166
|
+
points.forEach((point, index) => {
|
|
167
|
+
this.push();
|
|
168
|
+
this.translate(point.x, point.y);
|
|
169
|
+
if (currentShapeType === 'polarEllipse') {
|
|
170
|
+
this.polarEllipse(0, shapeSize / 3, shapeSize / 3);
|
|
171
|
+
} else {
|
|
172
|
+
this[currentShapeType](0, shapeSize / 3);
|
|
173
|
+
}
|
|
174
|
+
this.pop();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const connections = [
|
|
178
|
+
// Top triangle (Supernal Triad)
|
|
179
|
+
[3, 4], [4, 5], [5, 3],
|
|
180
|
+
// Vertical paths from top triangle
|
|
181
|
+
[5, 0], [3, 2],
|
|
182
|
+
// Connections to bottom ring
|
|
183
|
+
[0, 9], [2, 7],
|
|
184
|
+
// Horizontal connections
|
|
185
|
+
[0, 2],
|
|
186
|
+
// Vertical central trunk
|
|
187
|
+
[4, 8], [8, 10], [10, 6],
|
|
188
|
+
// Bottom formation connections
|
|
189
|
+
[7, 8], [8, 9], [9, 10], [10, 7]
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
connections.forEach(([from, to]) => {
|
|
193
|
+
if (points[from] && points[to]) {
|
|
194
|
+
this.line(points[from].x, points[from].y, points[to].x, points[to].y);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
};
|