git-hash-art 0.0.3 → 0.0.4
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/.release-it.json +1 -1
- package/CHANGELOG.md +9 -0
- package/dist/main.js +260 -155
- package/dist/main.js.map +1 -1
- package/dist/module.js +259 -154
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/global.d.ts +12 -0
- package/package.json +14 -10
- package/src/{index.js → index.ts} +35 -30
- package/src/lib/canvas/{colors.js → colors.ts} +53 -11
- package/src/lib/canvas/{draw.js → draw.ts} +29 -11
- package/src/lib/canvas/shapes/{basic.js → basic.ts} +14 -12
- package/src/lib/canvas/shapes/{complex.js → complex.ts} +116 -34
- package/src/lib/canvas/shapes/{index.js → index.ts} +7 -1
- package/src/lib/canvas/shapes/sacred.ts +206 -0
- package/src/lib/canvas/shapes/utils.ts +65 -0
- package/src/lib/{constants.js → constants.ts} +32 -5
- package/src/lib/{utils.js → utils.ts} +34 -6
- package/tsconfig.json +16 -0
- package/eslint.config.mjs +0 -29
- package/src/lib/canvas/shapes/sacred.js +0 -173
- package/src/lib/canvas/shapes/utils.js +0 -37
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ColorScheme from "color-scheme";
|
|
2
|
-
import
|
|
2
|
+
import "../../../global.d";
|
|
3
3
|
|
|
4
|
+
import { gitHashToSeed } from "../utils";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Generates a color scheme based on a given Git hash.
|
|
@@ -8,7 +9,7 @@ import { gitHashToSeed } from "../utils";
|
|
|
8
9
|
* @param {string} gitHash - The Git hash used to generate the color scheme.
|
|
9
10
|
* @returns {string[]} An array of hex color codes representing the generated color scheme.
|
|
10
11
|
*/
|
|
11
|
-
export function generateColorScheme(gitHash) {
|
|
12
|
+
export function generateColorScheme(gitHash: string): string[] {
|
|
12
13
|
const seed = gitHashToSeed(gitHash);
|
|
13
14
|
const scheme = new ColorScheme();
|
|
14
15
|
scheme
|
|
@@ -16,7 +17,7 @@ export function generateColorScheme(gitHash) {
|
|
|
16
17
|
.scheme("analogic")
|
|
17
18
|
.variation("soft");
|
|
18
19
|
|
|
19
|
-
let colors = scheme.colors().map((hex) => `#${hex}`);
|
|
20
|
+
let colors = scheme.colors().map((hex: string) => `#${hex}`);
|
|
20
21
|
|
|
21
22
|
const contrastingHue = (seed + 180) % 360;
|
|
22
23
|
const contrastingScheme = new ColorScheme();
|
|
@@ -26,30 +27,69 @@ export function generateColorScheme(gitHash) {
|
|
|
26
27
|
return colors;
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
interface MetallicColors {
|
|
31
|
+
gold: string;
|
|
32
|
+
silver: string;
|
|
33
|
+
copper: string;
|
|
34
|
+
bronze: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface SacredPalette {
|
|
38
|
+
primary: string;
|
|
39
|
+
secondary: string;
|
|
40
|
+
accent: string;
|
|
41
|
+
metallic: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface ElementalPalette {
|
|
45
|
+
earth: string;
|
|
46
|
+
water: string;
|
|
47
|
+
air: string;
|
|
48
|
+
fire: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface ChakraPalette {
|
|
52
|
+
root: string;
|
|
53
|
+
sacral: string;
|
|
54
|
+
solar: string;
|
|
55
|
+
heart: string;
|
|
56
|
+
throat: string;
|
|
57
|
+
third_eye: string;
|
|
58
|
+
crown: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type ColorPalette = SacredPalette | ElementalPalette | ChakraPalette | string[];
|
|
62
|
+
|
|
29
63
|
// Enhanced color scheme generation for sacred geometry
|
|
30
64
|
export class SacredColorScheme {
|
|
31
|
-
|
|
65
|
+
private seed: number;
|
|
66
|
+
public baseScheme: string[];
|
|
67
|
+
private complementaryScheme: string[];
|
|
68
|
+
private metallic: MetallicColors;
|
|
69
|
+
|
|
70
|
+
constructor(gitHash: string) {
|
|
32
71
|
this.seed = this.gitHashToSeed(gitHash);
|
|
33
72
|
this.baseScheme = this.generateBaseScheme();
|
|
34
73
|
this.complementaryScheme = this.generateComplementaryScheme();
|
|
35
74
|
this.metallic = this.generateMetallicColors();
|
|
36
75
|
}
|
|
37
76
|
|
|
38
|
-
gitHashToSeed(hash) {
|
|
77
|
+
private gitHashToSeed(hash: string): number {
|
|
39
78
|
return parseInt(hash.slice(0, 8), 16);
|
|
40
79
|
}
|
|
41
80
|
|
|
42
|
-
generateBaseScheme() {
|
|
81
|
+
private generateBaseScheme(): string[] {
|
|
43
82
|
const scheme = new ColorScheme();
|
|
83
|
+
scheme;
|
|
44
84
|
return scheme
|
|
45
85
|
.from_hue(this.seed % 360)
|
|
46
86
|
.scheme("analogic")
|
|
47
87
|
.variation("soft")
|
|
48
88
|
.colors()
|
|
49
|
-
.map((hex) => `#${hex}`);
|
|
89
|
+
.map((hex: string) => `#${hex}`);
|
|
50
90
|
}
|
|
51
91
|
|
|
52
|
-
generateComplementaryScheme() {
|
|
92
|
+
private generateComplementaryScheme(): string[] {
|
|
53
93
|
const complementaryHue = (this.seed + 180) % 360;
|
|
54
94
|
const scheme = new ColorScheme();
|
|
55
95
|
return scheme
|
|
@@ -57,10 +97,10 @@ export class SacredColorScheme {
|
|
|
57
97
|
.scheme("mono")
|
|
58
98
|
.variation("soft")
|
|
59
99
|
.colors()
|
|
60
|
-
.map((hex) => `#${hex}`);
|
|
100
|
+
.map((hex: string) => `#${hex}`);
|
|
61
101
|
}
|
|
62
102
|
|
|
63
|
-
generateMetallicColors() {
|
|
103
|
+
private generateMetallicColors(): MetallicColors {
|
|
64
104
|
return {
|
|
65
105
|
gold: "#FFD700",
|
|
66
106
|
silver: "#C0C0C0",
|
|
@@ -69,7 +109,9 @@ export class SacredColorScheme {
|
|
|
69
109
|
};
|
|
70
110
|
}
|
|
71
111
|
|
|
72
|
-
getColorPalette(
|
|
112
|
+
getColorPalette(
|
|
113
|
+
type: "sacred" | "elemental" | "chakra" | "default" = "sacred",
|
|
114
|
+
): ColorPalette {
|
|
73
115
|
switch (type) {
|
|
74
116
|
case "sacred":
|
|
75
117
|
return {
|
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
import { PatternCombiner } from "../utils";
|
|
1
|
+
import { PatternCombiner, ProportionType } from "../utils";
|
|
2
2
|
import { shapes } from "./shapes";
|
|
3
3
|
|
|
4
|
+
interface DrawShapeConfig {
|
|
5
|
+
fillColor: string;
|
|
6
|
+
strokeColor: string;
|
|
7
|
+
strokeWidth: number;
|
|
8
|
+
size: number;
|
|
9
|
+
rotation: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface EnhanceShapeConfig extends DrawShapeConfig {
|
|
13
|
+
patterns?: Array<{ type: string; config: any }>;
|
|
14
|
+
proportionType?: ProportionType;
|
|
15
|
+
baseOpacity?: number;
|
|
16
|
+
opacityReduction?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
4
19
|
export function drawShape(
|
|
5
|
-
ctx,
|
|
6
|
-
shape,
|
|
7
|
-
x,
|
|
8
|
-
y,
|
|
9
|
-
|
|
10
|
-
strokeColor,
|
|
11
|
-
strokeWidth,
|
|
12
|
-
size,
|
|
13
|
-
rotation
|
|
20
|
+
ctx: CanvasRenderingContext2D,
|
|
21
|
+
shape: string,
|
|
22
|
+
x: number,
|
|
23
|
+
y: number,
|
|
24
|
+
config: DrawShapeConfig,
|
|
14
25
|
) {
|
|
26
|
+
const { fillColor, strokeColor, strokeWidth, size, rotation } = config;
|
|
15
27
|
ctx.save();
|
|
16
28
|
ctx.translate(x, y);
|
|
17
29
|
ctx.rotate((rotation * Math.PI) / 180);
|
|
@@ -30,7 +42,13 @@ export function drawShape(
|
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
// Integration with existing generation logic
|
|
33
|
-
export function enhanceShapeGeneration(
|
|
45
|
+
export function enhanceShapeGeneration(
|
|
46
|
+
ctx: CanvasRenderingContext2D,
|
|
47
|
+
shape: string,
|
|
48
|
+
x: number,
|
|
49
|
+
y: number,
|
|
50
|
+
config: EnhanceShapeConfig,
|
|
51
|
+
) {
|
|
34
52
|
const {
|
|
35
53
|
fillColor,
|
|
36
54
|
strokeColor,
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
type DrawFunction = (ctx: CanvasRenderingContext2D, size: number) => void;
|
|
2
|
+
|
|
3
|
+
export const drawCircle: DrawFunction = (ctx, size) => {
|
|
2
4
|
ctx.beginPath();
|
|
3
5
|
ctx.arc(0, 0, size / 2, 0, Math.PI * 2);
|
|
4
6
|
};
|
|
5
7
|
|
|
6
|
-
export const drawSquare = (ctx, size) => {
|
|
8
|
+
export const drawSquare: DrawFunction = (ctx, size) => {
|
|
7
9
|
ctx.beginPath();
|
|
8
10
|
ctx.rect(-size / 2, -size / 2, size, size);
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
export const drawTriangle = (ctx, size) => {
|
|
13
|
+
export const drawTriangle: DrawFunction = (ctx, size) => {
|
|
12
14
|
ctx.beginPath();
|
|
13
15
|
ctx.moveTo(0, -size / 2);
|
|
14
16
|
ctx.lineTo(-size / 2, size / 2);
|
|
@@ -16,7 +18,7 @@ export const drawTriangle = (ctx, size) => {
|
|
|
16
18
|
ctx.closePath();
|
|
17
19
|
};
|
|
18
20
|
|
|
19
|
-
export const drawHexagon = (ctx, size) => {
|
|
21
|
+
export const drawHexagon: DrawFunction = (ctx, size) => {
|
|
20
22
|
ctx.beginPath();
|
|
21
23
|
for (let i = 0; i < 6; i++) {
|
|
22
24
|
const angle = (Math.PI / 8) * i;
|
|
@@ -28,7 +30,7 @@ export const drawHexagon = (ctx, size) => {
|
|
|
28
30
|
ctx.closePath();
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
export const drawStar = (ctx, size) => {
|
|
33
|
+
export const drawStar: DrawFunction = (ctx, size) => {
|
|
32
34
|
ctx.beginPath();
|
|
33
35
|
for (let i = 0; i < 10; i++) {
|
|
34
36
|
const angle = Math.PI / 5 + (Math.PI / 5) * i * 3;
|
|
@@ -41,7 +43,7 @@ export const drawStar = (ctx, size) => {
|
|
|
41
43
|
ctx.closePath();
|
|
42
44
|
};
|
|
43
45
|
|
|
44
|
-
export const drawJackedStar = (ctx, size) => {
|
|
46
|
+
export const drawJackedStar: DrawFunction = (ctx, size) => {
|
|
45
47
|
ctx.beginPath();
|
|
46
48
|
for (let i = 0; i < 10; i++) {
|
|
47
49
|
const angle = Math.PI / 30 + (Math.PI / 30) * i * 8;
|
|
@@ -54,14 +56,14 @@ export const drawJackedStar = (ctx, size) => {
|
|
|
54
56
|
ctx.closePath();
|
|
55
57
|
};
|
|
56
58
|
|
|
57
|
-
export const drawHeart = (ctx, size) => {
|
|
59
|
+
export const drawHeart: DrawFunction = (ctx, size) => {
|
|
58
60
|
ctx.beginPath();
|
|
59
61
|
ctx.moveTo(0, size / 4);
|
|
60
62
|
ctx.quadraticCurveTo(size / 2, size / 4, 0, -size / 4);
|
|
61
63
|
ctx.quadraticCurveTo(-size / 2, size / 4, 0, size / 4);
|
|
62
64
|
};
|
|
63
65
|
|
|
64
|
-
export const drawDiamond = (ctx, size) => {
|
|
66
|
+
export const drawDiamond: DrawFunction = (ctx, size) => {
|
|
65
67
|
ctx.beginPath();
|
|
66
68
|
ctx.moveTo(0, -size / 2);
|
|
67
69
|
ctx.lineTo(size / 2, 0);
|
|
@@ -70,7 +72,7 @@ export const drawDiamond = (ctx, size) => {
|
|
|
70
72
|
ctx.closePath();
|
|
71
73
|
};
|
|
72
74
|
|
|
73
|
-
export const drawCube = (ctx, size) => {
|
|
75
|
+
export const drawCube: DrawFunction = (ctx, size) => {
|
|
74
76
|
ctx.beginPath();
|
|
75
77
|
ctx.moveTo(-size / 2, -size / 2);
|
|
76
78
|
ctx.lineTo(size / 2, -size / 2);
|
|
@@ -80,7 +82,7 @@ export const drawCube = (ctx, size) => {
|
|
|
80
82
|
};
|
|
81
83
|
|
|
82
84
|
// Optional: Create a shape map for easier lookup
|
|
83
|
-
export const basicShapes = {
|
|
85
|
+
export const basicShapes: Record<string, DrawFunction> = {
|
|
84
86
|
circle: drawCircle,
|
|
85
87
|
square: drawSquare,
|
|
86
88
|
triangle: drawTriangle,
|
|
@@ -89,5 +91,5 @@ export const basicShapes = {
|
|
|
89
91
|
"jacked-star": drawJackedStar,
|
|
90
92
|
heart: drawHeart,
|
|
91
93
|
diamond: drawDiamond,
|
|
92
|
-
cube: drawCube
|
|
93
|
-
};
|
|
94
|
+
cube: drawCube,
|
|
95
|
+
};
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { defaultShapeConfig } from "../../constants";
|
|
2
2
|
import { applyTransforms, createCirclePoints, restoreContext } from "./utils";
|
|
3
3
|
|
|
4
|
+
interface PlatonicSolidConfig {
|
|
5
|
+
vertices: number;
|
|
6
|
+
faces: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface FibonacciConfig {
|
|
10
|
+
iterations: number;
|
|
11
|
+
growthFactor: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface GoldenRatioConfig {
|
|
15
|
+
iterations: number;
|
|
16
|
+
ratio: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
4
19
|
export const ShapeConfigs = {
|
|
5
20
|
platonic: {
|
|
6
21
|
tetrahedron: { vertices: 4, faces: 4 },
|
|
@@ -8,25 +23,41 @@ export const ShapeConfigs = {
|
|
|
8
23
|
octahedron: { vertices: 6, faces: 8 },
|
|
9
24
|
dodecahedron: { vertices: 20, faces: 12 },
|
|
10
25
|
icosahedron: { vertices: 12, faces: 20 },
|
|
11
|
-
},
|
|
26
|
+
} as Record<string, PlatonicSolidConfig>,
|
|
12
27
|
fibonacci: {
|
|
13
28
|
iterations: 13,
|
|
14
29
|
growthFactor: 1.618034, // Golden ratio
|
|
15
|
-
},
|
|
30
|
+
} as FibonacciConfig,
|
|
16
31
|
goldenRatio: {
|
|
17
32
|
iterations: 8,
|
|
18
33
|
ratio: 1.618034,
|
|
19
|
-
},
|
|
34
|
+
} as GoldenRatioConfig,
|
|
20
35
|
};
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
interface ShapeConfig {
|
|
38
|
+
fillStyle?: string;
|
|
39
|
+
strokeStyle?: string;
|
|
40
|
+
lineWidth?: number;
|
|
41
|
+
rotation?: number;
|
|
42
|
+
iterations?: number;
|
|
43
|
+
animate?: boolean;
|
|
44
|
+
type?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type DrawFunction = (
|
|
48
|
+
ctx: CanvasRenderingContext2D,
|
|
49
|
+
size: number,
|
|
50
|
+
config?: ShapeConfig,
|
|
51
|
+
) => void;
|
|
52
|
+
|
|
53
|
+
export const drawPlatonicSolid: DrawFunction = (ctx, size, config = {}) => {
|
|
23
54
|
const finalConfig = { ...defaultShapeConfig, ...config };
|
|
24
55
|
applyTransforms(ctx, size, finalConfig);
|
|
25
56
|
|
|
26
|
-
const {
|
|
27
|
-
vertices,
|
|
28
|
-
// faces
|
|
29
|
-
} = ShapeConfigs.platonic[type];
|
|
57
|
+
const {
|
|
58
|
+
vertices,
|
|
59
|
+
// faces
|
|
60
|
+
} = ShapeConfigs.platonic[config.type as keyof typeof ShapeConfigs.platonic];
|
|
30
61
|
const radius = size / 2;
|
|
31
62
|
|
|
32
63
|
// Calculate vertices based on platonic solid type
|
|
@@ -48,7 +79,7 @@ export const drawPlatonicSolid = (ctx, size, type, config = {}) => {
|
|
|
48
79
|
restoreContext(ctx);
|
|
49
80
|
};
|
|
50
81
|
|
|
51
|
-
export const drawFibonacciSpiral = (ctx, size, config = {}) => {
|
|
82
|
+
export const drawFibonacciSpiral: DrawFunction = (ctx, size, config = {}) => {
|
|
52
83
|
const finalConfig = {
|
|
53
84
|
...defaultShapeConfig,
|
|
54
85
|
...ShapeConfigs.fibonacci,
|
|
@@ -82,7 +113,7 @@ export const drawFibonacciSpiral = (ctx, size, config = {}) => {
|
|
|
82
113
|
restoreContext(ctx);
|
|
83
114
|
};
|
|
84
115
|
|
|
85
|
-
export const drawIslamicPattern = (ctx, size, config = {}) => {
|
|
116
|
+
export const drawIslamicPattern: DrawFunction = (ctx, size, config = {}) => {
|
|
86
117
|
const finalConfig = { ...defaultShapeConfig, ...config };
|
|
87
118
|
applyTransforms(ctx, size, finalConfig);
|
|
88
119
|
|
|
@@ -99,34 +130,29 @@ export const drawIslamicPattern = (ctx, size, config = {}) => {
|
|
|
99
130
|
// Draw star pattern at each intersection
|
|
100
131
|
const radius = unit / 2;
|
|
101
132
|
for (let k = 0; k < 8; k++) {
|
|
102
|
-
const angle = (
|
|
103
|
-
const x1 = x + Math.cos(angle)
|
|
104
|
-
const y1 = y + Math.sin(angle)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
133
|
+
const angle = (Math.PI / 4) * k;
|
|
134
|
+
const x1 = x + radius * Math.cos(angle);
|
|
135
|
+
const y1 = y + radius * Math.sin(angle);
|
|
136
|
+
const x2 = x + radius * Math.cos(angle + Math.PI / 4);
|
|
137
|
+
const y2 = y + radius * Math.sin(angle + Math.PI / 4);
|
|
138
|
+
ctx.moveTo(x1, y1);
|
|
139
|
+
ctx.lineTo(x2, y2);
|
|
110
140
|
}
|
|
111
|
-
ctx.closePath();
|
|
112
141
|
}
|
|
113
142
|
}
|
|
114
143
|
|
|
115
|
-
if (finalConfig.fillStyle !== "transparent") {
|
|
116
|
-
ctx.fill();
|
|
117
|
-
}
|
|
118
144
|
ctx.stroke();
|
|
119
145
|
restoreContext(ctx);
|
|
120
146
|
};
|
|
121
147
|
|
|
122
|
-
export const drawCelticKnot = (ctx, size, config = {}) => {
|
|
148
|
+
export const drawCelticKnot: DrawFunction = (ctx, size, config = {}) => {
|
|
123
149
|
const finalConfig = { ...defaultShapeConfig, ...config };
|
|
124
150
|
applyTransforms(ctx, size, finalConfig);
|
|
125
151
|
|
|
126
152
|
const gridSize = 4;
|
|
127
153
|
const unit = size / gridSize;
|
|
128
154
|
|
|
129
|
-
const drawKnotSegment = (x, y, type) => {
|
|
155
|
+
const drawKnotSegment = (x: number, y: number, type: string) => {
|
|
130
156
|
ctx.beginPath();
|
|
131
157
|
switch (type) {
|
|
132
158
|
case "over":
|
|
@@ -137,7 +163,7 @@ export const drawCelticKnot = (ctx, size, config = {}) => {
|
|
|
137
163
|
x + unit / 2,
|
|
138
164
|
y + unit,
|
|
139
165
|
x + unit,
|
|
140
|
-
y + unit
|
|
166
|
+
y + unit,
|
|
141
167
|
);
|
|
142
168
|
break;
|
|
143
169
|
case "under":
|
|
@@ -160,7 +186,7 @@ export const drawCelticKnot = (ctx, size, config = {}) => {
|
|
|
160
186
|
restoreContext(ctx);
|
|
161
187
|
};
|
|
162
188
|
|
|
163
|
-
export const drawMerkaba = (ctx, size, config = {}) => {
|
|
189
|
+
export const drawMerkaba: DrawFunction = (ctx, size, config = {}) => {
|
|
164
190
|
const finalConfig = { ...defaultShapeConfig, ...config };
|
|
165
191
|
applyTransforms(ctx, size, finalConfig);
|
|
166
192
|
|
|
@@ -194,12 +220,68 @@ export const drawMerkaba = (ctx, size, config = {}) => {
|
|
|
194
220
|
restoreContext(ctx);
|
|
195
221
|
};
|
|
196
222
|
|
|
197
|
-
export const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
223
|
+
export const drawMandala: DrawFunction = (ctx, size, config = {}) => {
|
|
224
|
+
const finalConfig = { ...defaultShapeConfig, ...config };
|
|
225
|
+
applyTransforms(ctx, size, finalConfig);
|
|
226
|
+
|
|
227
|
+
const numCircles = 8;
|
|
228
|
+
const numPoints = 16;
|
|
229
|
+
const radius = size / 2;
|
|
230
|
+
|
|
231
|
+
ctx.beginPath();
|
|
232
|
+
for (let i = 1; i <= numCircles; i++) {
|
|
233
|
+
const circleRadius = (radius / numCircles) * i;
|
|
234
|
+
ctx.moveTo(circleRadius, 0);
|
|
235
|
+
ctx.arc(0, 0, circleRadius, 0, Math.PI * 2);
|
|
236
|
+
|
|
237
|
+
for (let j = 0; j < numPoints; j++) {
|
|
238
|
+
const angle = (Math.PI * 2 * j) / numPoints;
|
|
239
|
+
const x = circleRadius * Math.cos(angle);
|
|
240
|
+
const y = circleRadius * Math.sin(angle);
|
|
241
|
+
ctx.moveTo(0, 0);
|
|
242
|
+
ctx.lineTo(x, y);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
ctx.stroke();
|
|
247
|
+
restoreContext(ctx);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export const drawFractal: DrawFunction = (ctx, size, config = {}) => {
|
|
251
|
+
const finalConfig = { ...defaultShapeConfig, ...config, iterations: 5 };
|
|
252
|
+
applyTransforms(ctx, size, finalConfig);
|
|
253
|
+
|
|
254
|
+
const drawBranch = (
|
|
255
|
+
x: number,
|
|
256
|
+
y: number,
|
|
257
|
+
length: number,
|
|
258
|
+
angle: number,
|
|
259
|
+
depth: number,
|
|
260
|
+
) => {
|
|
261
|
+
if (depth === 0) return;
|
|
262
|
+
|
|
263
|
+
const endX = x + length * Math.cos(angle);
|
|
264
|
+
const endY = y + length * Math.sin(angle);
|
|
265
|
+
|
|
266
|
+
ctx.beginPath();
|
|
267
|
+
ctx.moveTo(x, y);
|
|
268
|
+
ctx.lineTo(endX, endY);
|
|
269
|
+
ctx.stroke();
|
|
270
|
+
|
|
271
|
+
drawBranch(endX, endY, length * 0.7, angle - Math.PI / 6, depth - 1);
|
|
272
|
+
drawBranch(endX, endY, length * 0.7, angle + Math.PI / 6, depth - 1);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
drawBranch(0, size / 2, size / 4, -Math.PI / 2, finalConfig.iterations);
|
|
276
|
+
restoreContext(ctx);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const complexShapes: Record<string, DrawFunction> = {
|
|
280
|
+
platonicSolid: drawPlatonicSolid,
|
|
281
|
+
fibonacciSpiral: drawFibonacciSpiral,
|
|
282
|
+
islamicPattern: drawIslamicPattern,
|
|
283
|
+
celticKnot: drawCelticKnot,
|
|
284
|
+
merkaba: drawMerkaba,
|
|
285
|
+
mandala: drawMandala,
|
|
286
|
+
fractal: drawFractal,
|
|
205
287
|
};
|
|
@@ -2,7 +2,13 @@ import { basicShapes } from "./basic";
|
|
|
2
2
|
import { complexShapes } from "./complex";
|
|
3
3
|
import { sacredShapes } from "./sacred";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
type DrawFunction = (
|
|
6
|
+
ctx: CanvasRenderingContext2D,
|
|
7
|
+
size: number,
|
|
8
|
+
config?: any,
|
|
9
|
+
) => void;
|
|
10
|
+
|
|
11
|
+
export const shapes: Record<string, DrawFunction> = {
|
|
6
12
|
...basicShapes,
|
|
7
13
|
...complexShapes,
|
|
8
14
|
...sacredShapes,
|