@africode/core 5.0.0
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/AFRICODE_FRAMEWORK_GUIDE.md +707 -0
- package/LICENSE +623 -0
- package/README.md +442 -0
- package/bin/africode.js +73 -0
- package/bin/africode.js.1758507140 +343 -0
- package/bin/cli.ts +83 -0
- package/bin/create-africode.js +158 -0
- package/bin/scaffold.ts +219 -0
- package/components/accordion.js +183 -0
- package/components/alert.js +131 -0
- package/components/auth.js +172 -0
- package/components/avatar.js +117 -0
- package/components/badge.js +104 -0
- package/components/base.d.ts +139 -0
- package/components/base.js +184 -0
- package/components/button.js +164 -0
- package/components/card.js +137 -0
- package/components/cultural-card.js +243 -0
- package/components/divider.js +83 -0
- package/components/dropdown.js +171 -0
- package/components/error-boundary.js +155 -0
- package/components/form.js +131 -0
- package/components/grid.js +273 -0
- package/components/hero.js +138 -0
- package/components/icon.js +36 -0
- package/components/index.js +57 -0
- package/components/input.js +256 -0
- package/components/kanga-card.js +185 -0
- package/components/language-switcher.js +108 -0
- package/components/loader.js +80 -0
- package/components/modal.js +262 -0
- package/components/motion.js +84 -0
- package/components/navbar.js +236 -0
- package/components/pattern-showcase.js +225 -0
- package/components/progress.js +134 -0
- package/components/react.js +111 -0
- package/components/section.js +54 -0
- package/components/select.js +322 -0
- package/components/sidebar.js +180 -0
- package/components/skeleton.js +85 -0
- package/components/table.js +181 -0
- package/components/tabs.js +202 -0
- package/components/theme-toggle.js +82 -0
- package/components/toast.js +139 -0
- package/components/tooltip.js +167 -0
- package/core/a2ui-schema-manager.js +344 -0
- package/core/a2ui.js +431 -0
- package/core/bun-runtime.js +799 -0
- package/core/cli/commands/add.js +23 -0
- package/core/cli/commands/audit.js +58 -0
- package/core/cli/commands/build.js +137 -0
- package/core/cli/commands/create-plugin.js +241 -0
- package/core/cli/commands/dev.js +228 -0
- package/core/cli/commands/lint.js +23 -0
- package/core/cli/commands/test.js +34 -0
- package/core/cli/migrator.js +71 -0
- package/core/cli/ui.js +46 -0
- package/core/compliance.js +628 -0
- package/core/config.js +263 -0
- package/core/db-advanced.js +481 -0
- package/core/db.js +284 -0
- package/core/enhanced-hmr.js +404 -0
- package/core/errors.js +222 -0
- package/core/file-router.js +290 -0
- package/core/heartbeat.js +64 -0
- package/core/hmr-client.js +204 -0
- package/core/hmr.js +196 -0
- package/core/html.d.ts +116 -0
- package/core/html.js +160 -0
- package/core/hydration.js +52 -0
- package/core/lipa-namba-journey.js +572 -0
- package/core/motion.js +106 -0
- package/core/nida-cig-middleware.js +455 -0
- package/core/patterns.d.ts +124 -0
- package/core/patterns.js +833 -0
- package/core/plugins/index.js +312 -0
- package/core/router.js +387 -0
- package/core/sdk-client.js +62 -0
- package/core/sdk.d.ts +133 -0
- package/core/sdk.js +123 -0
- package/core/seo.js +76 -0
- package/core/server/auth-endpoints.js +339 -0
- package/core/server/auth.js +180 -0
- package/core/server/csrf.js +206 -0
- package/core/server/db.js +39 -0
- package/core/server/middleware.js +324 -0
- package/core/server/rate-limit.js +238 -0
- package/core/server/render.js +69 -0
- package/core/server/router.js +120 -0
- package/core/shim.js +28 -0
- package/core/state.d.ts +86 -0
- package/core/state.js +242 -0
- package/core/store.d.ts +122 -0
- package/core/store.js +61 -0
- package/core/validation.d.ts +233 -0
- package/core/validation.js +590 -0
- package/core/websocket.js +639 -0
- package/dist/africode.js +2905 -0
- package/dist/africode.js.map +61 -0
- package/dist/build-info.json +23 -0
- package/dist/components.js +2888 -0
- package/dist/components.js.map +58 -0
- package/dist/styles/africanity.css +322 -0
- package/dist/styles/typography.css +141 -0
- package/docs/IDE-Guide.md +50 -0
- package/package.json +110 -0
- package/src/index.ts +196 -0
- package/styles/africanity.css +322 -0
- package/styles/typography.css +141 -0
- package/templates/starter/.env.example +15 -0
- package/templates/starter/africode.config.js +40 -0
- package/templates/starter/package.json +14 -0
- package/templates/starter/src/pages/index.html +46 -0
- package/templates/starter/src/pages/index.js +32 -0
- package/templates/starter/src/styles/main.css +4 -0
- package/templates/starter-3d/.env.example +7 -0
- package/templates/starter-3d/africode.config.js +29 -0
- package/templates/starter-3d/components/af-model-viewer.js +125 -0
- package/templates/starter-3d/package.json +15 -0
- package/templates/starter-3d/src/pages/index.html +46 -0
- package/templates/starter-3d/src/pages/index.js +50 -0
- package/templates/starter-3d/src/styles/main.css +4 -0
- package/templates/starter-react/.env.example +15 -0
- package/templates/starter-react/africode.config.js +40 -0
- package/templates/starter-react/package.json +16 -0
- package/templates/starter-react/src/pages/index.html +46 -0
- package/templates/starter-react/src/pages/index.js +68 -0
- package/templates/starter-react/src/styles/main.css +4 -0
- package/templates/starter-tailwind/.env.example +15 -0
- package/templates/starter-tailwind/africode.config.js +40 -0
- package/templates/starter-tailwind/package.json +20 -0
- package/templates/starter-tailwind/src/pages/index.html +46 -0
- package/templates/starter-tailwind/src/pages/index.js +37 -0
- package/templates/starter-tailwind/src/styles/main.css +4 -0
- package/templates/starter-tailwind/src/styles/tailwind.css +1 -0
- package/templates/starter-tailwind/src/tailwind-loader.js +30 -0
package/core/patterns.js
ADDED
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AfriCode Procedural SVG Pattern Engine
|
|
3
|
+
*
|
|
4
|
+
* Generates lightweight, on-the-fly SVG patterns inspired by
|
|
5
|
+
* African textiles from across the continent:
|
|
6
|
+
*
|
|
7
|
+
* EAST AFRICA: Maasai Shuka, Kanga, Kitenge, Hadzabe
|
|
8
|
+
* WEST AFRICA: Ghana Kente, Adinkra, Nigeria Aso-Oke, Ankara
|
|
9
|
+
* SOUTHERN AFRICA: Ndebele, Zulu, Swazi/Eswatini, Xhosa
|
|
10
|
+
*
|
|
11
|
+
* @module core/patterns
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate a polygon with n sides
|
|
16
|
+
* Based on the mathematical formula:
|
|
17
|
+
* x_i = cx + r * cos(2πi/n)
|
|
18
|
+
* y_i = cy + r * sin(2πi/n)
|
|
19
|
+
*/
|
|
20
|
+
export function generatePolygon(n, r, cx = 50, cy = 50) {
|
|
21
|
+
const points = [];
|
|
22
|
+
for (let i = 0; i < n; i++) {
|
|
23
|
+
const angle = (2 * Math.PI * i) / n - Math.PI / 2;
|
|
24
|
+
const x = cx + r * Math.cos(angle);
|
|
25
|
+
const y = cy + r * Math.sin(angle);
|
|
26
|
+
points.push(`${x.toFixed(2)},${y.toFixed(2)}`);
|
|
27
|
+
}
|
|
28
|
+
return points.join(' ');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ============================================
|
|
32
|
+
// EAST AFRICAN PATTERNS
|
|
33
|
+
// ============================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Generate Maasai Shuka tartan pattern (Tanzania/Kenya)
|
|
37
|
+
* Traditional red checkered blanket with overlapping stripes
|
|
38
|
+
*/
|
|
39
|
+
export function generateShuka({
|
|
40
|
+
primaryColor = '#FF0000',
|
|
41
|
+
secondaryColor = '#000000',
|
|
42
|
+
backgroundColor = '#8B0000',
|
|
43
|
+
stripeWidth = 4,
|
|
44
|
+
size = 40
|
|
45
|
+
} = {}) {
|
|
46
|
+
const svg = `
|
|
47
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
48
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
49
|
+
<rect x="0" y="0" width="${size}" height="${stripeWidth}" fill="${primaryColor}" opacity="0.8"/>
|
|
50
|
+
<rect x="0" y="${size / 2 - stripeWidth / 2}" width="${size}" height="${stripeWidth}" fill="${secondaryColor}" opacity="0.6"/>
|
|
51
|
+
<rect x="0" y="${size - stripeWidth}" width="${size}" height="${stripeWidth}" fill="${primaryColor}" opacity="0.8"/>
|
|
52
|
+
<rect x="0" y="0" width="${stripeWidth}" height="${size}" fill="${primaryColor}" opacity="0.5"/>
|
|
53
|
+
<rect x="${size / 2 - stripeWidth / 2}" y="0" width="${stripeWidth}" height="${size}" fill="${secondaryColor}" opacity="0.4"/>
|
|
54
|
+
<rect x="${size - stripeWidth}" y="0" width="${stripeWidth}" height="${size}" fill="${primaryColor}" opacity="0.5"/>
|
|
55
|
+
</svg>
|
|
56
|
+
`;
|
|
57
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generate Hadzabe pattern (Tanzania)
|
|
62
|
+
* Inspired by cave paintings and natural earth tones
|
|
63
|
+
* Hunter-gatherer tribe with ancient artistic traditions
|
|
64
|
+
*/
|
|
65
|
+
export function generateHadzabe({
|
|
66
|
+
earthColor = '#8B4513',
|
|
67
|
+
ochreColor = '#CD853F',
|
|
68
|
+
charcoalColor = '#2F2F2F',
|
|
69
|
+
size = 50
|
|
70
|
+
} = {}) {
|
|
71
|
+
const svg = `
|
|
72
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
73
|
+
<rect width="${size}" height="${size}" fill="${earthColor}"/>
|
|
74
|
+
<!-- Cave art inspired figures -->
|
|
75
|
+
<circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.08}" fill="${ochreColor}"/>
|
|
76
|
+
<line x1="${size * 0.3}" y1="${size * 0.38}" x2="${size * 0.3}" y2="${size * 0.6}" stroke="${charcoalColor}" stroke-width="2"/>
|
|
77
|
+
<line x1="${size * 0.2}" y1="${size * 0.45}" x2="${size * 0.4}" y2="${size * 0.45}" stroke="${charcoalColor}" stroke-width="2"/>
|
|
78
|
+
<!-- Animal figure -->
|
|
79
|
+
<ellipse cx="${size * 0.7}" cy="${size * 0.5}" rx="${size * 0.15}" ry="${size * 0.08}" fill="${ochreColor}"/>
|
|
80
|
+
<line x1="${size * 0.6}" y1="${size * 0.58}" x2="${size * 0.6}" y2="${size * 0.7}" stroke="${charcoalColor}" stroke-width="2"/>
|
|
81
|
+
<line x1="${size * 0.8}" y1="${size * 0.58}" x2="${size * 0.8}" y2="${size * 0.7}" stroke="${charcoalColor}" stroke-width="2"/>
|
|
82
|
+
<!-- Dots like ancient markings -->
|
|
83
|
+
<circle cx="${size * 0.15}" cy="${size * 0.8}" r="3" fill="${ochreColor}"/>
|
|
84
|
+
<circle cx="${size * 0.85}" cy="${size * 0.2}" r="3" fill="${ochreColor}"/>
|
|
85
|
+
</svg>
|
|
86
|
+
`;
|
|
87
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Generate Kanga border pattern (Tanzania/Kenya)
|
|
92
|
+
*/
|
|
93
|
+
export function generateKangaBorder({
|
|
94
|
+
primaryColor = '#1EB53A', // Simple Green (Tanzania)
|
|
95
|
+
accentColor = '#FCD116', // Gold
|
|
96
|
+
size = 30
|
|
97
|
+
} = {}) {
|
|
98
|
+
const svg = `
|
|
99
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
100
|
+
<rect width="${size}" height="${size}" fill="${primaryColor}"/>
|
|
101
|
+
<!-- Pindo (Border) Motifs: Cashew/Triangle -->
|
|
102
|
+
<path d="M0,0 L${size / 2},${size / 2} L0,${size} Z" fill="${accentColor}"/>
|
|
103
|
+
<path d="M${size},0 L${size / 2},${size / 2} L${size},${size} Z" fill="${accentColor}"/>
|
|
104
|
+
<circle cx="${size / 2}" cy="${size / 2}" r="${size * 0.15}" fill="none" stroke="${accentColor}" stroke-width="2"/>
|
|
105
|
+
</svg>
|
|
106
|
+
`;
|
|
107
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Generate Kanga traditional Swahili cloth pattern (East Africa)
|
|
112
|
+
*/
|
|
113
|
+
export function generateKanga({
|
|
114
|
+
primaryColor = '#FF6B00',
|
|
115
|
+
secondaryColor = '#002B5C',
|
|
116
|
+
backgroundColor = '#FFFFFF',
|
|
117
|
+
size = 40
|
|
118
|
+
} = {}) {
|
|
119
|
+
const svg = `
|
|
120
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
121
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
122
|
+
<!-- Border pattern -->
|
|
123
|
+
<rect x="0" y="0" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
|
|
124
|
+
<rect x="0" y="${size * 0.9}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
|
|
125
|
+
<rect x="0" y="0" width="${size * 0.1}" height="${size}" fill="${primaryColor}"/>
|
|
126
|
+
<rect x="${size * 0.9}" y="0" width="${size * 0.1}" height="${size}" fill="${primaryColor}"/>
|
|
127
|
+
<!-- Center motif -->
|
|
128
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.15}" fill="${secondaryColor}"/>
|
|
129
|
+
<text x="${size * 0.5}" y="${size * 0.55}" text-anchor="middle" fill="${primaryColor}" font-size="${size * 0.08}">KANGA</text>
|
|
130
|
+
</svg>
|
|
131
|
+
`;
|
|
132
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Generate Kuba Border pattern (Congo)
|
|
137
|
+
*/
|
|
138
|
+
export function generateKubaBorder({
|
|
139
|
+
primaryColor = '#8B4513',
|
|
140
|
+
secondaryColor = '#DAA520',
|
|
141
|
+
backgroundColor = '#F5F5DC',
|
|
142
|
+
size = 30
|
|
143
|
+
} = {}) {
|
|
144
|
+
const svg = `
|
|
145
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
146
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
147
|
+
<!-- Kuba geometric border -->
|
|
148
|
+
<polygon points="0,0 ${size * 0.3},0 0,${size * 0.3}" fill="${primaryColor}"/>
|
|
149
|
+
<polygon points="${size},0 ${size * 0.7},0 ${size},${size * 0.3}" fill="${primaryColor}"/>
|
|
150
|
+
<polygon points="0,${size} ${size * 0.3},${size} 0,${size * 0.7}" fill="${primaryColor}"/>
|
|
151
|
+
<polygon points="${size},${size} ${size * 0.7},${size} ${size},${size * 0.7}" fill="${primaryColor}"/>
|
|
152
|
+
<!-- Center diamond -->
|
|
153
|
+
<polygon points="${size * 0.5},${size * 0.3} ${size * 0.7},${size * 0.5} ${size * 0.5},${size * 0.7} ${size * 0.3},${size * 0.5}" fill="${secondaryColor}"/>
|
|
154
|
+
</svg>
|
|
155
|
+
`;
|
|
156
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Generate Zulu Beads pattern (South Africa)
|
|
161
|
+
*/
|
|
162
|
+
export function generateZuluBeads({
|
|
163
|
+
primaryColor = '#FF0000',
|
|
164
|
+
secondaryColor = '#000000',
|
|
165
|
+
accentColor = '#FFFFFF',
|
|
166
|
+
size = 40
|
|
167
|
+
} = {}) {
|
|
168
|
+
const svg = `
|
|
169
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
170
|
+
<rect width="${size}" height="${size}" fill="${accentColor}"/>
|
|
171
|
+
<!-- Bead pattern -->
|
|
172
|
+
<circle cx="${size * 0.2}" cy="${size * 0.2}" r="${size * 0.08}" fill="${primaryColor}"/>
|
|
173
|
+
<circle cx="${size * 0.5}" cy="${size * 0.2}" r="${size * 0.08}" fill="${secondaryColor}"/>
|
|
174
|
+
<circle cx="${size * 0.8}" cy="${size * 0.2}" r="${size * 0.08}" fill="${primaryColor}"/>
|
|
175
|
+
<circle cx="${size * 0.2}" cy="${size * 0.5}" r="${size * 0.08}" fill="${secondaryColor}"/>
|
|
176
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.08}" fill="${primaryColor}"/>
|
|
177
|
+
<circle cx="${size * 0.8}" cy="${size * 0.5}" r="${size * 0.08}" fill="${secondaryColor}"/>
|
|
178
|
+
<circle cx="${size * 0.2}" cy="${size * 0.8}" r="${size * 0.08}" fill="${primaryColor}"/>
|
|
179
|
+
<circle cx="${size * 0.5}" cy="${size * 0.8}" r="${size * 0.08}" fill="${secondaryColor}"/>
|
|
180
|
+
<circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.08}" fill="${primaryColor}"/>
|
|
181
|
+
</svg>
|
|
182
|
+
`;
|
|
183
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generate Maasai Shield pattern (Kenya/Tanzania)
|
|
188
|
+
*/
|
|
189
|
+
export function generateMasaiShield({
|
|
190
|
+
primaryColor = '#8B0000',
|
|
191
|
+
secondaryColor = '#FFD700',
|
|
192
|
+
backgroundColor = '#654321',
|
|
193
|
+
size = 50
|
|
194
|
+
} = {}) {
|
|
195
|
+
const svg = `
|
|
196
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
197
|
+
<ellipse cx="${size * 0.5}" cy="${size * 0.5}" rx="${size * 0.4}" ry="${size * 0.45}" fill="${backgroundColor}"/>
|
|
198
|
+
<!-- Shield patterns -->
|
|
199
|
+
<ellipse cx="${size * 0.5}" cy="${size * 0.3}" rx="${size * 0.2}" ry="${size * 0.15}" fill="${primaryColor}"/>
|
|
200
|
+
<rect x="${size * 0.4}" y="${size * 0.5}" width="${size * 0.2}" height="${size * 0.3}" fill="${secondaryColor}"/>
|
|
201
|
+
<!-- Decorative lines -->
|
|
202
|
+
<line x1="${size * 0.3}" y1="${size * 0.2}" x2="${size * 0.7}" y2="${size * 0.2}" stroke="${primaryColor}" stroke-width="3"/>
|
|
203
|
+
<line x1="${size * 0.3}" y1="${size * 0.8}" x2="${size * 0.7}" y2="${size * 0.8}" stroke="${primaryColor}" stroke-width="3"/>
|
|
204
|
+
</svg>
|
|
205
|
+
`;
|
|
206
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Generate Ndebele Paint house pattern (South Africa)
|
|
211
|
+
*/
|
|
212
|
+
export function generateNdebelePaint({
|
|
213
|
+
primaryColor = '#FF1493',
|
|
214
|
+
secondaryColor = '#00FF00',
|
|
215
|
+
accentColor = '#FFFF00',
|
|
216
|
+
backgroundColor = '#FFFFFF',
|
|
217
|
+
size = 50
|
|
218
|
+
} = {}) {
|
|
219
|
+
const svg = `
|
|
220
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
221
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
222
|
+
<!-- Ndebele geometric patterns -->
|
|
223
|
+
<polygon points="${size * 0.2},${size * 0.2} ${size * 0.4},${size * 0.2} ${size * 0.3},${size * 0.4}" fill="${primaryColor}"/>
|
|
224
|
+
<polygon points="${size * 0.6},${size * 0.2} ${size * 0.8},${size * 0.2} ${size * 0.7},${size * 0.4}" fill="${secondaryColor}"/>
|
|
225
|
+
<polygon points="${size * 0.2},${size * 0.6} ${size * 0.4},${size * 0.6} ${size * 0.3},${size * 0.8}" fill="${accentColor}"/>
|
|
226
|
+
<polygon points="${size * 0.6},${size * 0.6} ${size * 0.8},${size * 0.6} ${size * 0.7},${size * 0.8}" fill="${primaryColor}"/>
|
|
227
|
+
<!-- Center design -->
|
|
228
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.15}" fill="${secondaryColor}"/>
|
|
229
|
+
<rect x="${size * 0.45}" y="${size * 0.45}" width="${size * 0.1}" height="${size * 0.1}" fill="${accentColor}"/>
|
|
230
|
+
</svg>
|
|
231
|
+
`;
|
|
232
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Generate Kitenge floral pattern (East Africa)
|
|
237
|
+
*/
|
|
238
|
+
export function generateKitenge({
|
|
239
|
+
primaryColor = '#00A3DD',
|
|
240
|
+
secondaryColor = '#FCD116',
|
|
241
|
+
backgroundColor = '#1EB53A',
|
|
242
|
+
size = 50
|
|
243
|
+
} = {}) {
|
|
244
|
+
const svg = `
|
|
245
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
246
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
247
|
+
<circle cx="${size * 0.25}" cy="${size * 0.25}" r="${size * 0.2}" fill="${primaryColor}" opacity="0.8"/>
|
|
248
|
+
<circle cx="${size * 0.75}" cy="${size * 0.75}" r="${size * 0.2}" fill="${primaryColor}" opacity="0.8"/>
|
|
249
|
+
<circle cx="${size * 0.25}" cy="${size * 0.25}" r="${size * 0.1}" fill="${secondaryColor}"/>
|
|
250
|
+
<circle cx="${size * 0.75}" cy="${size * 0.75}" r="${size * 0.1}" fill="${secondaryColor}"/>
|
|
251
|
+
<circle cx="${size * 0.75}" cy="${size * 0.25}" r="${size * 0.08}" fill="${secondaryColor}" opacity="0.6"/>
|
|
252
|
+
<circle cx="${size * 0.25}" cy="${size * 0.75}" r="${size * 0.08}" fill="${secondaryColor}" opacity="0.6"/>
|
|
253
|
+
</svg>
|
|
254
|
+
`;
|
|
255
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ============================================
|
|
259
|
+
// WEST AFRICAN PATTERNS
|
|
260
|
+
// ============================================
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Generate Ghana Kente cloth pattern
|
|
264
|
+
* Royal cloth of the Ashanti people with geometric strips
|
|
265
|
+
* Colors: Gold (royalty), Green (harvest), Red (blood/sacrifice)
|
|
266
|
+
*/
|
|
267
|
+
export function generateKente({
|
|
268
|
+
colors = ['#FFD700', '#228B22', '#DC143C', '#000000'],
|
|
269
|
+
size = 60
|
|
270
|
+
} = {}) {
|
|
271
|
+
const [gold, green, red, black] = colors;
|
|
272
|
+
const stripe = size / 6;
|
|
273
|
+
|
|
274
|
+
const svg = `
|
|
275
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
276
|
+
<rect width="${size}" height="${size}" fill="${black}"/>
|
|
277
|
+
<!-- Horizontal bands -->
|
|
278
|
+
<rect x="0" y="0" width="${size}" height="${stripe}" fill="${gold}"/>
|
|
279
|
+
<rect x="0" y="${stripe}" width="${size}" height="${stripe}" fill="${green}"/>
|
|
280
|
+
<rect x="0" y="${stripe * 2}" width="${size}" height="${stripe}" fill="${red}"/>
|
|
281
|
+
<rect x="0" y="${stripe * 3}" width="${size}" height="${stripe}" fill="${gold}"/>
|
|
282
|
+
<rect x="0" y="${stripe * 4}" width="${size}" height="${stripe}" fill="${green}"/>
|
|
283
|
+
<rect x="0" y="${stripe * 5}" width="${size}" height="${stripe}" fill="${red}"/>
|
|
284
|
+
<!-- Vertical accents -->
|
|
285
|
+
<rect x="${size * 0.2}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
|
|
286
|
+
<rect x="${size * 0.4}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
|
|
287
|
+
<rect x="${size * 0.6}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
|
|
288
|
+
<rect x="${size * 0.8}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
|
|
289
|
+
<!-- Kente squares -->
|
|
290
|
+
<rect x="${size * 0.1}" y="${size * 0.1}" width="${size * 0.15}" height="${size * 0.15}" fill="${gold}" stroke="${black}" stroke-width="1"/>
|
|
291
|
+
<rect x="${size * 0.75}" y="${size * 0.75}" width="${size * 0.15}" height="${size * 0.15}" fill="${red}" stroke="${black}" stroke-width="1"/>
|
|
292
|
+
</svg>
|
|
293
|
+
`;
|
|
294
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Generate Ghana Adinkra symbols pattern
|
|
299
|
+
* Philosophical symbols of the Akan people
|
|
300
|
+
* Each symbol represents concepts like wisdom, strength, unity
|
|
301
|
+
*/
|
|
302
|
+
export function generateAdinkra({
|
|
303
|
+
symbolColor = '#000000',
|
|
304
|
+
backgroundColor = '#CD853F',
|
|
305
|
+
size = 50
|
|
306
|
+
} = {}) {
|
|
307
|
+
// Gye Nyame symbol (Supremacy of God) simplified
|
|
308
|
+
const svg = `
|
|
309
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
310
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
311
|
+
<!-- Sankofa-inspired heart shape (go back and get it) -->
|
|
312
|
+
<path d="M${size * 0.5} ${size * 0.2}
|
|
313
|
+
C${size * 0.3} ${size * 0.1} ${size * 0.15} ${size * 0.3} ${size * 0.25} ${size * 0.5}
|
|
314
|
+
L${size * 0.5} ${size * 0.8}
|
|
315
|
+
L${size * 0.75} ${size * 0.5}
|
|
316
|
+
C${size * 0.85} ${size * 0.3} ${size * 0.7} ${size * 0.1} ${size * 0.5} ${size * 0.2}"
|
|
317
|
+
fill="none" stroke="${symbolColor}" stroke-width="3"/>
|
|
318
|
+
<!-- Spiral detail -->
|
|
319
|
+
<circle cx="${size * 0.35}" cy="${size * 0.45}" r="${size * 0.08}" fill="none" stroke="${symbolColor}" stroke-width="2"/>
|
|
320
|
+
<circle cx="${size * 0.65}" cy="${size * 0.45}" r="${size * 0.08}" fill="none" stroke="${symbolColor}" stroke-width="2"/>
|
|
321
|
+
</svg>
|
|
322
|
+
`;
|
|
323
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Generate Nigeria Aso-Oke pattern (Yoruba)
|
|
328
|
+
* Hand-woven cloth with intricate strip patterns
|
|
329
|
+
* Traditional for special occasions
|
|
330
|
+
*/
|
|
331
|
+
export function generateAsoOke({
|
|
332
|
+
colors = ['#4B0082', '#FFD700', '#FFFFFF'],
|
|
333
|
+
size = 50
|
|
334
|
+
} = {}) {
|
|
335
|
+
const [indigo, gold, white] = colors;
|
|
336
|
+
const stripe = size / 10;
|
|
337
|
+
|
|
338
|
+
const svg = `
|
|
339
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
340
|
+
<rect width="${size}" height="${size}" fill="${indigo}"/>
|
|
341
|
+
<!-- Horizontal stripes -->
|
|
342
|
+
<rect x="0" y="${stripe}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
|
|
343
|
+
<rect x="0" y="${stripe * 3}" width="${size}" height="${stripe * 0.5}" fill="${white}"/>
|
|
344
|
+
<rect x="0" y="${stripe * 5}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
|
|
345
|
+
<rect x="0" y="${stripe * 7}" width="${size}" height="${stripe * 0.5}" fill="${white}"/>
|
|
346
|
+
<rect x="0" y="${stripe * 9}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
|
|
347
|
+
<!-- Vertical accent lines -->
|
|
348
|
+
<rect x="${size * 0.48}" y="0" width="${stripe * 0.4}" height="${size}" fill="${gold}" opacity="0.7"/>
|
|
349
|
+
<!-- Diamond motifs -->
|
|
350
|
+
<polygon points="${size * 0.25},${size * 0.3} ${size * 0.35},${size * 0.5} ${size * 0.25},${size * 0.7} ${size * 0.15},${size * 0.5}"
|
|
351
|
+
fill="${gold}" stroke="${white}" stroke-width="1"/>
|
|
352
|
+
<polygon points="${size * 0.75},${size * 0.3} ${size * 0.85},${size * 0.5} ${size * 0.75},${size * 0.7} ${size * 0.65},${size * 0.5}"
|
|
353
|
+
fill="${gold}" stroke="${white}" stroke-width="1"/>
|
|
354
|
+
</svg>
|
|
355
|
+
`;
|
|
356
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Generate Nigeria Ankara/African wax print pattern
|
|
361
|
+
* Bold, colorful designs popular across Africa
|
|
362
|
+
*/
|
|
363
|
+
export function generateAnkara({
|
|
364
|
+
primaryColor = '#FF6B00',
|
|
365
|
+
secondaryColor = '#00A86B',
|
|
366
|
+
accentColor = '#FFD700',
|
|
367
|
+
backgroundColor = '#FFFFFF',
|
|
368
|
+
size = 60
|
|
369
|
+
} = {}) {
|
|
370
|
+
const svg = `
|
|
371
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
372
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
373
|
+
<!-- Bold circular motifs -->
|
|
374
|
+
<circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.25}" fill="${primaryColor}"/>
|
|
375
|
+
<circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.15}" fill="${secondaryColor}"/>
|
|
376
|
+
<circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.08}" fill="${accentColor}"/>
|
|
377
|
+
|
|
378
|
+
<circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.2}" fill="${secondaryColor}"/>
|
|
379
|
+
<circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.1}" fill="${primaryColor}"/>
|
|
380
|
+
|
|
381
|
+
<!-- Connecting lines -->
|
|
382
|
+
<line x1="${size * 0.45}" y1="${size * 0.45}" x2="${size * 0.65}" y2="${size * 0.65}"
|
|
383
|
+
stroke="${primaryColor}" stroke-width="4"/>
|
|
384
|
+
|
|
385
|
+
<!-- Small dots -->
|
|
386
|
+
<circle cx="${size * 0.1}" cy="${size * 0.8}" r="${size * 0.05}" fill="${accentColor}"/>
|
|
387
|
+
<circle cx="${size * 0.9}" cy="${size * 0.2}" r="${size * 0.05}" fill="${accentColor}"/>
|
|
388
|
+
</svg>
|
|
389
|
+
`;
|
|
390
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// ============================================
|
|
394
|
+
// CENTRAL & NORTH AFRICAN PATTERNS
|
|
395
|
+
// ============================================
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Generate Bogolanfini (Mud Cloth) pattern (Mali)
|
|
399
|
+
* Geometric abstract designs in earth tones
|
|
400
|
+
*/
|
|
401
|
+
export function generateBogolan({
|
|
402
|
+
primaryColor = '#000000',
|
|
403
|
+
secondaryColor = '#FFFFFF',
|
|
404
|
+
accentColor = '#8B4513',
|
|
405
|
+
size = 60
|
|
406
|
+
} = {}) {
|
|
407
|
+
const svg = `
|
|
408
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
409
|
+
<rect width="${size}" height="${size}" fill="${primaryColor}"/>
|
|
410
|
+
<!-- Zigzags -->
|
|
411
|
+
<polyline points="0,${size * 0.2} ${size * 0.25},0 ${size * 0.5},${size * 0.2} ${size * 0.75},0 ${size},${size * 0.2}"
|
|
412
|
+
fill="none" stroke="${secondaryColor}" stroke-width="3"/>
|
|
413
|
+
<polyline points="0,${size * 0.8} ${size * 0.25},${size} ${size * 0.5},${size * 0.8} ${size * 0.75},${size} ${size},${size * 0.8}"
|
|
414
|
+
fill="none" stroke="${secondaryColor}" stroke-width="3"/>
|
|
415
|
+
<!-- Crosses -->
|
|
416
|
+
<line x1="${size * 0.25}" y1="${size * 0.4}" x2="${size * 0.25}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
417
|
+
<line x1="${size * 0.15}" y1="${size * 0.5}" x2="${size * 0.35}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
418
|
+
<line x1="${size * 0.75}" y1="${size * 0.4}" x2="${size * 0.75}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
419
|
+
<line x1="${size * 0.65}" y1="${size * 0.5}" x2="${size * 0.85}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
420
|
+
<!-- Dots -->
|
|
421
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.08}" fill="${accentColor}"/>
|
|
422
|
+
</svg>
|
|
423
|
+
`;
|
|
424
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Generate Kuba Shoowa pattern (DRC)
|
|
429
|
+
* Complex interlocking geometric shapes
|
|
430
|
+
*/
|
|
431
|
+
export function generateKuba({
|
|
432
|
+
primaryColor = '#D2B48C',
|
|
433
|
+
secondaryColor = '#3E2723',
|
|
434
|
+
size = 60
|
|
435
|
+
} = {}) {
|
|
436
|
+
const svg = `
|
|
437
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
438
|
+
<rect width="${size}" height="${size}" fill="${primaryColor}"/>
|
|
439
|
+
<!-- Interlocking diamonds/rectangles -->
|
|
440
|
+
<rect x="${size * 0.1}" y="${size * 0.1}" width="${size * 0.3}" height="${size * 0.3}" fill="${secondaryColor}"/>
|
|
441
|
+
<rect x="${size * 0.6}" y="${size * 0.6}" width="${size * 0.3}" height="${size * 0.3}" fill="${secondaryColor}"/>
|
|
442
|
+
<rect x="${size * 0.6}" y="${size * 0.1}" width="${size * 0.3}" height="${size * 0.3}"
|
|
443
|
+
fill="none" stroke="${secondaryColor}" stroke-width="4"/>
|
|
444
|
+
<rect x="${size * 0.1}" y="${size * 0.6}" width="${size * 0.3}" height="${size * 0.3}"
|
|
445
|
+
fill="none" stroke="${secondaryColor}" stroke-width="4"/>
|
|
446
|
+
<!-- Center lines -->
|
|
447
|
+
<line x1="${size * 0.4}" y1="${size * 0.5}" x2="${size * 0.6}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
448
|
+
<line x1="${size * 0.5}" y1="${size * 0.4}" x2="${size * 0.5}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
449
|
+
</svg>
|
|
450
|
+
`;
|
|
451
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Generate Imigongo pattern (Rwanda)
|
|
456
|
+
* Spiral/Geometric ridges traditionally made from cow dung
|
|
457
|
+
*/
|
|
458
|
+
export function generateImigongo({
|
|
459
|
+
primaryColor = '#000000',
|
|
460
|
+
secondaryColor = '#FFFFFF',
|
|
461
|
+
accentColor = '#B22222',
|
|
462
|
+
size = 60
|
|
463
|
+
} = {}) {
|
|
464
|
+
const svg = `
|
|
465
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
466
|
+
<rect width="${size}" height="${size}" fill="${secondaryColor}"/>
|
|
467
|
+
<!-- Spiral/Diamond Motif -->
|
|
468
|
+
<path d="M${size * 0.5} ${size * 0.1}
|
|
469
|
+
L${size * 0.9} ${size * 0.5}
|
|
470
|
+
L${size * 0.5} ${size * 0.9}
|
|
471
|
+
L${size * 0.1} ${size * 0.5} Z"
|
|
472
|
+
fill="${primaryColor}"/>
|
|
473
|
+
<path d="M${size * 0.5} ${size * 0.3}
|
|
474
|
+
L${size * 0.7} ${size * 0.5}
|
|
475
|
+
L${size * 0.5} ${size * 0.7}
|
|
476
|
+
L${size * 0.3} ${size * 0.5} Z"
|
|
477
|
+
fill="${secondaryColor}"/>
|
|
478
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${accentColor}"/>
|
|
479
|
+
</svg>
|
|
480
|
+
`;
|
|
481
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Generate Ethiopian Tibeb pattern
|
|
486
|
+
* Vibrant woven geometric borders
|
|
487
|
+
*/
|
|
488
|
+
export function generateTibeb({
|
|
489
|
+
colors = ['#009E60', '#FCDD09', '#EF3340'], // Ethiopian flag colors
|
|
490
|
+
backgroundColor = '#FFFFFF',
|
|
491
|
+
size = 40
|
|
492
|
+
} = {}) {
|
|
493
|
+
const [c1, c2, c3] = colors;
|
|
494
|
+
const svg = `
|
|
495
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
496
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
497
|
+
<!-- Diamond Chain -->
|
|
498
|
+
<polygon points="${size * 0.5},0 ${size},${size * 0.5} ${size * 0.5},${size} 0,${size * 0.5}"
|
|
499
|
+
fill="${c1}" opacity="0.2"/>
|
|
500
|
+
<polygon points="${size * 0.5},${size * 0.2} ${size * 0.8},${size * 0.5} ${size * 0.5},${size * 0.8} ${size * 0.2},${size * 0.5}"
|
|
501
|
+
fill="${c2}"/>
|
|
502
|
+
<rect x="${size * 0.4}" y="${size * 0.4}" width="${size * 0.2}" height="${size * 0.2}" fill="${c3}"/>
|
|
503
|
+
<!-- Side accents -->
|
|
504
|
+
<line x1="0" y1="0" x2="0" y2="${size}" stroke="${c1}" stroke-width="4"/>
|
|
505
|
+
<line x1="${size}" y1="0" x2="${size}" y2="${size}" stroke="${c1}" stroke-width="4"/>
|
|
506
|
+
</svg>
|
|
507
|
+
`;
|
|
508
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// ============================================
|
|
512
|
+
// SOUTHERN AFRICAN PATTERNS
|
|
513
|
+
// ============================================
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Generate Ndebele geometric mural pattern (South Africa)
|
|
517
|
+
*/
|
|
518
|
+
export function generateNdebele({
|
|
519
|
+
colors = ['#FFD700', '#4169E1', '#FF69B4', '#228B22'],
|
|
520
|
+
size = 60,
|
|
521
|
+
strokeWidth = 2
|
|
522
|
+
} = {}) {
|
|
523
|
+
const [c1, c2, c3, c4] = colors;
|
|
524
|
+
const svg = `
|
|
525
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
526
|
+
<rect width="${size}" height="${size}" fill="#FFFFFF"/>
|
|
527
|
+
<rect x="${strokeWidth}" y="${strokeWidth}"
|
|
528
|
+
width="${size - strokeWidth * 2}" height="${size - strokeWidth * 2}"
|
|
529
|
+
fill="none" stroke="#000000" stroke-width="${strokeWidth}"/>
|
|
530
|
+
<rect x="${size * 0.15}" y="${size * 0.15}" width="${size * 0.35}" height="${size * 0.35}"
|
|
531
|
+
fill="${c1}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
|
|
532
|
+
<rect x="${size * 0.5}" y="${size * 0.15}" width="${size * 0.35}" height="${size * 0.35}"
|
|
533
|
+
fill="${c2}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
|
|
534
|
+
<rect x="${size * 0.15}" y="${size * 0.5}" width="${size * 0.35}" height="${size * 0.35}"
|
|
535
|
+
fill="${c3}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
|
|
536
|
+
<rect x="${size * 0.5}" y="${size * 0.5}" width="${size * 0.35}" height="${size * 0.35}"
|
|
537
|
+
fill="${c4}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
|
|
538
|
+
<polygon points="${size / 2},${size * 0.3} ${size * 0.7},${size / 2} ${size / 2},${size * 0.7} ${size * 0.3},${size / 2}"
|
|
539
|
+
fill="#FFFFFF" stroke="#000000" stroke-width="${strokeWidth}"/>
|
|
540
|
+
</svg>
|
|
541
|
+
`;
|
|
542
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Generate Zulu beadwork pattern (South Africa)
|
|
547
|
+
* Traditional "love letter" beadwork with symbolic colors
|
|
548
|
+
* Colors carry deep meaning in Zulu courtship
|
|
549
|
+
*/
|
|
550
|
+
export function generateZulu({
|
|
551
|
+
colors = ['#FFFFFF', '#000000', '#FF0000', '#00A86B', '#FFD700'],
|
|
552
|
+
size = 50
|
|
553
|
+
} = {}) {
|
|
554
|
+
const [white, black, red, green, gold] = colors;
|
|
555
|
+
const bead = size / 10;
|
|
556
|
+
|
|
557
|
+
const svg = `
|
|
558
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
559
|
+
<rect width="${size}" height="${size}" fill="${black}"/>
|
|
560
|
+
<!-- Triangle pattern (isivivane - sacred cairn) -->
|
|
561
|
+
<polygon points="${size * 0.5},${size * 0.1} ${size * 0.9},${size * 0.9} ${size * 0.1},${size * 0.9}"
|
|
562
|
+
fill="none" stroke="${white}" stroke-width="2"/>
|
|
563
|
+
<polygon points="${size * 0.5},${size * 0.25} ${size * 0.75},${size * 0.75} ${size * 0.25},${size * 0.75}"
|
|
564
|
+
fill="${red}"/>
|
|
565
|
+
<!-- Beadwork dots -->
|
|
566
|
+
<circle cx="${size * 0.5}" cy="${size * 0.35}" r="${bead}" fill="${white}"/>
|
|
567
|
+
<circle cx="${size * 0.35}" cy="${size * 0.6}" r="${bead}" fill="${green}"/>
|
|
568
|
+
<circle cx="${size * 0.65}" cy="${size * 0.6}" r="${bead}" fill="${gold}"/>
|
|
569
|
+
<circle cx="${size * 0.5}" cy="${size * 0.8}" r="${bead}" fill="${white}"/>
|
|
570
|
+
<!-- Border dots -->
|
|
571
|
+
<circle cx="${size * 0.1}" cy="${size * 0.1}" r="${bead * 0.7}" fill="${red}"/>
|
|
572
|
+
<circle cx="${size * 0.9}" cy="${size * 0.1}" r="${bead * 0.7}" fill="${green}"/>
|
|
573
|
+
</svg>
|
|
574
|
+
`;
|
|
575
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Generate Swazi/Eswatini pattern
|
|
580
|
+
* Inspired by Ligwalagwala (purple-crested turaco) and royal patterns
|
|
581
|
+
* Traditional shields and ceremonial designs
|
|
582
|
+
*/
|
|
583
|
+
export function generateSwazi({
|
|
584
|
+
colors = ['#3E5EB9', '#FECD00', '#B10C0C', '#FFFFFF'],
|
|
585
|
+
size = 50
|
|
586
|
+
} = {}) {
|
|
587
|
+
const [blue, gold, red, white] = colors;
|
|
588
|
+
|
|
589
|
+
const svg = `
|
|
590
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
591
|
+
<rect width="${size}" height="${size}" fill="${blue}"/>
|
|
592
|
+
<!-- Shield shape (central to Eswatini culture) -->
|
|
593
|
+
<ellipse cx="${size * 0.5}" cy="${size * 0.45}" rx="${size * 0.35}" ry="${size * 0.4}"
|
|
594
|
+
fill="${gold}" stroke="${red}" stroke-width="3"/>
|
|
595
|
+
<!-- Inner pattern -->
|
|
596
|
+
<ellipse cx="${size * 0.5}" cy="${size * 0.45}" rx="${size * 0.2}" ry="${size * 0.25}"
|
|
597
|
+
fill="${red}"/>
|
|
598
|
+
<!-- Feather accents -->
|
|
599
|
+
<line x1="${size * 0.5}" y1="${size * 0.05}" x2="${size * 0.5}" y2="${size * 0.2}"
|
|
600
|
+
stroke="${white}" stroke-width="3"/>
|
|
601
|
+
<line x1="${size * 0.4}" y1="${size * 0.08}" x2="${size * 0.45}" y2="${size * 0.15}"
|
|
602
|
+
stroke="${white}" stroke-width="2"/>
|
|
603
|
+
<line x1="${size * 0.6}" y1="${size * 0.08}" x2="${size * 0.55}" y2="${size * 0.15}"
|
|
604
|
+
stroke="${white}" stroke-width="2"/>
|
|
605
|
+
<!-- Spear points -->
|
|
606
|
+
<polygon points="${size * 0.1},${size * 0.3} ${size * 0.05},${size * 0.5} ${size * 0.15},${size * 0.5}" fill="${white}"/>
|
|
607
|
+
<polygon points="${size * 0.9},${size * 0.3} ${size * 0.85},${size * 0.5} ${size * 0.95},${size * 0.5}" fill="${white}"/>
|
|
608
|
+
</svg>
|
|
609
|
+
`;
|
|
610
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Generate Xhosa pattern (South Africa)
|
|
615
|
+
* Inspired by traditional Xhosa beadwork and blanket designs
|
|
616
|
+
* Known for bold geometric patterns
|
|
617
|
+
*/
|
|
618
|
+
export function generateXhosa({
|
|
619
|
+
primaryColor = '#FFFFFF',
|
|
620
|
+
accentColor = '#00A86B',
|
|
621
|
+
backgroundColor = '#1a1a2e',
|
|
622
|
+
size = 50
|
|
623
|
+
} = {}) {
|
|
624
|
+
const svg = `
|
|
625
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
626
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
627
|
+
<!-- Horizontal bands -->
|
|
628
|
+
<rect x="0" y="${size * 0.2}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
|
|
629
|
+
<rect x="0" y="${size * 0.7}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
|
|
630
|
+
<!-- Vertical bands -->
|
|
631
|
+
<rect x="${size * 0.2}" y="0" width="${size * 0.1}" height="${size}" fill="${accentColor}"/>
|
|
632
|
+
<rect x="${size * 0.7}" y="0" width="${size * 0.1}" height="${size}" fill="${accentColor}"/>
|
|
633
|
+
<!-- Central diamond -->
|
|
634
|
+
<polygon points="${size * 0.5},${size * 0.35} ${size * 0.65},${size * 0.5} ${size * 0.5},${size * 0.65} ${size * 0.35},${size * 0.5}"
|
|
635
|
+
fill="${accentColor}" stroke="${primaryColor}" stroke-width="2"/>
|
|
636
|
+
<!-- Corner triangles -->
|
|
637
|
+
<polygon points="0,0 ${size * 0.15},0 0,${size * 0.15}" fill="${accentColor}"/>
|
|
638
|
+
<polygon points="${size},0 ${size * 0.85},0 ${size},${size * 0.15}" fill="${accentColor}"/>
|
|
639
|
+
<polygon points="0,${size} ${size * 0.15},${size} 0,${size * 0.85}" fill="${accentColor}"/>
|
|
640
|
+
<polygon points="${size},${size} ${size * 0.85},${size} ${size},${size * 0.85}" fill="${accentColor}"/>
|
|
641
|
+
</svg>
|
|
642
|
+
`;
|
|
643
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Apply pattern as background to an element
|
|
648
|
+
*/
|
|
649
|
+
export function applyPattern(element, patternUrl) {
|
|
650
|
+
element.style.backgroundImage = `url("${patternUrl}")`;
|
|
651
|
+
element.style.backgroundRepeat = 'repeat';
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// ============================================
|
|
655
|
+
// NORTH AFRICAN PATTERNS
|
|
656
|
+
// ============================================
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Generate Berber pattern (North Africa)
|
|
660
|
+
* Geometric designs inspired by Amazigh rugs and tattoos
|
|
661
|
+
* Symbols of protection, fertility, and nature
|
|
662
|
+
*/
|
|
663
|
+
export function generateBerber({
|
|
664
|
+
primaryColor = '#8B0000', // Deep red
|
|
665
|
+
secondaryColor = '#000000',
|
|
666
|
+
accentColor = '#FFD700',
|
|
667
|
+
backgroundColor = '#F5F5DC', // Beige/Wool
|
|
668
|
+
size = 60
|
|
669
|
+
} = {}) {
|
|
670
|
+
const svg = `
|
|
671
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
672
|
+
<rect width="${size}" height="${size}" fill="${backgroundColor}"/>
|
|
673
|
+
<!-- Lozenge (Diamond) - universal protective symbol -->
|
|
674
|
+
<polygon points="${size * 0.5},${size * 0.1} ${size * 0.9},${size * 0.5} ${size * 0.5},${size * 0.9} ${size * 0.1},${size * 0.5}"
|
|
675
|
+
fill="${primaryColor}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
676
|
+
<!-- Inner geometric details -->
|
|
677
|
+
<line x1="${size * 0.5}" y1="${size * 0.1}" x2="${size * 0.5}" y2="${size * 0.9}" stroke="${accentColor}" stroke-width="2"/>
|
|
678
|
+
<line x1="${size * 0.1}" y1="${size * 0.5}" x2="${size * 0.9}" y2="${size * 0.5}" stroke="${accentColor}" stroke-width="2"/>
|
|
679
|
+
<!-- X symbols (Fibula/Cross) -->
|
|
680
|
+
<line x1="${size * 0.4}" y1="${size * 0.4}" x2="${size * 0.6}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
681
|
+
<line x1="${size * 0.6}" y1="${size * 0.4}" x2="${size * 0.4}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
|
|
682
|
+
</svg>
|
|
683
|
+
`;
|
|
684
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Generate Adire Oniko (Yoruba Indigo) pattern
|
|
689
|
+
* Resist-dyed circles and ripples
|
|
690
|
+
* "Tie and dye" technique simulation
|
|
691
|
+
*/
|
|
692
|
+
export function generateAdire({
|
|
693
|
+
primaryColor = '#4B0082', // Indigo
|
|
694
|
+
secondaryColor = '#8A2BE2', // Light Indigo
|
|
695
|
+
accentColor = '#FFFFFF',
|
|
696
|
+
size = 50
|
|
697
|
+
} = {}) {
|
|
698
|
+
const svg = `
|
|
699
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
700
|
+
<rect width="${size}" height="${size}" fill="${primaryColor}"/>
|
|
701
|
+
<!-- Resist circles (Oniko) -->
|
|
702
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.35}" fill="none" stroke="${secondaryColor}" stroke-width="3"/>
|
|
703
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.25}" fill="none" stroke="${accentColor}" stroke-width="2" stroke-dasharray="4 2"/>
|
|
704
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${accentColor}" opacity="0.8"/>
|
|
705
|
+
<!-- Corner ripples -->
|
|
706
|
+
<path d="M0,0 Q${size * 0.2},0 ${size * 0.2},${size * 0.2} Q0,${size * 0.2} 0,0" fill="${secondaryColor}"/>
|
|
707
|
+
<path d="M${size},${size} Q${size * 0.8},${size} ${size * 0.8},${size * 0.8} Q${size},${size * 0.8} ${size},${size}" fill="${secondaryColor}"/>
|
|
708
|
+
</svg>
|
|
709
|
+
`;
|
|
710
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Export all generators
|
|
714
|
+
export default {
|
|
715
|
+
// East Africa
|
|
716
|
+
generatePolygon,
|
|
717
|
+
generateShuka,
|
|
718
|
+
generateHadzabe,
|
|
719
|
+
generateKanga,
|
|
720
|
+
generateKangaBorder,
|
|
721
|
+
generateKitenge,
|
|
722
|
+
generateMasaiShield,
|
|
723
|
+
generateTibeb, // Ethiopia
|
|
724
|
+
generateImigongo, // Rwanda
|
|
725
|
+
// West Africa
|
|
726
|
+
generateKente,
|
|
727
|
+
generateAdinkra,
|
|
728
|
+
generateAsoOke,
|
|
729
|
+
generateAnkara,
|
|
730
|
+
generateBogolan, // Mali/West
|
|
731
|
+
generateAdire, // Nigeria (Indigo)
|
|
732
|
+
// Central Africa
|
|
733
|
+
generateKuba, // DRC
|
|
734
|
+
generateKubaBorder,
|
|
735
|
+
// North Africa
|
|
736
|
+
generateBerber, // Amazigh
|
|
737
|
+
// Southern Africa
|
|
738
|
+
generateNdebele,
|
|
739
|
+
generateNdebelePaint,
|
|
740
|
+
generateZulu,
|
|
741
|
+
generateZuluBeads,
|
|
742
|
+
generateSwazi,
|
|
743
|
+
generateXhosa,
|
|
744
|
+
// Utilities
|
|
745
|
+
applyPattern,
|
|
746
|
+
// Tech Patterns
|
|
747
|
+
generateTuareg,
|
|
748
|
+
generateGeez,
|
|
749
|
+
generateBoli,
|
|
750
|
+
generateCircuit,
|
|
751
|
+
circuit: generateCircuit
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Generate Tuareg Indigo pattern (Sahara/Berber)
|
|
756
|
+
* Inspired by the "Blue Men of the Sahara" and their geometric silver jewelry/stars
|
|
757
|
+
*/
|
|
758
|
+
export function generateTuareg({
|
|
759
|
+
primaryColor = '#2D3D6B', // Tuareg Indigo
|
|
760
|
+
secondaryColor = '#6B8CC7', // Sky Blue
|
|
761
|
+
accentColor = '#FFFFFF', // Silver/White
|
|
762
|
+
size = 60
|
|
763
|
+
} = {}) {
|
|
764
|
+
const svg = `
|
|
765
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
766
|
+
<rect width="${size}" height="${size}" fill="${primaryColor}"/>
|
|
767
|
+
<!-- Southern Cross / Tuareg Star -->
|
|
768
|
+
<path d="M${size * 0.5} 0 L${size * 0.6} ${size * 0.4} L${size} ${size * 0.5} L${size * 0.6} ${size * 0.6} L${size * 0.5} ${size} L${size * 0.4} ${size * 0.6} L0 ${size * 0.5} L${size * 0.4} ${size * 0.4} Z"
|
|
769
|
+
fill="none" stroke="${accentColor}" stroke-width="2"/>
|
|
770
|
+
<circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${secondaryColor}"/>
|
|
771
|
+
</svg>
|
|
772
|
+
`;
|
|
773
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Generate Ge'ez Script pattern (Ethiopia/Eritrea)
|
|
778
|
+
* Abstract calligraphic strokes inspired by one of the world's oldest scripts
|
|
779
|
+
*/
|
|
780
|
+
export function generateGeez({
|
|
781
|
+
inkColor = '#3A2E2C',
|
|
782
|
+
parchmentColor = '#F4E4BC',
|
|
783
|
+
size = 50
|
|
784
|
+
} = {}) {
|
|
785
|
+
const svg = `
|
|
786
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
787
|
+
<rect width="${size}" height="${size}" fill="${parchmentColor}"/>
|
|
788
|
+
<path d="M${size * 0.2} ${size * 0.2} L${size * 0.4} ${size * 0.2} M${size * 0.3} ${size * 0.2} L${size * 0.3} ${size * 0.5} Q${size * 0.4} ${size * 0.6} ${size * 0.2} ${size * 0.7}"
|
|
789
|
+
fill="none" stroke="${inkColor}" stroke-width="3" stroke-linecap="round"/>
|
|
790
|
+
<path d="M${size * 0.6} ${size * 0.3} C${size * 0.8} ${size * 0.3} ${size * 0.8} ${size * 0.6} ${size * 0.6} ${size * 0.6} L${size * 0.8} ${size * 0.8}"
|
|
791
|
+
fill="none" stroke="${inkColor}" stroke-width="3" stroke-linecap="round"/>
|
|
792
|
+
</svg>
|
|
793
|
+
`;
|
|
794
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Generate Boli pattern (Mali/Bambara)
|
|
799
|
+
* Abstract organic shapes inspired by mud-based ritual objects
|
|
800
|
+
*/
|
|
801
|
+
export function generateBoli({
|
|
802
|
+
clayColor = '#4E342E',
|
|
803
|
+
earthColor = '#3E2723',
|
|
804
|
+
accentColor = '#BCAAA4',
|
|
805
|
+
size = 60
|
|
806
|
+
} = {}) {
|
|
807
|
+
const svg = `
|
|
808
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
809
|
+
<rect width="${size}" height="${size}" fill="${earthColor}"/>
|
|
810
|
+
<path d="M${size * 0.2} ${size * 0.5} Q${size * 0.3} ${size * 0.2} ${size * 0.5} ${size * 0.3} T${size * 0.8} ${size * 0.5} Q${size * 0.7} ${size * 0.8} ${size * 0.5} ${size * 0.7} T${size * 0.2} ${size * 0.5}"
|
|
811
|
+
fill="${clayColor}" stroke="${accentColor}" stroke-width="2"/>
|
|
812
|
+
</svg>
|
|
813
|
+
`;
|
|
814
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
export function generateCircuit({
|
|
818
|
+
primaryColor = '#334155',
|
|
819
|
+
secondaryColor = '#1e293b',
|
|
820
|
+
size = 100
|
|
821
|
+
} = {}) {
|
|
822
|
+
const svg = `
|
|
823
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 100 100">
|
|
824
|
+
<rect width="100" height="100" fill="${secondaryColor}"/>
|
|
825
|
+
<path d="M10 10 H90 V90 H10 Z" fill="none" stroke="${primaryColor}" stroke-width="0.5" opacity="0.3"/>
|
|
826
|
+
<path d="M20 20 V50 H50 V80 H80" fill="none" stroke="${primaryColor}" stroke-width="1"/>
|
|
827
|
+
<circle cx="20" cy="20" r="2" fill="${primaryColor}"/>
|
|
828
|
+
<circle cx="80" cy="80" r="2" fill="${primaryColor}"/>
|
|
829
|
+
<circle cx="50" cy="50" r="1.5" fill="${primaryColor}"/>
|
|
830
|
+
</svg>
|
|
831
|
+
`;
|
|
832
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
|
|
833
|
+
}
|