@principal-ai/logo-component 0.1.4 → 0.1.6

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.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Single-stroke character definitions for TextReveal component.
3
+ * Each character is defined as a set of simple SVG paths that particles can trace.
4
+ * Coordinates use a consistent cell: 0-40 width, 0-60 height, baseline at y=60.
5
+ */
6
+ export interface CharacterPath {
7
+ d: string;
8
+ id: string;
9
+ }
10
+ export interface CharacterDefinition {
11
+ paths: CharacterPath[];
12
+ width: number;
13
+ }
14
+ export declare const STROKE_CHARACTERS: Record<string, CharacterDefinition>;
15
+ /**
16
+ * Layout text and return positioned paths
17
+ */
18
+ export interface PositionedPath {
19
+ d: string;
20
+ id: string;
21
+ charIndex: number;
22
+ char: string;
23
+ }
24
+ export declare function layoutText(text: string, options?: {
25
+ x?: number;
26
+ y?: number;
27
+ letterSpacing?: number;
28
+ scale?: number;
29
+ }): {
30
+ paths: PositionedPath[];
31
+ width: number;
32
+ height: number;
33
+ };
@@ -0,0 +1,521 @@
1
+ "use strict";
2
+ /**
3
+ * Single-stroke character definitions for TextReveal component.
4
+ * Each character is defined as a set of simple SVG paths that particles can trace.
5
+ * Coordinates use a consistent cell: 0-40 width, 0-60 height, baseline at y=60.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.STROKE_CHARACTERS = void 0;
9
+ exports.layoutText = layoutText;
10
+ exports.STROKE_CHARACTERS = {
11
+ // Uppercase letters
12
+ A: {
13
+ paths: [
14
+ { d: "M 2,60 L 20,4 L 38,60", id: "a-legs" },
15
+ { d: "M 10,38 L 30,38", id: "a-bar" },
16
+ ],
17
+ width: 42,
18
+ },
19
+ B: {
20
+ paths: [
21
+ { d: "M 4,60 L 4,4", id: "b-stem" },
22
+ { d: "M 4,4 L 24,4 Q 34,4 34,16 Q 34,28 24,32 L 4,32", id: "b-top" },
23
+ { d: "M 4,32 L 26,32 Q 38,32 38,46 Q 38,60 26,60 L 4,60", id: "b-bot" },
24
+ ],
25
+ width: 42,
26
+ },
27
+ C: {
28
+ paths: [
29
+ { d: "M 36,12 Q 20,0 8,16 Q 0,28 0,32 Q 0,48 8,52 Q 20,64 36,52", id: "c-arc" },
30
+ ],
31
+ width: 40,
32
+ },
33
+ D: {
34
+ paths: [
35
+ { d: "M 4,60 L 4,4", id: "d-stem" },
36
+ { d: "M 4,4 L 20,4 Q 38,4 38,32 Q 38,60 20,60 L 4,60", id: "d-arc" },
37
+ ],
38
+ width: 42,
39
+ },
40
+ E: {
41
+ paths: [
42
+ { d: "M 4,60 L 4,4", id: "e-stem" },
43
+ { d: "M 4,4 L 34,4", id: "e-top" },
44
+ { d: "M 4,32 L 28,32", id: "e-mid" },
45
+ { d: "M 4,60 L 34,60", id: "e-bot" },
46
+ ],
47
+ width: 38,
48
+ },
49
+ F: {
50
+ paths: [
51
+ { d: "M 4,60 L 4,4", id: "f-stem" },
52
+ { d: "M 4,4 L 34,4", id: "f-top" },
53
+ { d: "M 4,32 L 26,32", id: "f-mid" },
54
+ ],
55
+ width: 36,
56
+ },
57
+ G: {
58
+ paths: [
59
+ { d: "M 36,12 Q 20,0 8,16 Q 0,28 0,32 Q 0,48 8,52 Q 20,64 36,52 L 36,36 L 22,36", id: "g-shape" },
60
+ ],
61
+ width: 42,
62
+ },
63
+ H: {
64
+ paths: [
65
+ { d: "M 4,60 L 4,4", id: "h-left" },
66
+ { d: "M 36,60 L 36,4", id: "h-right" },
67
+ { d: "M 4,32 L 36,32", id: "h-bar" },
68
+ ],
69
+ width: 42,
70
+ },
71
+ I: {
72
+ paths: [
73
+ { d: "M 20,4 L 20,60", id: "i-stem" },
74
+ { d: "M 8,4 L 32,4", id: "i-top" },
75
+ { d: "M 8,60 L 32,60", id: "i-bot" },
76
+ ],
77
+ width: 36,
78
+ },
79
+ J: {
80
+ paths: [
81
+ { d: "M 28,4 L 28,48 Q 28,60 16,60 Q 4,60 4,48", id: "j-hook" },
82
+ ],
83
+ width: 34,
84
+ },
85
+ K: {
86
+ paths: [
87
+ { d: "M 4,60 L 4,4", id: "k-stem" },
88
+ { d: "M 34,4 L 4,36 L 36,60", id: "k-legs" },
89
+ ],
90
+ width: 40,
91
+ },
92
+ L: {
93
+ paths: [
94
+ { d: "M 4,4 L 4,60 L 34,60", id: "l-shape" },
95
+ ],
96
+ width: 38,
97
+ },
98
+ M: {
99
+ paths: [
100
+ { d: "M 4,60 L 4,4 L 22,32 L 40,4 L 40,60", id: "m-shape" },
101
+ ],
102
+ width: 46,
103
+ },
104
+ N: {
105
+ paths: [
106
+ { d: "M 4,60 L 4,4 L 36,60 L 36,4", id: "n-shape" },
107
+ ],
108
+ width: 42,
109
+ },
110
+ O: {
111
+ paths: [
112
+ { d: "M 20,4 Q 4,4 4,32 Q 4,60 20,60 Q 36,60 36,32 Q 36,4 20,4 Z", id: "o-circle" },
113
+ ],
114
+ width: 42,
115
+ },
116
+ P: {
117
+ paths: [
118
+ { d: "M 4,60 L 4,4", id: "p-stem" },
119
+ { d: "M 4,4 L 24,4 Q 36,4 36,18 Q 36,32 24,32 L 4,32", id: "p-bowl" },
120
+ ],
121
+ width: 40,
122
+ },
123
+ Q: {
124
+ paths: [
125
+ { d: "M 20,4 Q 4,4 4,32 Q 4,60 20,60 Q 36,60 36,32 Q 36,4 20,4 Z", id: "q-circle" },
126
+ { d: "M 26,48 L 40,64", id: "q-tail" },
127
+ ],
128
+ width: 44,
129
+ },
130
+ R: {
131
+ paths: [
132
+ { d: "M 4,60 L 4,4", id: "r-stem" },
133
+ { d: "M 4,4 L 24,4 Q 36,4 36,18 Q 36,32 24,32 L 4,32", id: "r-bowl" },
134
+ { d: "M 22,32 L 38,60", id: "r-leg" },
135
+ ],
136
+ width: 42,
137
+ },
138
+ S: {
139
+ paths: [
140
+ { d: "M 34,12 Q 34,4 20,4 Q 4,4 4,16 Q 4,28 20,32 Q 36,36 36,48 Q 36,60 20,60 Q 4,60 4,52", id: "s-curve" },
141
+ ],
142
+ width: 40,
143
+ },
144
+ T: {
145
+ paths: [
146
+ { d: "M 4,4 L 36,4", id: "t-top" },
147
+ { d: "M 20,4 L 20,60", id: "t-stem" },
148
+ ],
149
+ width: 40,
150
+ },
151
+ U: {
152
+ paths: [
153
+ { d: "M 4,4 L 4,46 Q 4,60 20,60 Q 36,60 36,46 L 36,4", id: "u-shape" },
154
+ ],
155
+ width: 42,
156
+ },
157
+ V: {
158
+ paths: [
159
+ { d: "M 2,4 L 20,60 L 38,4", id: "v-shape" },
160
+ ],
161
+ width: 42,
162
+ },
163
+ W: {
164
+ paths: [
165
+ { d: "M 0,4 L 10,60 L 22,28 L 34,60 L 44,4", id: "w-shape" },
166
+ ],
167
+ width: 48,
168
+ },
169
+ X: {
170
+ paths: [
171
+ { d: "M 4,4 L 36,60", id: "x-down" },
172
+ { d: "M 36,4 L 4,60", id: "x-up" },
173
+ ],
174
+ width: 42,
175
+ },
176
+ Y: {
177
+ paths: [
178
+ { d: "M 4,4 L 20,32 L 36,4", id: "y-arms" },
179
+ { d: "M 20,32 L 20,60", id: "y-stem" },
180
+ ],
181
+ width: 42,
182
+ },
183
+ Z: {
184
+ paths: [
185
+ { d: "M 4,4 L 36,4 L 4,60 L 36,60", id: "z-shape" },
186
+ ],
187
+ width: 42,
188
+ },
189
+ // Numbers
190
+ "0": {
191
+ paths: [
192
+ { d: "M 20,4 Q 4,4 4,32 Q 4,60 20,60 Q 36,60 36,32 Q 36,4 20,4 Z", id: "0-circle" },
193
+ { d: "M 12,48 L 28,16", id: "0-slash" },
194
+ ],
195
+ width: 42,
196
+ },
197
+ "1": {
198
+ paths: [
199
+ { d: "M 10,16 L 22,4 L 22,60", id: "1-shape" },
200
+ { d: "M 12,60 L 32,60", id: "1-base" },
201
+ ],
202
+ width: 38,
203
+ },
204
+ "2": {
205
+ paths: [
206
+ { d: "M 4,16 Q 4,4 20,4 Q 36,4 36,16 Q 36,28 4,60 L 36,60", id: "2-shape" },
207
+ ],
208
+ width: 42,
209
+ },
210
+ "3": {
211
+ paths: [
212
+ { d: "M 4,12 Q 4,4 20,4 Q 36,4 36,18 Q 36,32 20,32 Q 36,32 36,46 Q 36,60 20,60 Q 4,60 4,52", id: "3-shape" },
213
+ ],
214
+ width: 42,
215
+ },
216
+ "4": {
217
+ paths: [
218
+ { d: "M 28,60 L 28,4 L 4,44 L 38,44", id: "4-shape" },
219
+ ],
220
+ width: 42,
221
+ },
222
+ "5": {
223
+ paths: [
224
+ { d: "M 34,4 L 6,4 L 4,28 Q 4,28 20,28 Q 36,28 36,44 Q 36,60 20,60 Q 4,60 4,52", id: "5-shape" },
225
+ ],
226
+ width: 42,
227
+ },
228
+ "6": {
229
+ paths: [
230
+ { d: "M 32,8 Q 20,4 10,16 Q 4,28 4,44 Q 4,60 20,60 Q 36,60 36,44 Q 36,28 20,28 Q 4,28 4,44", id: "6-shape" },
231
+ ],
232
+ width: 42,
233
+ },
234
+ "7": {
235
+ paths: [
236
+ { d: "M 4,4 L 36,4 L 16,60", id: "7-shape" },
237
+ ],
238
+ width: 42,
239
+ },
240
+ "8": {
241
+ paths: [
242
+ { d: "M 20,32 Q 6,32 6,18 Q 6,4 20,4 Q 34,4 34,18 Q 34,32 20,32 Q 4,32 4,46 Q 4,60 20,60 Q 36,60 36,46 Q 36,32 20,32", id: "8-shape" },
243
+ ],
244
+ width: 42,
245
+ },
246
+ "9": {
247
+ paths: [
248
+ { d: "M 8,56 Q 20,60 30,48 Q 36,36 36,20 Q 36,4 20,4 Q 4,4 4,20 Q 4,36 20,36 Q 36,36 36,20", id: "9-shape" },
249
+ ],
250
+ width: 42,
251
+ },
252
+ // Punctuation & special
253
+ " ": {
254
+ paths: [],
255
+ width: 20,
256
+ },
257
+ ".": {
258
+ paths: [
259
+ { d: "M 8,56 L 12,56 L 12,60 L 8,60 Z", id: "period" },
260
+ ],
261
+ width: 20,
262
+ },
263
+ ",": {
264
+ paths: [
265
+ { d: "M 12,56 L 8,66", id: "comma" },
266
+ ],
267
+ width: 20,
268
+ },
269
+ "!": {
270
+ paths: [
271
+ { d: "M 10,4 L 10,42", id: "exclaim-stem" },
272
+ { d: "M 8,56 L 12,56 L 12,60 L 8,60 Z", id: "exclaim-dot" },
273
+ ],
274
+ width: 20,
275
+ },
276
+ "?": {
277
+ paths: [
278
+ { d: "M 4,12 Q 4,4 18,4 Q 32,4 32,16 Q 32,28 18,32 L 18,42", id: "question-curve" },
279
+ { d: "M 16,56 L 20,56 L 20,60 L 16,60 Z", id: "question-dot" },
280
+ ],
281
+ width: 36,
282
+ },
283
+ "-": {
284
+ paths: [
285
+ { d: "M 4,32 L 28,32", id: "hyphen" },
286
+ ],
287
+ width: 32,
288
+ },
289
+ ":": {
290
+ paths: [
291
+ { d: "M 8,20 L 12,20 L 12,24 L 8,24 Z", id: "colon-top" },
292
+ { d: "M 8,48 L 12,48 L 12,52 L 8,52 Z", id: "colon-bot" },
293
+ ],
294
+ width: 20,
295
+ },
296
+ "/": {
297
+ paths: [
298
+ { d: "M 4,60 L 28,4", id: "slash" },
299
+ ],
300
+ width: 32,
301
+ },
302
+ // Lowercase (simplified - same height as uppercase for now)
303
+ a: {
304
+ paths: [
305
+ { d: "M 30,24 Q 30,16 18,16 Q 6,16 6,32 Q 6,48 18,48 Q 30,48 30,32 L 30,16 L 30,48", id: "a-lower" },
306
+ ],
307
+ width: 36,
308
+ },
309
+ b: {
310
+ paths: [
311
+ { d: "M 6,4 L 6,48", id: "b-stem-lower" },
312
+ { d: "M 6,32 Q 6,16 20,16 Q 34,16 34,32 Q 34,48 20,48 Q 6,48 6,32", id: "b-bowl-lower" },
313
+ ],
314
+ width: 38,
315
+ },
316
+ c: {
317
+ paths: [
318
+ { d: "M 32,20 Q 18,14 10,24 Q 6,32 10,40 Q 18,50 32,44", id: "c-lower" },
319
+ ],
320
+ width: 36,
321
+ },
322
+ d: {
323
+ paths: [
324
+ { d: "M 30,4 L 30,48", id: "d-stem-lower" },
325
+ { d: "M 30,32 Q 30,16 16,16 Q 2,16 2,32 Q 2,48 16,48 Q 30,48 30,32", id: "d-bowl-lower" },
326
+ ],
327
+ width: 36,
328
+ },
329
+ e: {
330
+ paths: [
331
+ { d: "M 6,32 L 32,32 Q 32,16 18,16 Q 4,16 4,32 Q 4,48 18,48 Q 32,48 32,42", id: "e-lower" },
332
+ ],
333
+ width: 38,
334
+ },
335
+ f: {
336
+ paths: [
337
+ { d: "M 28,8 Q 20,4 14,12 L 14,48", id: "f-stem-lower" },
338
+ { d: "M 4,24 L 26,24", id: "f-bar-lower" },
339
+ ],
340
+ width: 30,
341
+ },
342
+ g: {
343
+ paths: [
344
+ { d: "M 30,16 L 30,56 Q 30,66 16,66 Q 4,66 4,58", id: "g-stem-lower" },
345
+ { d: "M 30,32 Q 30,16 16,16 Q 2,16 2,32 Q 2,48 16,48 Q 30,48 30,32", id: "g-bowl-lower" },
346
+ ],
347
+ width: 36,
348
+ },
349
+ h: {
350
+ paths: [
351
+ { d: "M 6,4 L 6,48", id: "h-stem-lower" },
352
+ { d: "M 6,28 Q 6,16 20,16 Q 32,16 32,28 L 32,48", id: "h-arch-lower" },
353
+ ],
354
+ width: 38,
355
+ },
356
+ i: {
357
+ paths: [
358
+ { d: "M 10,20 L 10,48", id: "i-stem-lower" },
359
+ { d: "M 8,8 L 12,8 L 12,12 L 8,12 Z", id: "i-dot-lower" },
360
+ ],
361
+ width: 22,
362
+ },
363
+ j: {
364
+ paths: [
365
+ { d: "M 18,20 L 18,56 Q 18,66 6,66", id: "j-hook-lower" },
366
+ { d: "M 16,8 L 20,8 L 20,12 L 16,12 Z", id: "j-dot-lower" },
367
+ ],
368
+ width: 26,
369
+ },
370
+ k: {
371
+ paths: [
372
+ { d: "M 6,4 L 6,48", id: "k-stem-lower" },
373
+ { d: "M 30,16 L 6,36 L 32,48", id: "k-legs-lower" },
374
+ ],
375
+ width: 36,
376
+ },
377
+ l: {
378
+ paths: [
379
+ { d: "M 10,4 L 10,48", id: "l-stem-lower" },
380
+ ],
381
+ width: 20,
382
+ },
383
+ m: {
384
+ paths: [
385
+ { d: "M 4,48 L 4,24 Q 4,16 14,16 Q 24,16 24,24 L 24,48", id: "m-left-lower" },
386
+ { d: "M 24,24 Q 24,16 34,16 Q 44,16 44,24 L 44,48", id: "m-right-lower" },
387
+ ],
388
+ width: 50,
389
+ },
390
+ n: {
391
+ paths: [
392
+ { d: "M 6,48 L 6,16", id: "n-stem-lower" },
393
+ { d: "M 6,28 Q 6,16 20,16 Q 32,16 32,28 L 32,48", id: "n-arch-lower" },
394
+ ],
395
+ width: 38,
396
+ },
397
+ o: {
398
+ paths: [
399
+ { d: "M 18,16 Q 4,16 4,32 Q 4,48 18,48 Q 32,48 32,32 Q 32,16 18,16 Z", id: "o-lower" },
400
+ ],
401
+ width: 38,
402
+ },
403
+ p: {
404
+ paths: [
405
+ { d: "M 6,16 L 6,64", id: "p-stem-lower" },
406
+ { d: "M 6,32 Q 6,16 20,16 Q 34,16 34,32 Q 34,48 20,48 Q 6,48 6,32", id: "p-bowl-lower" },
407
+ ],
408
+ width: 38,
409
+ },
410
+ q: {
411
+ paths: [
412
+ { d: "M 30,16 L 30,64", id: "q-stem-lower" },
413
+ { d: "M 30,32 Q 30,16 16,16 Q 2,16 2,32 Q 2,48 16,48 Q 30,48 30,32", id: "q-bowl-lower" },
414
+ ],
415
+ width: 36,
416
+ },
417
+ r: {
418
+ paths: [
419
+ { d: "M 6,48 L 6,16", id: "r-stem-lower" },
420
+ { d: "M 6,28 Q 6,16 20,16 Q 28,16 30,22", id: "r-shoulder-lower" },
421
+ ],
422
+ width: 32,
423
+ },
424
+ s: {
425
+ paths: [
426
+ { d: "M 28,20 Q 28,16 18,16 Q 6,16 6,24 Q 6,32 18,32 Q 30,32 30,40 Q 30,48 18,48 Q 6,48 6,44", id: "s-lower" },
427
+ ],
428
+ width: 36,
429
+ },
430
+ t: {
431
+ paths: [
432
+ { d: "M 16,4 L 16,44 Q 16,48 24,48", id: "t-stem-lower" },
433
+ { d: "M 6,16 L 28,16", id: "t-bar-lower" },
434
+ ],
435
+ width: 30,
436
+ },
437
+ u: {
438
+ paths: [
439
+ { d: "M 6,16 L 6,36 Q 6,48 18,48 Q 30,48 30,36 L 30,16 L 30,48", id: "u-lower" },
440
+ ],
441
+ width: 38,
442
+ },
443
+ v: {
444
+ paths: [
445
+ { d: "M 4,16 L 18,48 L 32,16", id: "v-lower" },
446
+ ],
447
+ width: 38,
448
+ },
449
+ w: {
450
+ paths: [
451
+ { d: "M 2,16 L 10,48 L 20,28 L 30,48 L 38,16", id: "w-lower" },
452
+ ],
453
+ width: 42,
454
+ },
455
+ x: {
456
+ paths: [
457
+ { d: "M 6,16 L 30,48", id: "x-down-lower" },
458
+ { d: "M 30,16 L 6,48", id: "x-up-lower" },
459
+ ],
460
+ width: 38,
461
+ },
462
+ y: {
463
+ paths: [
464
+ { d: "M 6,16 L 18,40", id: "y-left-lower" },
465
+ { d: "M 30,16 L 10,64", id: "y-right-lower" },
466
+ ],
467
+ width: 38,
468
+ },
469
+ z: {
470
+ paths: [
471
+ { d: "M 6,16 L 30,16 L 6,48 L 30,48", id: "z-lower" },
472
+ ],
473
+ width: 38,
474
+ },
475
+ };
476
+ function layoutText(text, options = {}) {
477
+ const { x = 0, y = 0, letterSpacing = 4, scale = 1 } = options;
478
+ const paths = [];
479
+ let currentX = x;
480
+ for (let i = 0; i < text.length; i++) {
481
+ const char = text[i];
482
+ const charDef = exports.STROKE_CHARACTERS[char] || exports.STROKE_CHARACTERS[char.toUpperCase()];
483
+ if (charDef) {
484
+ for (const path of charDef.paths) {
485
+ // Transform the path to the current position
486
+ const transformedD = transformPath(path.d, currentX, y, scale);
487
+ paths.push({
488
+ d: transformedD,
489
+ id: `${path.id}-${i}`,
490
+ charIndex: i,
491
+ char,
492
+ });
493
+ }
494
+ currentX += (charDef.width + letterSpacing) * scale;
495
+ }
496
+ }
497
+ return {
498
+ paths,
499
+ width: currentX - x,
500
+ height: 60 * scale,
501
+ };
502
+ }
503
+ /**
504
+ * Transform path coordinates by offset and scale
505
+ */
506
+ function transformPath(d, offsetX, offsetY, scale) {
507
+ // Match all coordinate pairs in the path
508
+ return d.replace(/-?\d+\.?\d*/g, (match, offset, fullString) => {
509
+ const num = parseFloat(match);
510
+ // Determine if this is an X or Y coordinate by counting preceding numbers
511
+ const before = fullString.substring(0, offset);
512
+ const numCount = (before.match(/-?\d+\.?\d*/g) || []).length;
513
+ const isY = numCount % 2 === 1;
514
+ if (isY) {
515
+ return String(num * scale + offsetY);
516
+ }
517
+ else {
518
+ return String(num * scale + offsetX);
519
+ }
520
+ });
521
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/logo-component",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Animated wireframe sphere logo component",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -30,6 +30,7 @@
30
30
  "@storybook/blocks": "^8.6.14",
31
31
  "@storybook/react": "^8.6.14",
32
32
  "@storybook/react-vite": "^8.6.14",
33
+ "@types/opentype.js": "^1.3.9",
33
34
  "@types/react": "^19.1.12",
34
35
  "@vitejs/plugin-react": "^4.7.0",
35
36
  "react": "^19.1.1",
@@ -37,5 +38,8 @@
37
38
  "storybook": "^8.6.14",
38
39
  "typescript": "^5",
39
40
  "vite": "^5.4.20"
41
+ },
42
+ "dependencies": {
43
+ "opentype.js": "^1.3.4"
40
44
  }
41
45
  }