@shopify/klint 0.0.91 → 0.0.92

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,946 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/elements/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Color: () => Color_default,
24
+ Easing: () => Easing_default,
25
+ State: () => State_default,
26
+ Text: () => Text_default,
27
+ Thing: () => Thing_default,
28
+ Time: () => Time_default,
29
+ Vector: () => Vector_default
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/elements/Color.tsx
34
+ var Color = class {
35
+ constructor() {
36
+ // context: KlintContexts;
37
+ /**
38
+ * Array of predefined colors in the Klint color palette
39
+ */
40
+ this.colors = [
41
+ "#E84D37",
42
+ // coral
43
+ "#7F4C2F",
44
+ // brown
45
+ "#EDBC2F",
46
+ // mustard
47
+ "#BF3034",
48
+ // crimson
49
+ "#18599D",
50
+ // navy
51
+ "#45A7C6",
52
+ // sky
53
+ "#8CB151",
54
+ // olive
55
+ "#252120",
56
+ // charcoal
57
+ "#ECA088",
58
+ // peach
59
+ "#C9B1B8",
60
+ // rose
61
+ "#8F3064",
62
+ // plum
63
+ "#7B8870",
64
+ // sage
65
+ "#C0C180",
66
+ // drab
67
+ "#4B423D",
68
+ // taupe
69
+ "#1A2A65",
70
+ // midnight
71
+ "#EAA550",
72
+ // golden
73
+ "#F17B04",
74
+ // orange
75
+ "#404757"
76
+ // slate
77
+ ];
78
+ }
79
+ // /**
80
+ // * Creates a new Color instance
81
+ // * @param ctx - The Klint context
82
+ // */
83
+ // constructor(ctx: KlintContexts) {
84
+ // this.context = ctx;
85
+ // }
86
+ get coral() {
87
+ return this.colors[0];
88
+ }
89
+ get brown() {
90
+ return this.colors[1];
91
+ }
92
+ get mustard() {
93
+ return this.colors[2];
94
+ }
95
+ get crimson() {
96
+ return this.colors[3];
97
+ }
98
+ get navy() {
99
+ return this.colors[4];
100
+ }
101
+ get sky() {
102
+ return this.colors[5];
103
+ }
104
+ get olive() {
105
+ return this.colors[6];
106
+ }
107
+ get charcoal() {
108
+ return this.colors[7];
109
+ }
110
+ get peach() {
111
+ return this.colors[8];
112
+ }
113
+ get rose() {
114
+ return this.colors[9];
115
+ }
116
+ get plum() {
117
+ return this.colors[10];
118
+ }
119
+ get sage() {
120
+ return this.colors[11];
121
+ }
122
+ get drab() {
123
+ return this.colors[12];
124
+ }
125
+ get taupe() {
126
+ return this.colors[13];
127
+ }
128
+ get midnight() {
129
+ return this.colors[14];
130
+ }
131
+ get golden() {
132
+ return this.colors[15];
133
+ }
134
+ get orange() {
135
+ return this.colors[16];
136
+ }
137
+ get slate() {
138
+ return this.colors[17];
139
+ }
140
+ /**
141
+ * Ensures a color string has a # prefix
142
+ * @param color - Color string in hex format (with or without #)
143
+ * @returns Hex color string with # prefix
144
+ */
145
+ hex(color) {
146
+ return color.startsWith("#") ? color : `#${color}`;
147
+ }
148
+ /**
149
+ * Creates an RGB color string
150
+ * @param r - Red component (0-255)
151
+ * @param g - Green component (0-255)
152
+ * @param b - Blue component (0-255)
153
+ * @returns RGB color string
154
+ */
155
+ rgb(r, g, b) {
156
+ return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`;
157
+ }
158
+ /**
159
+ * Creates an RGBA color string
160
+ * @param r - Red component (0-255)
161
+ * @param g - Green component (0-255)
162
+ * @param b - Blue component (0-255)
163
+ * @param alpha - Alpha/opacity value (0-1)
164
+ * @returns RGBA color string
165
+ */
166
+ rgba(r, g, b, alpha) {
167
+ return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(
168
+ b
169
+ )}, ${alpha})`;
170
+ }
171
+ /**
172
+ * Creates a grayscale color
173
+ * @param value - Gray value (0-255)
174
+ * @param alpha - Optional alpha/opacity value (0-1)
175
+ * @returns RGB or RGBA grayscale color string
176
+ */
177
+ gray(value, alpha) {
178
+ return alpha !== void 0 ? `rgba(${Math.round(value)}, ${Math.round(value)}, ${Math.round(
179
+ value
180
+ )}, ${alpha})` : `rgb(${Math.round(value)}, ${Math.round(value)}, ${Math.round(value)})`;
181
+ }
182
+ /**
183
+ * Creates an HSL color string
184
+ * @param h - Hue (0-360)
185
+ * @param s - Saturation percentage (0-100)
186
+ * @param l - Lightness percentage (0-100)
187
+ * @returns HSL color string
188
+ */
189
+ hsl(h, s, l) {
190
+ return `hsl(${h % 360}, ${Math.max(0, s)}%, ${Math.max(0, l)}%)`;
191
+ }
192
+ /**
193
+ * Creates an HSLA color string
194
+ * @param h - Hue (0-360)
195
+ * @param s - Saturation percentage (0-100)
196
+ * @param l - Lightness percentage (0-100)
197
+ * @param alpha - Alpha/opacity value (0-1)
198
+ * @returns HSLA color string
199
+ */
200
+ hsla(h, s, l, alpha) {
201
+ return `hsla(${h % 360}, ${Math.max(0, s)}%, ${Math.max(0, l)}%, ${alpha})`;
202
+ }
203
+ /**
204
+ * Creates an LCH color string
205
+ * @param l - Lightness percentage (0-100)
206
+ * @param c - Chroma value
207
+ * @param h - Hue (0-360)
208
+ * @returns LCH color string
209
+ */
210
+ lch(l, c, h) {
211
+ return `lch(${l}% ${c} ${h})`;
212
+ }
213
+ /**
214
+ * Creates an LCH color string with alpha
215
+ * @param l - Lightness percentage (0-100)
216
+ * @param c - Chroma value
217
+ * @param h - Hue (0-360)
218
+ * @param alpha - Alpha/opacity value (0-1)
219
+ * @returns LCH color string with alpha
220
+ */
221
+ lcha(l, c, h, alpha) {
222
+ return `lch(${l}% ${c} ${h} / ${alpha})`;
223
+ }
224
+ /**
225
+ * Creates a LAB color string
226
+ * @param l - Lightness percentage (0-100)
227
+ * @param a - A-axis value (green to red)
228
+ * @param b - B-axis value (blue to yellow)
229
+ * @returns LAB color string
230
+ */
231
+ lab(l, a, b) {
232
+ return `lab(${l}% ${a} ${b})`;
233
+ }
234
+ /**
235
+ * Creates a LAB color string with alpha
236
+ * @param l - Lightness percentage (0-100)
237
+ * @param a - A-axis value (green to red)
238
+ * @param b - B-axis value (blue to yellow)
239
+ * @param alpha - Alpha/opacity value (0-1)
240
+ * @returns LAB color string with alpha
241
+ */
242
+ laba(l, a, b, alpha) {
243
+ return `lab(${l}% ${a} ${b} / ${alpha})`;
244
+ }
245
+ /**
246
+ * Creates an OKLCH color string
247
+ * @param l - Lightness value (0-1)
248
+ * @param c - Chroma value
249
+ * @param h - Hue (0-360)
250
+ * @returns OKLCH color string
251
+ */
252
+ oklch(l, c, h) {
253
+ return `oklch(${l} ${c} ${h})`;
254
+ }
255
+ /**
256
+ * Creates an OKLCH color string with alpha
257
+ * @param l - Lightness value (0-1)
258
+ * @param c - Chroma value
259
+ * @param h - Hue (0-360)
260
+ * @param alpha - Alpha/opacity value (0-1)
261
+ * @returns OKLCH color string with alpha
262
+ */
263
+ oklcha(l, c, h, alpha) {
264
+ return `oklch(${l} ${c} ${h} / ${alpha})`;
265
+ }
266
+ /**
267
+ * Creates an OKLAB color string
268
+ * @param l - Lightness value (0-1)
269
+ * @param a - A-axis value (green to red)
270
+ * @param b - B-axis value (blue to yellow)
271
+ * @returns OKLAB color string
272
+ */
273
+ oklab(l, a, b) {
274
+ return `oklab(${l} ${a} ${b})`;
275
+ }
276
+ /**
277
+ * Creates an OKLAB color string with alpha
278
+ * @param l - Lightness value (0-1)
279
+ * @param a - A-axis value (green to red)
280
+ * @param b - B-axis value (blue to yellow)
281
+ * @param alpha - Alpha/opacity value (0-1)
282
+ * @returns OKLAB color string with alpha
283
+ */
284
+ oklaba(l, a, b, alpha) {
285
+ return `oklab(${l} ${a} ${b} / ${alpha})`;
286
+ }
287
+ /**
288
+ * Blends two colors using CSS color-mix
289
+ * @param colorA - First color
290
+ * @param colorB - Second color
291
+ * @param factor - Blend factor (0-1) where 0 is colorA and 1 is colorB
292
+ * @param colorMode - Color space to blend in (e.g., "oklch", "hsl")
293
+ * @returns Blended color string
294
+ */
295
+ blendColors(colorA, colorB, factor, colorMode = "oklch") {
296
+ const t = Math.max(0, Math.min(1, factor)) * 100;
297
+ return `color-mix(in ${colorMode}, ${colorA}, ${colorB} ${t}%)`;
298
+ }
299
+ /**
300
+ * Creates a palette of colors based on a single base color
301
+ * @param baseColor - The base color to create palette from
302
+ * @param steps - Number of steps in each direction (lighter/darker)
303
+ * @returns Array of color strings forming a palette
304
+ */
305
+ createPalette(baseColor, steps = 9) {
306
+ const palette = [];
307
+ for (let i = 1; i < steps; i++) {
308
+ const factor = i / steps;
309
+ palette.unshift(this.blendColors(baseColor, "#ffffff", factor, "oklch"));
310
+ }
311
+ palette.push(baseColor);
312
+ for (let i = 1; i < steps; i++) {
313
+ const factor = i / steps;
314
+ palette.push(this.blendColors(baseColor, "#000000", factor, "oklch"));
315
+ }
316
+ return palette;
317
+ }
318
+ /**
319
+ * Creates a complementary color (opposite on the color wheel)
320
+ * @param color - Base color
321
+ * @returns Complementary color string
322
+ */
323
+ complementary(color) {
324
+ return this.blendColors(color, "hsl(180deg 100% 50%)", 1, "hsl");
325
+ }
326
+ /**
327
+ * Creates analogous colors (adjacent on the color wheel)
328
+ * @param color - Base color
329
+ * @param angle - Angle of separation in degrees
330
+ * @returns Tuple of two analogous color strings
331
+ */
332
+ analogous(color, angle = 30) {
333
+ return [
334
+ this.blendColors(color, `hsl(${-angle}deg 100% 50%)`, 1, "hsl"),
335
+ this.blendColors(color, `hsl(${angle}deg 100% 50%)`, 1, "hsl")
336
+ ];
337
+ }
338
+ /**
339
+ * Creates a triadic color scheme (three colors evenly spaced on the color wheel)
340
+ * @param color - Base color
341
+ * @returns Tuple of two additional colors to form a triadic scheme
342
+ */
343
+ triadic(color) {
344
+ return [
345
+ this.blendColors(color, "hsl(120deg 100% 50%)", 1, "hsl"),
346
+ this.blendColors(color, "hsl(240deg 100% 50%)", 1, "hsl")
347
+ ];
348
+ }
349
+ /**
350
+ * Increases the saturation of a color
351
+ * @param color - Base color
352
+ * @param amount - Amount to saturate (percentage)
353
+ * @returns Saturated color string
354
+ */
355
+ saturate(color, amount) {
356
+ return this.blendColors(
357
+ color,
358
+ "hsl(0deg 100% 50% / 0%)",
359
+ amount / 100,
360
+ "hsl"
361
+ );
362
+ }
363
+ /**
364
+ * Lightens a color by mixing with white
365
+ * @param color - Base color
366
+ * @param amount - Amount to lighten (percentage)
367
+ * @returns Lightened color string
368
+ */
369
+ lighten(color, amount) {
370
+ return this.blendColors(color, "white", amount / 100, "hsl");
371
+ }
372
+ /**
373
+ * Darkens a color by mixing with black
374
+ * @param color - Base color
375
+ * @param amount - Amount to darken (percentage)
376
+ * @returns Darkened color string
377
+ */
378
+ darken(color, amount) {
379
+ return this.blendColors(color, "black", amount / 100, "hsl");
380
+ }
381
+ };
382
+ var Color_default = Color;
383
+
384
+ // src/elements/Easing.tsx
385
+ var Easing = class {
386
+ constructor(ctx) {
387
+ this.normalize = (val) => {
388
+ return val * 0.5 + 0.5;
389
+ };
390
+ this.expand = (val) => {
391
+ return val * 2 - 1;
392
+ };
393
+ this.inout = (val, power = 2) => {
394
+ const m = val - 1;
395
+ const t = val * 2;
396
+ if (t < 1) {
397
+ return val * Math.pow(t, power - 1);
398
+ }
399
+ return power % 2 === 0 ? 1 - Math.pow(m, power) * Math.pow(2, power - 1) : 1 + Math.pow(m, power) * Math.pow(2, power - 1);
400
+ };
401
+ this.in = (val, power = 2) => {
402
+ return Math.pow(val, power);
403
+ };
404
+ this.out = (val, power = 2) => {
405
+ const m = val - 1;
406
+ return power % 2 === 0 ? 1 - Math.pow(m, power) : 1 + Math.pow(m, power);
407
+ };
408
+ this.overshootIn = (val) => {
409
+ const k = 1.70158;
410
+ return val * val * (val * (k + 1) - k);
411
+ };
412
+ this.overshootOut = (val) => {
413
+ const m = val - 1;
414
+ const k = 1.70158;
415
+ return 1 + m * m * (m * (k + 1) + k);
416
+ };
417
+ this.overshootInOut = (val) => {
418
+ const m = val - 1;
419
+ const t = val * 2;
420
+ const k = 1.70158 * 1.525;
421
+ if (val < 0.5) return val * t * (t * (k + 1) - k);
422
+ return 1 + 2 * m * m * (2 * m * (k + 1) + k);
423
+ };
424
+ this.bounceOut = (val) => {
425
+ const r = 1 / 2.75;
426
+ const k1 = r;
427
+ const k2 = 2 * r;
428
+ const k3 = 1.5 * r;
429
+ const k4 = 2.5 * r;
430
+ const k5 = 2.25 * r;
431
+ const k6 = 2.625 * r;
432
+ const k0 = 7.5625;
433
+ let t;
434
+ if (val < k1) {
435
+ return k0 * val * val;
436
+ } else if (val < k2) {
437
+ t = val - k3;
438
+ return k0 * t * t + 0.75;
439
+ } else if (val < k4) {
440
+ t = val - k5;
441
+ return k0 * t * t + 0.9375;
442
+ }
443
+ t = val - k6;
444
+ return k0 * t * t + 0.984375;
445
+ };
446
+ this.bounceIn = (val) => {
447
+ return 1 - this.bounceOut(1 - val);
448
+ };
449
+ this.bounceInOut = (val) => {
450
+ const t = val * 2;
451
+ if (t < 1) return 0.5 - 0.5 * this.bounceOut(1 - t);
452
+ return 0.5 + 0.5 * this.bounceOut(t - 1);
453
+ };
454
+ this.elasticIn = (val) => {
455
+ const m = val - 1;
456
+ return -Math.pow(2, 10 * m) * Math.sin((m * 40 - 3) * Math.PI / 6);
457
+ };
458
+ this.elasticOut = (val) => {
459
+ return 1 + Math.pow(2, 10 * -val) * Math.sin((-val * 40 - 3) * Math.PI / 6);
460
+ };
461
+ this.elasticInOut = (val) => {
462
+ const s = 2 * val - 1;
463
+ const k = (80 * s - 9) * Math.PI / 18;
464
+ if (s < 0) return -0.5 * Math.pow(2, 10 * s) * Math.sin(k);
465
+ return 1 + 0.5 * Math.pow(2, -10 * s) * Math.sin(k);
466
+ };
467
+ this.smoothstep = (val, x0 = 0, x1 = 1) => {
468
+ let p = (val - x0) / (x1 - x0);
469
+ p = p < 0 ? 0 : p > 1 ? 1 : p;
470
+ return p * p * (3 - 2 * p);
471
+ };
472
+ this.log = () => {
473
+ console.log(this);
474
+ };
475
+ this.context = ctx;
476
+ }
477
+ };
478
+ var Easing_default = Easing;
479
+
480
+ // src/elements/State.tsx
481
+ var State = class {
482
+ constructor() {
483
+ this.store = /* @__PURE__ */ new Map();
484
+ }
485
+ set(key, value, callback) {
486
+ this.store.set(key, value);
487
+ callback?.(key, value);
488
+ }
489
+ get(key, callback) {
490
+ const value = this.store.get(key);
491
+ callback?.(key, value);
492
+ return value;
493
+ }
494
+ has(key) {
495
+ return this.store.has(key);
496
+ }
497
+ delete(key, callback) {
498
+ this.store.delete(key);
499
+ callback?.(key);
500
+ }
501
+ log() {
502
+ return this.store;
503
+ }
504
+ };
505
+ var State_default = State;
506
+
507
+ // src/elements/Vector.tsx
508
+ var Vector = class _Vector {
509
+ /**
510
+ * Creates a new Vector
511
+ * @param x - X-coordinate (default: 0)
512
+ * @param y - Y-coordinate (default: 0)
513
+ */
514
+ constructor(x = 0, y = 0) {
515
+ this.x = x;
516
+ this.y = y;
517
+ }
518
+ /**
519
+ * Adds another vector to this vector
520
+ * @param v - Vector to add
521
+ * @returns This vector after addition
522
+ */
523
+ add(v) {
524
+ this.x += v.x;
525
+ this.y += v.y;
526
+ return this;
527
+ }
528
+ /**
529
+ * Subtracts another vector from this vector
530
+ * @param v - Vector to subtract
531
+ * @returns This vector after subtraction
532
+ */
533
+ sub(v) {
534
+ this.x -= v.x;
535
+ this.y -= v.y;
536
+ return this;
537
+ }
538
+ /**
539
+ * Multiplies this vector by a scalar
540
+ * @param n - Scalar to multiply by
541
+ * @returns This vector after multiplication
542
+ */
543
+ mult(n) {
544
+ this.x *= n;
545
+ this.y *= n;
546
+ return this;
547
+ }
548
+ /**
549
+ * Divides this vector by a scalar
550
+ * @param n - Scalar to divide by
551
+ * @returns This vector after division
552
+ */
553
+ div(n) {
554
+ this.x /= n;
555
+ this.y /= n;
556
+ return this;
557
+ }
558
+ // to do : project, perp, slerp
559
+ /**
560
+ * Rotates this vector by an angle
561
+ * @param angle - Angle in radians
562
+ * @returns This vector after rotation
563
+ */
564
+ rotate(angle) {
565
+ const cos = Math.cos(angle);
566
+ const sin = Math.sin(angle);
567
+ const x = this.x * cos - this.y * sin;
568
+ const y = this.x * sin + this.y * cos;
569
+ this.x = x;
570
+ this.y = y;
571
+ return this;
572
+ }
573
+ /**
574
+ * Calculates the magnitude (length) of this vector
575
+ * @returns The magnitude of the vector
576
+ */
577
+ mag() {
578
+ return Math.sqrt(this.x * this.x + this.y * this.y);
579
+ }
580
+ /**
581
+ * Alias for mag() - calculates the length of this vector
582
+ * @returns The length of the vector
583
+ */
584
+ length() {
585
+ return this.mag();
586
+ }
587
+ /**
588
+ * Calculates the dot product of this vector with another vector
589
+ * @param v - The other vector
590
+ * @returns The dot product
591
+ */
592
+ dot(v) {
593
+ return this.x * v.x + this.y * v.y;
594
+ }
595
+ /**
596
+ * Calculates the distance between this vector and another vector
597
+ * @param v - The other vector
598
+ * @returns The distance between the vectors
599
+ */
600
+ dist(v) {
601
+ return Math.hypot(this.x - v.x, this.y - v.y);
602
+ }
603
+ /**
604
+ * Calculates the angle of this vector
605
+ * @returns The angle in radians
606
+ */
607
+ angle() {
608
+ return Math.atan2(-this.x, -this.y) + Math.PI;
609
+ }
610
+ /**
611
+ * Creates a copy of this vector
612
+ * @returns A new Vector with the same coordinates
613
+ */
614
+ copy() {
615
+ return new _Vector(this.x, this.y);
616
+ }
617
+ /**
618
+ * Normalizes this vector (sets its magnitude to 1)
619
+ * @returns This vector after normalization
620
+ */
621
+ normalize() {
622
+ const m = this.mag();
623
+ return m !== 0 ? this.div(m) : this;
624
+ }
625
+ /**
626
+ * Sets the coordinates of this vector
627
+ * @param x - New X-coordinate
628
+ * @param y - New Y-coordinate
629
+ * @returns This vector after setting coordinates
630
+ */
631
+ set(x, y) {
632
+ this.x = x;
633
+ this.y = y;
634
+ return this;
635
+ }
636
+ /**
637
+ * Creates a new vector at a specified angle and distance from a center point
638
+ * @param center - The center point vector
639
+ * @param a - The angle in radians
640
+ * @param r - The radius (distance from center)
641
+ * @returns A new Vector at the calculated position
642
+ */
643
+ static fromAngle(center, a, r) {
644
+ const x = Math.cos(a) * r + center.x;
645
+ const y = Math.sin(a) * r + center.y;
646
+ return new _Vector(x, y);
647
+ }
648
+ };
649
+ var Vector_default = Vector;
650
+
651
+ // src/elements/Time.tsx
652
+ var Time = class {
653
+ constructor(ctx) {
654
+ this.timelines = /* @__PURE__ */ new Map();
655
+ this.currentTimeline = "default";
656
+ this.DEFAULT_DURATION = 8 * 60;
657
+ this.staggers = [];
658
+ this.context = ctx;
659
+ this.timelines.set("default", {
660
+ progress: 0,
661
+ duration: this.DEFAULT_DURATION
662
+ });
663
+ }
664
+ timeline(key) {
665
+ if (!this.timelines.has(key)) {
666
+ this.timelines.set(key, { progress: 0, duration: this.DEFAULT_DURATION });
667
+ }
668
+ this.currentTimeline = key;
669
+ return this;
670
+ }
671
+ use(progress) {
672
+ const timeline = this.timelines.get(this.currentTimeline);
673
+ if (timeline.duration <= 0) {
674
+ timeline.progress = 0;
675
+ return this;
676
+ }
677
+ timeline.progress = timeline.duration === 1 ? Math.min(progress, 1) : progress / timeline.duration % 1;
678
+ return this;
679
+ }
680
+ for(duration) {
681
+ const timeline = this.timelines.get(this.currentTimeline);
682
+ timeline.duration = duration;
683
+ return this;
684
+ }
685
+ stagger(num, offset = 0, callback) {
686
+ const timeline = this.timelines.get(this.currentTimeline);
687
+ const totalduration = this.context.remap(
688
+ timeline.progress,
689
+ 0,
690
+ 1,
691
+ 0,
692
+ 1 + offset
693
+ );
694
+ for (let i = 0; i < num; i++) {
695
+ const id = 1 - i / (num - 1);
696
+ const progress = this.context.constrain(
697
+ totalduration - id * offset,
698
+ 0,
699
+ 1
700
+ );
701
+ if (!callback) {
702
+ if (this.staggers[i]) {
703
+ this.staggers[i].progress = progress;
704
+ } else {
705
+ this.staggers[i] = { progress, id };
706
+ }
707
+ } else {
708
+ callback?.(progress, id, num);
709
+ }
710
+ }
711
+ return callback ? this : this.staggers;
712
+ }
713
+ between(from = 0, to = 1, callback) {
714
+ const timeline = this.timelines.get(this.currentTimeline);
715
+ const localProgress = this.context.remap(
716
+ timeline.progress,
717
+ Math.max(0, from),
718
+ Math.min(1, to),
719
+ 0,
720
+ 1
721
+ );
722
+ callback(localProgress);
723
+ return this;
724
+ }
725
+ progress() {
726
+ return this.timelines.get(this.currentTimeline)?.progress || 0;
727
+ }
728
+ };
729
+ var Time_default = Time;
730
+
731
+ // src/elements/Text.tsx
732
+ var Text = class {
733
+ constructor(ctx) {
734
+ this.findTextSize = (text, dist, estimate, direction = "x") => {
735
+ let low = 1;
736
+ let high = estimate || this.context.__textSize * 2;
737
+ let lastValidSize = low;
738
+ for (let i = 0; i < 16; i++) {
739
+ const mid = Math.floor((low + high) / 2);
740
+ this.context.__textSize = mid;
741
+ const bounds = this.textBounds(text);
742
+ const size = direction === "x" ? bounds.width : bounds.height;
743
+ if (size === dist) {
744
+ return mid;
745
+ } else if (size < dist) {
746
+ lastValidSize = mid;
747
+ low = mid + 1;
748
+ } else {
749
+ high = mid - 1;
750
+ }
751
+ }
752
+ return lastValidSize;
753
+ };
754
+ this.getTextMetrics = (text) => {
755
+ const ctx = this.context;
756
+ const metrics = ctx.measureText(text);
757
+ return {
758
+ width: metrics.width,
759
+ height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent,
760
+ baseline: metrics.actualBoundingBoxAscent
761
+ };
762
+ };
763
+ this.splitTo = (text, kind, options = {}) => {
764
+ const ctx = this.context;
765
+ const {
766
+ maxWidth = 0,
767
+ lineSpacing = 0,
768
+ letterSpacing = 0,
769
+ wordSpacing = 0
770
+ } = options;
771
+ ctx.computeFont();
772
+ if (maxWidth < this.textBounds(" ").width * 2 && maxWidth !== 0) {
773
+ return [];
774
+ }
775
+ const lines = text.split("\n");
776
+ const lineHeights = lines.map((line) => this.getTextMetrics(line).height);
777
+ const totalHeight = lineHeights.reduce((sum, height) => sum + height, 0) + (lines.length - 1) * (lineSpacing || 0);
778
+ let y = ctx.textBaseline === "middle" ? -totalHeight / 2 : 0;
779
+ return lines.flatMap((lineText, lineIndex) => {
780
+ const words = lineText.split(" ");
781
+ const currentLine = {
782
+ text: "",
783
+ width: 0,
784
+ letters: []
785
+ };
786
+ const totalWidth = this.getTextMetrics(lineText).width;
787
+ let startX = 0;
788
+ switch (ctx.textAlign) {
789
+ case "center":
790
+ startX = -totalWidth / 2;
791
+ break;
792
+ case "right":
793
+ startX = -totalWidth;
794
+ break;
795
+ }
796
+ let x = startX;
797
+ let letterIndex = 0;
798
+ let wordIndex = 0;
799
+ const lineLetters = words.flatMap((word) => {
800
+ const letters = [];
801
+ for (const char of word) {
802
+ const charMetrics = this.getTextMetrics(char);
803
+ x += charMetrics.width / 2;
804
+ const letterData = {
805
+ char,
806
+ x,
807
+ y: y + (ctx.textBaseline === "middle" ? lineHeights[lineIndex] / 2 : 0),
808
+ metrics: charMetrics,
809
+ ...kind === "all" && {
810
+ letterIndex,
811
+ wordIndex,
812
+ lineIndex
813
+ }
814
+ };
815
+ letters.push(letterData);
816
+ currentLine.text += char;
817
+ x += charMetrics.width / 2 + letterSpacing;
818
+ letterIndex++;
819
+ }
820
+ if (wordIndex < words.length - 1) {
821
+ const spaceMetrics = this.getTextMetrics(" ");
822
+ x += spaceMetrics.width + wordSpacing;
823
+ letters.push({
824
+ char: " ",
825
+ x,
826
+ y,
827
+ metrics: spaceMetrics,
828
+ ...kind === "all" && {
829
+ letterIndex,
830
+ wordIndex,
831
+ lineIndex
832
+ }
833
+ });
834
+ currentLine.text += " ";
835
+ letterIndex++;
836
+ }
837
+ wordIndex++;
838
+ return letters;
839
+ });
840
+ const lineHeight = lineHeights[lineIndex];
841
+ y += lineHeight + lineSpacing;
842
+ return lineLetters;
843
+ });
844
+ };
845
+ this.circularText = (text, radius = 100, fill = "fill", offset = 0, arc = Math.PI * 2) => {
846
+ const totalAngle = Math.min(Math.max(arc, 0), Math.PI * 2);
847
+ if (fill === "fill") {
848
+ const chars = text.split("");
849
+ const anglePerChar = totalAngle / (chars.length + 1);
850
+ chars.forEach((char, i) => {
851
+ const angle = anglePerChar * i + offset;
852
+ const x = Math.cos(angle) * radius;
853
+ const y = Math.sin(angle) * radius;
854
+ this.context.push();
855
+ this.context.textAlign = "center";
856
+ this.context.translate(x, y);
857
+ this.context.rotate(angle + Math.PI / 2);
858
+ this.context.text(char, 0, 0);
859
+ this.context.pop();
860
+ });
861
+ } else if (fill === "kerned") {
862
+ let currentAngle = offset;
863
+ text.split("").forEach((char) => {
864
+ const charWidth = this.textBounds(char).width;
865
+ currentAngle += charWidth / radius * 0.5;
866
+ const angle = currentAngle;
867
+ const x = Math.cos(angle) * radius;
868
+ const y = Math.sin(angle) * radius;
869
+ this.context.push();
870
+ this.context.textAlign = "center";
871
+ this.context.translate(x, y);
872
+ this.context.rotate(angle + Math.PI / 2);
873
+ this.context.text(char, 0, 0);
874
+ this.context.pop();
875
+ currentAngle += charWidth / radius * 0.5;
876
+ });
877
+ } else if (fill === "words") {
878
+ const words = text.split(" ");
879
+ const wordMetrics = words.map((word) => ({
880
+ word,
881
+ width: this.textBounds(word).width
882
+ }));
883
+ const spaceCount = words.length;
884
+ const totalWordWidth = wordMetrics.reduce((sum, m) => sum + m.width, 0);
885
+ const spaceAngle = (totalAngle - totalWordWidth / radius) / spaceCount;
886
+ let currentAngle = offset;
887
+ wordMetrics.forEach(({ word }, i) => {
888
+ word.split("").forEach((char) => {
889
+ const charWidth = this.textBounds(char).width;
890
+ currentAngle += charWidth / radius * 0.5;
891
+ const x = Math.cos(currentAngle) * radius;
892
+ const y = Math.sin(currentAngle) * radius;
893
+ this.context.push();
894
+ this.context.textAlign = "center";
895
+ this.context.translate(x, y);
896
+ this.context.rotate(currentAngle + Math.PI / 2);
897
+ this.context.text(char, 0, 0);
898
+ this.context.pop();
899
+ currentAngle += charWidth / radius * 0.5;
900
+ });
901
+ if (i < words.length - 1) {
902
+ currentAngle += spaceAngle;
903
+ }
904
+ });
905
+ }
906
+ };
907
+ this.textBounds = (text) => {
908
+ if (this.context.font !== this.context.__computedTextFont) {
909
+ this.context.font = this.context.__computedTextFont;
910
+ }
911
+ const metrics = this.context.measureText(text);
912
+ return {
913
+ x: metrics.actualBoundingBoxLeft * -1,
914
+ y: metrics.actualBoundingBoxAscent * -1,
915
+ width: metrics.width,
916
+ height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent
917
+ };
918
+ };
919
+ this.log = () => {
920
+ console.log(this.context);
921
+ };
922
+ this.context = ctx;
923
+ }
924
+ };
925
+ var Text_default = Text;
926
+
927
+ // src/elements/Thing.tsx
928
+ var Thing = class {
929
+ constructor(ctx) {
930
+ this.context = ctx;
931
+ }
932
+ log() {
933
+ console.log(this.context);
934
+ }
935
+ };
936
+ var Thing_default = Thing;
937
+ // Annotate the CommonJS export names for ESM import in node:
938
+ 0 && (module.exports = {
939
+ Color,
940
+ Easing,
941
+ State,
942
+ Text,
943
+ Thing,
944
+ Time,
945
+ Vector
946
+ });