typography-toolkit 1.2.1 → 1.3.1
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class f {
|
|
2
|
-
update(e, o,
|
|
3
|
-
const i = t.speed || 1, l = t.amplitude || 20,
|
|
2
|
+
update(e, o, a, t = {}) {
|
|
3
|
+
const i = t.speed || 1, l = t.amplitude || 20, s = o * 0.2, c = (a * 10 * i + s * 5) % l - l / 2;
|
|
4
4
|
return {
|
|
5
5
|
...e,
|
|
6
6
|
y: c
|
|
@@ -8,61 +8,69 @@ class f {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
class C {
|
|
11
|
-
update(e, o,
|
|
12
|
-
const i = t.speed || 1, l = t.amplitude || 4,
|
|
11
|
+
update(e, o, a, t = {}) {
|
|
12
|
+
const i = t.speed || 1, l = t.amplitude || 4, s = o * 0.2, n = Math.sin(a * 0.5 * i + s) * l;
|
|
13
13
|
return {
|
|
14
14
|
...e,
|
|
15
|
-
x:
|
|
15
|
+
x: n
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
class
|
|
19
|
+
class S {
|
|
20
20
|
constructor() {
|
|
21
|
-
this.
|
|
21
|
+
this.letterStates = /* @__PURE__ */ new Map();
|
|
22
22
|
}
|
|
23
|
-
update(e, o,
|
|
24
|
-
const i = t.amplitude || 3;
|
|
25
|
-
|
|
23
|
+
update(e, o, a, t = {}) {
|
|
24
|
+
const i = t.amplitude || 3, l = t.speed || 1;
|
|
25
|
+
let s = this.letterStates.get(o);
|
|
26
|
+
s || (s = {
|
|
27
|
+
lastUpdate: a,
|
|
28
|
+
glitchX: 0,
|
|
29
|
+
glitchY: 0,
|
|
30
|
+
glitchRot: 0
|
|
31
|
+
}, this.letterStates.set(o, s));
|
|
32
|
+
const n = 0.1 / l;
|
|
33
|
+
return a - s.lastUpdate > n && (s.glitchX = (Math.random() - 0.5) * i, s.glitchY = (Math.random() - 0.5) * (i * 0.67), s.glitchRot = (Math.random() - 0.5) * i, s.lastUpdate = a), {
|
|
26
34
|
...e,
|
|
27
|
-
x:
|
|
28
|
-
y:
|
|
29
|
-
rotation:
|
|
35
|
+
x: s.glitchX,
|
|
36
|
+
y: s.glitchY,
|
|
37
|
+
rotation: s.glitchRot
|
|
30
38
|
};
|
|
31
39
|
}
|
|
32
40
|
}
|
|
33
|
-
class
|
|
34
|
-
update(e, o,
|
|
35
|
-
const i = t.speed || 1, l = t.amplitude || 15,
|
|
41
|
+
class b {
|
|
42
|
+
update(e, o, a, t = {}) {
|
|
43
|
+
const i = t.speed || 1, l = t.amplitude || 15, s = o * 0.2, c = -((a * 8 * i + s * 4) % l - l / 2);
|
|
36
44
|
return {
|
|
37
45
|
...e,
|
|
38
46
|
y: c
|
|
39
47
|
};
|
|
40
48
|
}
|
|
41
49
|
}
|
|
42
|
-
function
|
|
43
|
-
const { x: o, y:
|
|
44
|
-
|
|
50
|
+
function D(r, e) {
|
|
51
|
+
const { x: o, y: a, rotation: t, scale: i, opacity: l } = e;
|
|
52
|
+
r.style.transform = `translate(${o}px, ${a}px) rotate(${t}deg) scale(${i})`, r.style.opacity = l.toString();
|
|
45
53
|
}
|
|
46
|
-
function
|
|
54
|
+
function k(r, e, o, a, t, i) {
|
|
47
55
|
if (!i.enabled)
|
|
48
56
|
return {
|
|
49
57
|
state: { x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 },
|
|
50
58
|
applied: !1
|
|
51
59
|
};
|
|
52
|
-
const l = i.radius || 80,
|
|
60
|
+
const l = i.radius || 80, s = i.strength || 1, n = i.behaviors || ["fall-away", "split-apart", "explode"], c = o - r, u = a - e, d = Math.sqrt(c * c + u * u);
|
|
53
61
|
if (d >= l)
|
|
54
62
|
return {
|
|
55
63
|
state: { x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 },
|
|
56
64
|
applied: !1
|
|
57
65
|
};
|
|
58
|
-
const g = (1 - d / l) *
|
|
66
|
+
const g = (1 - d / l) * s, h = Math.atan2(u, c), T = n[t % n.length];
|
|
59
67
|
let m;
|
|
60
|
-
switch (
|
|
68
|
+
switch (T) {
|
|
61
69
|
case "fall-away":
|
|
62
|
-
const A = Math.cos(
|
|
70
|
+
const A = Math.cos(h) * g * 20, E = Math.sin(h) * g * 40 + g * 30;
|
|
63
71
|
m = {
|
|
64
72
|
x: A,
|
|
65
|
-
y:
|
|
73
|
+
y: E,
|
|
66
74
|
rotation: g * 15,
|
|
67
75
|
scale: 1,
|
|
68
76
|
opacity: 1 - g * 0.6
|
|
@@ -79,7 +87,7 @@ function b(s, e, o, n, t, i) {
|
|
|
79
87
|
};
|
|
80
88
|
break;
|
|
81
89
|
case "explode":
|
|
82
|
-
const F =
|
|
90
|
+
const F = h + (Math.random() - 0.5) * 0.5;
|
|
83
91
|
m = {
|
|
84
92
|
x: Math.cos(F) * g * 40,
|
|
85
93
|
y: Math.sin(F) * g * 40,
|
|
@@ -99,33 +107,33 @@ function b(s, e, o, n, t, i) {
|
|
|
99
107
|
class v {
|
|
100
108
|
constructor(e) {
|
|
101
109
|
var o;
|
|
102
|
-
if (this.letters = [], this.animationFrame = null, this.mouseX = 0, this.mouseY = 0, this.mouseMoveHandler = null, this.startTime = Date.now(), this.isDestroyed = !1, this.container = e.container, this.animationTypes = e.animations || ["falling", "splitting", "glitching", "floating"], this.cycle = e.cycle !== !1, this.speed = e.speed || 1, this.amplitude = e.amplitude || 1, this.disintegration = e.disintegration || { enabled: !1 }, this.style = e.style || {}, this.fadeOut = e.fadeOut || 0, this.callbacks = e.callbacks, this.textContainer = document.createElement("div"), this.textContainer.style.position = "absolute", this.textContainer.style.pointerEvents = "none", this.textContainer.style.zIndex = "1", e.containerClass && (this.textContainer.className = e.containerClass), e.containerStyle && Object.entries(e.containerStyle).forEach(([
|
|
103
|
-
this.textContainer.style.setProperty(
|
|
110
|
+
if (this.letters = [], this.animationSpeedMultiplier = 1, this.animationFrame = null, this.mouseX = 0, this.mouseY = 0, this.mouseMoveHandler = null, this.startTime = Date.now(), this.isDestroyed = !1, this.animationInstances = /* @__PURE__ */ new Map(), this.container = e.container, this.animationTypes = e.animations || ["falling", "splitting", "glitching", "floating"], this.cycle = e.cycle !== !1, this.speed = e.speed || 1, this.amplitude = e.amplitude || 1, this.animationEasing = e.animationEasing || "linear", this.disintegration = e.disintegration || { enabled: !1 }, this.style = e.style || {}, this.fadeOut = e.fadeOut || 0, this.callbacks = e.callbacks, e.animationSpeed !== void 0 && (this.animationSpeedMultiplier = this.parseAnimationSpeed(e.animationSpeed)), this.textContainer = document.createElement("div"), this.textContainer.style.position = "absolute", this.textContainer.style.pointerEvents = "none", this.textContainer.style.zIndex = "1", e.containerClass && (this.textContainer.className = e.containerClass), e.containerStyle && Object.entries(e.containerStyle).forEach(([a, t]) => {
|
|
111
|
+
this.textContainer.style.setProperty(a, t);
|
|
104
112
|
}), e.position) {
|
|
105
|
-
let
|
|
113
|
+
let a = e.position.x, t = e.position.y;
|
|
106
114
|
if (e.position.constrainToViewport) {
|
|
107
115
|
this.container.getBoundingClientRect();
|
|
108
|
-
const i = window.innerWidth, l = window.innerHeight,
|
|
109
|
-
|
|
116
|
+
const i = window.innerWidth, l = window.innerHeight, s = e.text.length * 20;
|
|
117
|
+
a !== void 0 && (a = Math.max(0, Math.min(a, i - s))), t !== void 0 && (t = Math.max(0, Math.min(t, l - 50)));
|
|
110
118
|
}
|
|
111
|
-
|
|
119
|
+
a !== void 0 && (this.textContainer.style.left = `${a}px`), t !== void 0 && (this.textContainer.style.top = `${t}px`);
|
|
112
120
|
}
|
|
113
121
|
this.createLetters(e.text), this.setupMouseTracking(), this.startAnimation(), (o = this.callbacks) != null && o.onCreate && this.callbacks.onCreate(this.textContainer), this.fadeOut > 0 && setTimeout(() => this.destroy(), this.fadeOut);
|
|
114
122
|
}
|
|
115
123
|
createLetters(e) {
|
|
116
|
-
e.toUpperCase().split("").forEach((
|
|
117
|
-
if (
|
|
118
|
-
const
|
|
119
|
-
this.textContainer.appendChild(
|
|
124
|
+
e.toUpperCase().split("").forEach((a, t) => {
|
|
125
|
+
if (a === " ") {
|
|
126
|
+
const s = document.createTextNode(" ");
|
|
127
|
+
this.textContainer.appendChild(s);
|
|
120
128
|
return;
|
|
121
129
|
}
|
|
122
130
|
const i = document.createElement("span");
|
|
123
|
-
i.className = "animated-letter", i.textContent =
|
|
131
|
+
i.className = "animated-letter", i.textContent = a, i.dataset.index = t.toString(), i.dataset.char = a, this.applyStyle(i), i.style.display = "inline-block", i.style.position = "relative", i.style.transition = "transform 0.1s ease-out", this.textContainer.appendChild(i);
|
|
124
132
|
const l = i.getBoundingClientRect();
|
|
125
133
|
this.letters.push({
|
|
126
134
|
element: i,
|
|
127
135
|
index: t,
|
|
128
|
-
char:
|
|
136
|
+
char: a,
|
|
129
137
|
baseX: l.left,
|
|
130
138
|
baseY: l.top
|
|
131
139
|
});
|
|
@@ -143,19 +151,19 @@ class v {
|
|
|
143
151
|
const e = () => {
|
|
144
152
|
if (this.isDestroyed) return;
|
|
145
153
|
const o = (Date.now() - this.startTime) * 1e-3;
|
|
146
|
-
this.letters.forEach((
|
|
147
|
-
var
|
|
148
|
-
const i =
|
|
154
|
+
this.letters.forEach((a, t) => {
|
|
155
|
+
var u;
|
|
156
|
+
const i = a.element.getBoundingClientRect(), l = i.left + i.width / 2, s = i.top + i.height / 2, n = k(
|
|
149
157
|
l,
|
|
150
|
-
|
|
158
|
+
s,
|
|
151
159
|
this.mouseX,
|
|
152
160
|
this.mouseY,
|
|
153
161
|
t,
|
|
154
162
|
this.disintegration
|
|
155
163
|
);
|
|
156
164
|
let c;
|
|
157
|
-
if (
|
|
158
|
-
c =
|
|
165
|
+
if (n.applied)
|
|
166
|
+
c = n.state, (u = this.callbacks) != null && u.onDisintegrate && this.callbacks.onDisintegrate(t);
|
|
159
167
|
else {
|
|
160
168
|
const d = this.getAnimationType(t);
|
|
161
169
|
c = this.getAnimation(d).update(
|
|
@@ -163,12 +171,12 @@ class v {
|
|
|
163
171
|
t,
|
|
164
172
|
o,
|
|
165
173
|
{
|
|
166
|
-
speed: this.speed,
|
|
174
|
+
speed: this.speed * this.animationSpeedMultiplier,
|
|
167
175
|
amplitude: this.amplitude * (d === "falling" || d === "floating" ? 20 : 4)
|
|
168
176
|
}
|
|
169
177
|
);
|
|
170
178
|
}
|
|
171
|
-
|
|
179
|
+
D(a.element, c);
|
|
172
180
|
}), this.animationFrame = requestAnimationFrame(e);
|
|
173
181
|
};
|
|
174
182
|
this.animationFrame = requestAnimationFrame(e);
|
|
@@ -177,25 +185,74 @@ class v {
|
|
|
177
185
|
return this.cycle ? this.animationTypes[e % this.animationTypes.length] : this.animationTypes[0];
|
|
178
186
|
}
|
|
179
187
|
getAnimation(e) {
|
|
188
|
+
if (this.animationInstances.has(e))
|
|
189
|
+
return this.animationInstances.get(e);
|
|
190
|
+
let o;
|
|
180
191
|
switch (e) {
|
|
181
192
|
case "falling":
|
|
182
|
-
|
|
193
|
+
o = new f();
|
|
194
|
+
break;
|
|
183
195
|
case "splitting":
|
|
184
|
-
|
|
196
|
+
o = new C();
|
|
197
|
+
break;
|
|
185
198
|
case "glitching":
|
|
186
|
-
|
|
199
|
+
o = new S();
|
|
200
|
+
break;
|
|
187
201
|
case "floating":
|
|
188
|
-
|
|
202
|
+
o = new b();
|
|
203
|
+
break;
|
|
204
|
+
default:
|
|
205
|
+
o = new f();
|
|
206
|
+
}
|
|
207
|
+
return this.animationInstances.set(e, o), o;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Parse animation speed preset or numeric value to a multiplier
|
|
211
|
+
*/
|
|
212
|
+
parseAnimationSpeed(e) {
|
|
213
|
+
if (typeof e == "number")
|
|
214
|
+
return e;
|
|
215
|
+
switch (e) {
|
|
216
|
+
case "slow":
|
|
217
|
+
return 0.5;
|
|
218
|
+
case "normal":
|
|
219
|
+
return 1;
|
|
220
|
+
case "fast":
|
|
221
|
+
return 2;
|
|
189
222
|
default:
|
|
190
|
-
return
|
|
223
|
+
return 1;
|
|
191
224
|
}
|
|
192
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the current animation speed multiplier
|
|
228
|
+
*/
|
|
229
|
+
getAnimationSpeed() {
|
|
230
|
+
return this.animationSpeedMultiplier;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Set the animation speed multiplier (supports numeric values and presets)
|
|
234
|
+
*/
|
|
235
|
+
setAnimationSpeed(e) {
|
|
236
|
+
this.animationSpeedMultiplier = this.parseAnimationSpeed(e);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get the current animation easing function
|
|
240
|
+
*/
|
|
241
|
+
getAnimationEasing() {
|
|
242
|
+
return this.animationEasing;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Set the animation easing function
|
|
246
|
+
*/
|
|
247
|
+
setAnimationEasing(e) {
|
|
248
|
+
this.animationEasing = e;
|
|
249
|
+
}
|
|
193
250
|
/**
|
|
194
251
|
* Destroy the animated text instance
|
|
195
252
|
*/
|
|
196
253
|
destroy() {
|
|
197
254
|
var e;
|
|
198
|
-
this.isDestroyed || (this.isDestroyed = !0, this.animationFrame !== null && cancelAnimationFrame(this.animationFrame), this.mouseMoveHandler && document.removeEventListener("mousemove", this.mouseMoveHandler), (e = this.callbacks) != null && e.onDestroy && this.callbacks.onDestroy(), this.textContainer.style.transition = "opacity 3s ease", this.textContainer.style.opacity = "0", setTimeout(() => {
|
|
255
|
+
this.isDestroyed || (this.isDestroyed = !0, this.animationFrame !== null && cancelAnimationFrame(this.animationFrame), this.mouseMoveHandler && document.removeEventListener("mousemove", this.mouseMoveHandler), this.animationInstances.clear(), (e = this.callbacks) != null && e.onDestroy && this.callbacks.onDestroy(), this.textContainer.style.transition = "opacity 3s ease", this.textContainer.style.opacity = "0", setTimeout(() => {
|
|
199
256
|
this.textContainer.parentNode && this.textContainer.parentNode.removeChild(this.textContainer);
|
|
200
257
|
}, 3e3));
|
|
201
258
|
}
|
|
@@ -206,7 +263,7 @@ class v {
|
|
|
206
263
|
return this.textContainer;
|
|
207
264
|
}
|
|
208
265
|
}
|
|
209
|
-
const
|
|
266
|
+
const H = [
|
|
210
267
|
"unsettling",
|
|
211
268
|
"eerie",
|
|
212
269
|
"decayed",
|
|
@@ -215,7 +272,7 @@ const E = [
|
|
|
215
272
|
"imperfect",
|
|
216
273
|
"uneven",
|
|
217
274
|
"scratchy"
|
|
218
|
-
], R = ["subtle", "moderate", "intense"],
|
|
275
|
+
], R = ["subtle", "moderate", "intense"], x = [
|
|
219
276
|
// Hand-drawn / Handwriting
|
|
220
277
|
{
|
|
221
278
|
name: "Hand-drawn Casual",
|
|
@@ -494,73 +551,73 @@ const E = [
|
|
|
494
551
|
artistic: !0
|
|
495
552
|
}
|
|
496
553
|
];
|
|
497
|
-
function L(
|
|
498
|
-
const e =
|
|
554
|
+
function L(r) {
|
|
555
|
+
const e = r.toLowerCase().split(/\s+/).filter((t) => t.length > 0), o = [], a = [];
|
|
499
556
|
for (const t of e)
|
|
500
|
-
t.startsWith("-") && t.length > 1 ?
|
|
501
|
-
return { positive: o, negative:
|
|
557
|
+
t.startsWith("-") && t.length > 1 ? a.push(t.slice(1)) : o.push(t);
|
|
558
|
+
return { positive: o, negative: a };
|
|
502
559
|
}
|
|
503
|
-
function
|
|
504
|
-
const o = /* @__PURE__ */ new Set(),
|
|
505
|
-
for (const l of
|
|
560
|
+
function I(r, e) {
|
|
561
|
+
const o = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Map(), t = 2, i = [];
|
|
562
|
+
for (const l of r) {
|
|
506
563
|
if (i.length >= e) break;
|
|
507
564
|
if (o.has(l.font.googleFontsName))
|
|
508
565
|
continue;
|
|
509
|
-
const
|
|
510
|
-
|
|
566
|
+
const s = l.font.categories[0], n = a.get(s) || 0;
|
|
567
|
+
n >= t || (o.add(l.font.googleFontsName), a.set(s, n + 1), i.push(l.font));
|
|
511
568
|
}
|
|
512
569
|
return i;
|
|
513
570
|
}
|
|
514
|
-
function y(
|
|
515
|
-
const { positive: o, negative:
|
|
516
|
-
let
|
|
571
|
+
function y(r, e) {
|
|
572
|
+
const { positive: o, negative: a } = L(r), t = (e == null ? void 0 : e.limit) ?? 10, l = x.map((s) => {
|
|
573
|
+
let n = 0;
|
|
517
574
|
for (const c of o) {
|
|
518
|
-
for (const
|
|
519
|
-
(
|
|
520
|
-
|
|
575
|
+
for (const u of s.categories)
|
|
576
|
+
(u.includes(c) || c.includes(u)) && (n += 10);
|
|
577
|
+
s.name.toLowerCase().includes(c) && (n += 15), s.description.toLowerCase().includes(c) && (n += 8);
|
|
521
578
|
}
|
|
522
|
-
for (const c of
|
|
523
|
-
for (const
|
|
524
|
-
(
|
|
525
|
-
|
|
579
|
+
for (const c of a) {
|
|
580
|
+
for (const u of s.categories)
|
|
581
|
+
(u.includes(c) || c.includes(u)) && (n -= 20);
|
|
582
|
+
s.name.toLowerCase().includes(c) && (n -= 15), s.description.toLowerCase().includes(c) && (n -= 10);
|
|
526
583
|
}
|
|
527
|
-
return
|
|
528
|
-
}).filter((
|
|
529
|
-
return
|
|
584
|
+
return s.artistic && (n += 1), { font: s, score: n };
|
|
585
|
+
}).filter((s) => s.score > 0).sort((s, n) => n.score - s.score);
|
|
586
|
+
return I(l, t);
|
|
530
587
|
}
|
|
531
|
-
function
|
|
532
|
-
return y(
|
|
588
|
+
function O(r) {
|
|
589
|
+
return y(r)[0];
|
|
533
590
|
}
|
|
534
591
|
const p = /* @__PURE__ */ new Set();
|
|
535
|
-
function N(
|
|
592
|
+
function N(r) {
|
|
536
593
|
return new Promise((e, o) => {
|
|
537
|
-
const
|
|
538
|
-
if (p.has(
|
|
594
|
+
const a = r.replace(/\s+/g, "+");
|
|
595
|
+
if (p.has(a)) {
|
|
539
596
|
e();
|
|
540
597
|
return;
|
|
541
598
|
}
|
|
542
599
|
if (document.querySelector(
|
|
543
|
-
`link[href*="fonts.googleapis.com"][href*="${
|
|
600
|
+
`link[href*="fonts.googleapis.com"][href*="${a}"]`
|
|
544
601
|
)) {
|
|
545
|
-
p.add(
|
|
602
|
+
p.add(a), e();
|
|
546
603
|
return;
|
|
547
604
|
}
|
|
548
605
|
const i = document.createElement("link");
|
|
549
|
-
i.rel = "stylesheet", i.href = `https://fonts.googleapis.com/css2?family=${
|
|
550
|
-
p.add(
|
|
606
|
+
i.rel = "stylesheet", i.href = `https://fonts.googleapis.com/css2?family=${a}:wght@400&display=swap`, i.onload = () => {
|
|
607
|
+
p.add(a), e();
|
|
551
608
|
}, i.onerror = () => {
|
|
552
|
-
console.warn(`Failed to load Google Font: ${
|
|
609
|
+
console.warn(`Failed to load Google Font: ${r}`), o(new Error(`Failed to load Google Font: ${r}`));
|
|
553
610
|
}, document.head.appendChild(i);
|
|
554
611
|
});
|
|
555
612
|
}
|
|
556
|
-
function
|
|
557
|
-
return Promise.all(
|
|
613
|
+
function P(r) {
|
|
614
|
+
return Promise.all(r.map((e) => N(e)));
|
|
558
615
|
}
|
|
559
|
-
function
|
|
560
|
-
const e =
|
|
616
|
+
function B(r) {
|
|
617
|
+
const e = r.replace(/\s+/g, "+");
|
|
561
618
|
return p.has(e);
|
|
562
619
|
}
|
|
563
|
-
function
|
|
620
|
+
function G(r, e = "sans-serif") {
|
|
564
621
|
const o = [
|
|
565
622
|
"Caveat",
|
|
566
623
|
"Dancing Script",
|
|
@@ -580,7 +637,7 @@ function I(s, e = "sans-serif") {
|
|
|
580
637
|
"Kalam",
|
|
581
638
|
"Satisfy",
|
|
582
639
|
"Yellowtail"
|
|
583
|
-
],
|
|
640
|
+
], a = [
|
|
584
641
|
"VT323",
|
|
585
642
|
"Press Start 2P",
|
|
586
643
|
"Share Tech Mono",
|
|
@@ -589,68 +646,68 @@ function I(s, e = "sans-serif") {
|
|
|
589
646
|
"Cutive Mono"
|
|
590
647
|
];
|
|
591
648
|
let t = e;
|
|
592
|
-
return o.includes(
|
|
649
|
+
return o.includes(r) ? t = "cursive" : a.includes(r) && (t = "monospace"), `'${r}', ${t}`;
|
|
593
650
|
}
|
|
594
|
-
function
|
|
595
|
-
const o =
|
|
596
|
-
return y(
|
|
597
|
-
(
|
|
598
|
-
).map((
|
|
651
|
+
function M(r, e) {
|
|
652
|
+
const o = r.toLowerCase(), a = e.rejectedFont.toLowerCase(), t = e.negativeAspects.map((n) => n.toLowerCase()), i = e.positiveAspects.map((n) => n.toLowerCase());
|
|
653
|
+
return y(r).filter(
|
|
654
|
+
(n) => n.googleFontsName.toLowerCase() !== a && n.name.toLowerCase() !== a
|
|
655
|
+
).map((n) => {
|
|
599
656
|
let c = 0;
|
|
600
|
-
for (const d of
|
|
657
|
+
for (const d of n.categories)
|
|
601
658
|
o.includes(d) && (c += 5);
|
|
602
659
|
for (const d of i)
|
|
603
|
-
(
|
|
660
|
+
(n.categories.some((h) => h.includes(d) || d.includes(h)) || n.name.toLowerCase().includes(d) || n.description.toLowerCase().includes(d)) && (c += 15);
|
|
604
661
|
for (const d of t)
|
|
605
|
-
(
|
|
606
|
-
const
|
|
662
|
+
(n.categories.some((h) => h.includes(d) || d.includes(h)) || n.name.toLowerCase().includes(d) || n.description.toLowerCase().includes(d)) && (c -= 20);
|
|
663
|
+
const u = i.some(
|
|
607
664
|
(d) => d.includes("striking") || d.includes("artistic") || d.includes("unique")
|
|
608
665
|
);
|
|
609
|
-
return
|
|
610
|
-
}).filter((
|
|
666
|
+
return u && n.artistic && (c += 10), u && !n.artistic && (c -= 5), { font: n, score: c };
|
|
667
|
+
}).filter((n) => n.score > 0).sort((n, c) => c.score - n.score).map((n) => n.font);
|
|
611
668
|
}
|
|
612
|
-
function Y(
|
|
613
|
-
return
|
|
669
|
+
function Y(r, e) {
|
|
670
|
+
return M(r, e)[0];
|
|
614
671
|
}
|
|
615
672
|
if (typeof window < "u") {
|
|
616
|
-
const
|
|
673
|
+
const r = {
|
|
617
674
|
AnimatedText: v,
|
|
618
675
|
FallingAnimation: f,
|
|
619
676
|
SplittingAnimation: C,
|
|
620
|
-
GlitchingAnimation:
|
|
621
|
-
FloatingAnimation:
|
|
622
|
-
calculateDisintegration:
|
|
677
|
+
GlitchingAnimation: S,
|
|
678
|
+
FloatingAnimation: b,
|
|
679
|
+
calculateDisintegration: k,
|
|
623
680
|
// Font utilities
|
|
624
|
-
fontSuggestions:
|
|
681
|
+
fontSuggestions: x,
|
|
625
682
|
suggestFonts: y,
|
|
626
|
-
suggestFont:
|
|
683
|
+
suggestFont: O,
|
|
627
684
|
loadGoogleFont: N,
|
|
628
|
-
loadGoogleFonts:
|
|
629
|
-
isFontLoaded:
|
|
630
|
-
getFontFamily:
|
|
631
|
-
refineSuggestion:
|
|
685
|
+
loadGoogleFonts: P,
|
|
686
|
+
isFontLoaded: B,
|
|
687
|
+
getFontFamily: G,
|
|
688
|
+
refineSuggestion: M,
|
|
632
689
|
refineFont: Y,
|
|
633
|
-
MOOD_CATEGORIES:
|
|
690
|
+
MOOD_CATEGORIES: H,
|
|
634
691
|
INTENSITY_CATEGORIES: R
|
|
635
692
|
};
|
|
636
|
-
window.TypographyToolkit =
|
|
693
|
+
window.TypographyToolkit = r, window.AnimatedText = v;
|
|
637
694
|
}
|
|
638
695
|
export {
|
|
639
696
|
v as AnimatedText,
|
|
640
697
|
f as FallingAnimation,
|
|
641
|
-
|
|
642
|
-
|
|
698
|
+
b as FloatingAnimation,
|
|
699
|
+
S as GlitchingAnimation,
|
|
643
700
|
R as INTENSITY_CATEGORIES,
|
|
644
|
-
|
|
701
|
+
H as MOOD_CATEGORIES,
|
|
645
702
|
C as SplittingAnimation,
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
703
|
+
k as calculateDisintegration,
|
|
704
|
+
x as fontSuggestions,
|
|
705
|
+
G as getFontFamily,
|
|
706
|
+
B as isFontLoaded,
|
|
650
707
|
N as loadGoogleFont,
|
|
651
|
-
|
|
708
|
+
P as loadGoogleFonts,
|
|
652
709
|
Y as refineFont,
|
|
653
|
-
|
|
654
|
-
|
|
710
|
+
M as refineSuggestion,
|
|
711
|
+
O as suggestFont,
|
|
655
712
|
y as suggestFonts
|
|
656
713
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var TypographyToolkit=function(g){"use strict";class f{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||20,r=o*.2,c=(n*10*i+r*5)%l-l/2;return{...e,y:c}}}class F{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||4,r=o*.2,a=Math.sin(n*.5*i+r)*l;return{...e,x:a}}}class v{constructor(){this.lastUpdate=0,this.glitchX=0,this.glitchY=0,this.glitchRot=0}update(e,o,n,t={}){const i=t.amplitude||3;return n-this.lastUpdate>.1&&(this.glitchX=(Math.random()-.5)*i,this.glitchY=(Math.random()-.5)*(i*.67),this.glitchRot=(Math.random()-.5)*i,this.lastUpdate=n),{...e,x:this.glitchX,y:this.glitchY,rotation:this.glitchRot}}}class C{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||15,r=o*.2,c=-((n*8*i+r*4)%l-l/2);return{...e,y:c}}}function G(s,e){const{x:o,y:n,rotation:t,scale:i,opacity:l}=e;s.style.transform=`translate(${o}px, ${n}px) rotate(${t}deg) scale(${i})`,s.style.opacity=l.toString()}function S(s,e,o,n,t,i){if(!i.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const l=i.radius||80,r=i.strength||1,a=i.behaviors||["fall-away","split-apart","explode"],c=o-s,h=n-e,d=Math.sqrt(c*c+h*h);if(d>=l)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const u=(1-d/l)*r,m=Math.atan2(h,c),B=a[t%a.length];let p;switch(B){case"fall-away":const Y=Math.cos(m)*u*20,$=Math.sin(m)*u*40+u*30;p={x:Y,y:$,rotation:u*15,scale:1,opacity:1-u*.6};break;case"split-apart":const L=t%2===0?1:-1;p={x:L*u*50,y:(Math.random()-.5)*u*10,rotation:u*10*L,scale:1,opacity:1-u*.6};break;case"explode":const O=m+(Math.random()-.5)*.5;p={x:Math.cos(O)*u*40,y:Math.sin(O)*u*40,rotation:u*30,scale:1+u*.4,opacity:1-u*.6};break;default:p={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:p,applied:!0}}class b{constructor(e){var o;if(this.letters=[],this.animationFrame=null,this.mouseX=0,this.mouseY=0,this.mouseMoveHandler=null,this.startTime=Date.now(),this.isDestroyed=!1,this.container=e.container,this.animationTypes=e.animations||["falling","splitting","glitching","floating"],this.cycle=e.cycle!==!1,this.speed=e.speed||1,this.amplitude=e.amplitude||1,this.disintegration=e.disintegration||{enabled:!1},this.style=e.style||{},this.fadeOut=e.fadeOut||0,this.callbacks=e.callbacks,this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",e.containerClass&&(this.textContainer.className=e.containerClass),e.containerStyle&&Object.entries(e.containerStyle).forEach(([n,t])=>{this.textContainer.style.setProperty(n,t)}),e.position){let n=e.position.x,t=e.position.y;if(e.position.constrainToViewport){this.container.getBoundingClientRect();const i=window.innerWidth,l=window.innerHeight,r=e.text.length*20;n!==void 0&&(n=Math.max(0,Math.min(n,i-r))),t!==void 0&&(t=Math.max(0,Math.min(t,l-50)))}n!==void 0&&(this.textContainer.style.left=`${n}px`),t!==void 0&&(this.textContainer.style.top=`${t}px`)}this.createLetters(e.text),this.setupMouseTracking(),this.startAnimation(),(o=this.callbacks)!=null&&o.onCreate&&this.callbacks.onCreate(this.textContainer),this.fadeOut>0&&setTimeout(()=>this.destroy(),this.fadeOut)}createLetters(e){e.toUpperCase().split("").forEach((n,t)=>{if(n===" "){const r=document.createTextNode(" ");this.textContainer.appendChild(r);return}const i=document.createElement("span");i.className="animated-letter",i.textContent=n,i.dataset.index=t.toString(),i.dataset.char=n,this.applyStyle(i),i.style.display="inline-block",i.style.position="relative",i.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(i);const l=i.getBoundingClientRect();this.letters.push({element:i,index:t,char:n,baseX:l.left,baseY:l.top})}),this.container.appendChild(this.textContainer)}applyStyle(e){this.style.fontFamily&&(e.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(e.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(e.style.color=this.style.color),this.style.fontWeight&&(e.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(e.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(e.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(e.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=e=>{this.mouseX=e.clientX,this.mouseY=e.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const e=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((n,t)=>{var h;const i=n.element.getBoundingClientRect(),l=i.left+i.width/2,r=i.top+i.height/2,a=S(l,r,this.mouseX,this.mouseY,t,this.disintegration);let c;if(a.applied)c=a.state,(h=this.callbacks)!=null&&h.onDisintegrate&&this.callbacks.onDisintegrate(t);else{const d=this.getAnimationType(t);c=this.getAnimation(d).update({x:0,y:0,rotation:0,scale:1,opacity:1},t,o,{speed:this.speed,amplitude:this.amplitude*(d==="falling"||d==="floating"?20:4)})}G(n.element,c)}),this.animationFrame=requestAnimationFrame(e)};this.animationFrame=requestAnimationFrame(e)}getAnimationType(e){return this.cycle?this.animationTypes[e%this.animationTypes.length]:this.animationTypes[0]}getAnimation(e){switch(e){case"falling":return new f;case"splitting":return new F;case"glitching":return new v;case"floating":return new C;default:return new f}}destroy(){var e;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),(e=this.callbacks)!=null&&e.onDestroy&&this.callbacks.onDestroy(),this.textContainer.style.transition="opacity 3s ease",this.textContainer.style.opacity="0",setTimeout(()=>{this.textContainer.parentNode&&this.textContainer.parentNode.removeChild(this.textContainer)},3e3))}getElement(){return this.textContainer}}const x=["unsettling","eerie","decayed","weathered","organic","imperfect","uneven","scratchy"],M=["subtle","moderate","intense"],k=[{name:"Hand-drawn Casual",googleFontsName:"Caveat",categories:["hand-drawn","handwriting","casual","sketchy","informal"],description:"Casual handwritten style, friendly and approachable",artistic:!1},{name:"Hand-drawn Playful",googleFontsName:"Finger Paint",categories:["hand-drawn","playful","childlike","casual","sketchy"],description:"Bold hand-drawn style, playful and energetic",artistic:!0},{name:"Hand-drawn Script",googleFontsName:"Dancing Script",categories:["hand-drawn","script","elegant","flowing","cursive"],description:"Elegant flowing script, graceful and organic",artistic:!1},{name:"Gothic Blackletter",googleFontsName:"UnifrakturMaguntia",categories:["gothic","medieval","blackletter","ornate","historical"],description:"Medieval blackletter style, ornate and historical",artistic:!0},{name:"Gothic Horror",googleFontsName:"Creepster",categories:["gothic","horror","creepy","dripping","display","striking","intense"],description:"Horror-style font with dripping effects, very striking",artistic:!0},{name:"Gothic Bold",googleFontsName:"Eater",categories:["gothic","bold","aggressive","display","striking"],description:"Bold aggressive display font, powerful impact",artistic:!0},{name:"Futuristic Digital",googleFontsName:"Orbitron",categories:["futuristic","sci-fi","digital","tech","modern","geometric"],description:"Futuristic geometric font, tech-forward and modern",artistic:!0},{name:"Futuristic Display",googleFontsName:"Bungee",categories:["futuristic","display","bold","condensed","striking"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Futuristic Outline",googleFontsName:"Bungee Shade",categories:["futuristic","outline","display","bold","striking"],description:"Outlined version of Bungee, bold and striking",artistic:!0},{name:"Retro Terminal",googleFontsName:"VT323",categories:["retro","terminal","monospace","pixel","80s","tech"],description:"Retro terminal font, pixelated and nostalgic",artistic:!0},{name:"Retro Pixel",googleFontsName:"Press Start 2P",categories:["retro","pixel","8-bit","arcade","nostalgic","display"],description:"8-bit pixel font, classic arcade style",artistic:!0},{name:"Retro Display",googleFontsName:"Frijole",categories:["retro","playful","rounded","display","casual"],description:"Playful rounded retro font, fun and casual",artistic:!0},{name:"Decorative Ornate",googleFontsName:"Fascinate",categories:["decorative","ornate","display","striking","elaborate"],description:"Highly decorative display font, ornate and elaborate",artistic:!0},{name:"Decorative Outline",googleFontsName:"Fascinate Inline",categories:["decorative","outline","display","ornate","striking"],description:"Outlined decorative font, ornate and striking",artistic:!0},{name:"Decorative Script",googleFontsName:"Fredericka the Great",categories:["decorative","script","ornate","elegant","display"],description:"Elegant decorative script, ornate and sophisticated",artistic:!0},{name:"Horror Dripping",googleFontsName:"Nosifer",categories:["horror","creepy","dripping","blood","striking","display","intense"],description:"Creepy font with blood-dripping effects, very striking",artistic:!0},{name:"Tech Monospace",googleFontsName:"Share Tech Mono",categories:["tech","monospace","terminal","code","modern"],description:"Clean tech monospace font, modern and readable",artistic:!1},{name:"Tech Display",googleFontsName:"Rajdhani",categories:["tech","modern","geometric","sans-serif","futuristic"],description:"Modern geometric tech font, clean and futuristic",artistic:!1},{name:"Organic Flowing",googleFontsName:"Dancing Script",categories:["organic","flowing","natural","script","elegant"],description:"Flowing organic script, natural and elegant",artistic:!1},{name:"Modern Sans",googleFontsName:"Roboto",categories:["modern","clean","sans-serif","readable","professional"],description:"Clean modern sans-serif, professional and readable",artistic:!1},{name:"Modern Serif",googleFontsName:"Playfair Display",categories:["modern","serif","elegant","sophisticated","readable"],description:"Elegant modern serif, sophisticated and readable",artistic:!1},{name:"Bold Condensed",googleFontsName:"Bungee",categories:["bold","condensed","display","striking","impact"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Bold Aggressive",googleFontsName:"Eater",categories:["bold","aggressive","display","striking","powerful"],description:"Bold aggressive display font, powerful and striking",artistic:!0},{name:"Handwritten Thin",googleFontsName:"Amatic SC",categories:["hand-drawn","uneven","organic","unsettling","subtle","scratchy"],description:"Thin hand-drawn letters with subtle irregularity, organic feel",artistic:!0},{name:"Rough Handwriting",googleFontsName:"Rock Salt",categories:["hand-drawn","scratchy","weathered","rough","unsettling","moderate"],description:"Rough, weathered handwriting with natural imperfection",artistic:!0},{name:"Typewriter Degraded",googleFontsName:"Special Elite",categories:["typewriter","decayed","weathered","imperfect","unsettling","moderate"],description:"Degraded typewriter font, vintage with imperfection",artistic:!0},{name:"Casual Handwriting",googleFontsName:"Handlee",categories:["hand-drawn","casual","imperfect","organic","subtle"],description:"Casual handwriting with subtle imperfection",artistic:!1},{name:"Childlike Organic",googleFontsName:"Indie Flower",categories:["hand-drawn","childlike","organic","imperfect","eerie","subtle"],description:"Childlike handwriting, can feel innocent or eerie depending on context",artistic:!1},{name:"Scratchy Personal",googleFontsName:"Shadows Into Light",categories:["hand-drawn","scratchy","personal","unsettling","uneven","moderate"],description:"Scratchy personal handwriting with unsettling quality",artistic:!0},{name:"Hurried Scratchy",googleFontsName:"Reenie Beanie",categories:["hand-drawn","scratchy","hurried","uneven","unsettling","moderate"],description:"Hurried scratchy handwriting with nervous energy",artistic:!0},{name:"Architectural Irregular",googleFontsName:"Architects Daughter",categories:["hand-drawn","imperfect","uneven","organic","subtle"],description:"Hand-drawn with architectural irregularity",artistic:!1},{name:"Informal Unsettling",googleFontsName:"Coming Soon",categories:["hand-drawn","informal","imperfect","unsettling","subtle"],description:"Informal handwriting that feels slightly off",artistic:!1},{name:"Manic Handwriting",googleFontsName:"Gloria Hallelujah",categories:["hand-drawn","playful","manic","uneven","unsettling","moderate"],description:"Playful handwriting that can feel manic or unsettled",artistic:!0},{name:"Quick Imperfect",googleFontsName:"Just Another Hand",categories:["hand-drawn","scratchy","quick","imperfect","uneven","subtle"],description:"Quick scratchy handwriting with natural imperfection",artistic:!1},{name:"Organic Handwriting",googleFontsName:"Kalam",categories:["hand-drawn","organic","natural","flowing","subtle"],description:"Organic natural handwriting with flowing quality",artistic:!1},{name:"Flowing Tension",googleFontsName:"Satisfy",categories:["script","flowing","tension","elegant","unsettling","subtle"],description:"Flowing script with underlying tension",artistic:!0},{name:"Unsettling Elegance",googleFontsName:"Yellowtail",categories:["script","elegant","stylized","unsettling","uneven","moderate"],description:"Stylized elegance with unsettling undertones",artistic:!0},{name:"Typewriter Imperfect",googleFontsName:"Cutive Mono",categories:["typewriter","monospace","imperfect","decayed","vintage","subtle"],description:"Imperfect vintage typewriter with character",artistic:!0}];function I(s){const e=s.toLowerCase().split(/\s+/).filter(t=>t.length>0),o=[],n=[];for(const t of e)t.startsWith("-")&&t.length>1?n.push(t.slice(1)):o.push(t);return{positive:o,negative:n}}function P(s,e){const o=new Set,n=new Map,t=2,i=[];for(const l of s){if(i.length>=e)break;if(o.has(l.font.googleFontsName))continue;const r=l.font.categories[0],a=n.get(r)||0;a>=t||(o.add(l.font.googleFontsName),n.set(r,a+1),i.push(l.font))}return i}function y(s,e){const{positive:o,negative:n}=I(s),t=(e==null?void 0:e.limit)??10,l=k.map(r=>{let a=0;for(const c of o){for(const h of r.categories)(h.includes(c)||c.includes(h))&&(a+=10);r.name.toLowerCase().includes(c)&&(a+=15),r.description.toLowerCase().includes(c)&&(a+=8)}for(const c of n){for(const h of r.categories)(h.includes(c)||c.includes(h))&&(a-=20);r.name.toLowerCase().includes(c)&&(a-=15),r.description.toLowerCase().includes(c)&&(a-=10)}return r.artistic&&(a+=1),{font:r,score:a}}).filter(r=>r.score>0).sort((r,a)=>a.score-r.score);return P(l,t)}function A(s){return y(s)[0]}const w=new Set;function N(s){return new Promise((e,o)=>{const n=s.replace(/\s+/g,"+");if(w.has(n)){e();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${n}"]`)){w.add(n),e();return}const i=document.createElement("link");i.rel="stylesheet",i.href=`https://fonts.googleapis.com/css2?family=${n}:wght@400&display=swap`,i.onload=()=>{w.add(n),e()},i.onerror=()=>{console.warn(`Failed to load Google Font: ${s}`),o(new Error(`Failed to load Google Font: ${s}`))},document.head.appendChild(i)})}function D(s){return Promise.all(s.map(e=>N(e)))}function E(s){const e=s.replace(/\s+/g,"+");return w.has(e)}function H(s,e="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great","Amatic SC","Handlee","Indie Flower","Shadows Into Light","Rock Salt","Reenie Beanie","Architects Daughter","Coming Soon","Gloria Hallelujah","Just Another Hand","Kalam","Satisfy","Yellowtail"],n=["VT323","Press Start 2P","Share Tech Mono","Special Elite","Cutive Mono"];let t=e;return o.includes(s)?t="cursive":n.includes(s)&&(t="monospace"),`'${s}', ${t}`}function T(s,e){const o=s.toLowerCase(),n=e.rejectedFont.toLowerCase(),t=e.negativeAspects.map(a=>a.toLowerCase()),i=e.positiveAspects.map(a=>a.toLowerCase());return y(s).filter(a=>a.googleFontsName.toLowerCase()!==n&&a.name.toLowerCase()!==n).map(a=>{let c=0;for(const d of a.categories)o.includes(d)&&(c+=5);for(const d of i)(a.categories.some(m=>m.includes(d)||d.includes(m))||a.name.toLowerCase().includes(d)||a.description.toLowerCase().includes(d))&&(c+=15);for(const d of t)(a.categories.some(m=>m.includes(d)||d.includes(m))||a.name.toLowerCase().includes(d)||a.description.toLowerCase().includes(d))&&(c-=20);const h=i.some(d=>d.includes("striking")||d.includes("artistic")||d.includes("unique"));return h&&a.artistic&&(c+=10),h&&!a.artistic&&(c-=5),{font:a,score:c}}).filter(a=>a.score>0).sort((a,c)=>c.score-a.score).map(a=>a.font)}function R(s,e){return T(s,e)[0]}if(typeof window<"u"){const s={AnimatedText:b,FallingAnimation:f,SplittingAnimation:F,GlitchingAnimation:v,FloatingAnimation:C,calculateDisintegration:S,fontSuggestions:k,suggestFonts:y,suggestFont:A,loadGoogleFont:N,loadGoogleFonts:D,isFontLoaded:E,getFontFamily:H,refineSuggestion:T,refineFont:R,MOOD_CATEGORIES:x,INTENSITY_CATEGORIES:M};window.TypographyToolkit=s,window.AnimatedText=b}return g.AnimatedText=b,g.FallingAnimation=f,g.FloatingAnimation=C,g.GlitchingAnimation=v,g.INTENSITY_CATEGORIES=M,g.MOOD_CATEGORIES=x,g.SplittingAnimation=F,g.calculateDisintegration=S,g.fontSuggestions=k,g.getFontFamily=H,g.isFontLoaded=E,g.loadGoogleFont=N,g.loadGoogleFonts=D,g.refineFont=R,g.refineSuggestion=T,g.suggestFont=A,g.suggestFonts=y,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"}),g}({});
|
|
1
|
+
var TypographyToolkit=function(g){"use strict";class f{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||20,s=o*.2,c=(a*10*i+s*5)%l-l/2;return{...e,y:c}}}class F{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||4,s=o*.2,n=Math.sin(a*.5*i+s)*l;return{...e,x:n}}}class S{constructor(){this.letterStates=new Map}update(e,o,a,t={}){const i=t.amplitude||3,l=t.speed||1;let s=this.letterStates.get(o);s||(s={lastUpdate:a,glitchX:0,glitchY:0,glitchRot:0},this.letterStates.set(o,s));const n=.1/l;return a-s.lastUpdate>n&&(s.glitchX=(Math.random()-.5)*i,s.glitchY=(Math.random()-.5)*(i*.67),s.glitchRot=(Math.random()-.5)*i,s.lastUpdate=a),{...e,x:s.glitchX,y:s.glitchY,rotation:s.glitchRot}}}class v{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||15,s=o*.2,c=-((a*8*i+s*4)%l-l/2);return{...e,y:c}}}function O(r,e){const{x:o,y:a,rotation:t,scale:i,opacity:l}=e;r.style.transform=`translate(${o}px, ${a}px) rotate(${t}deg) scale(${i})`,r.style.opacity=l.toString()}function C(r,e,o,a,t,i){if(!i.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const l=i.radius||80,s=i.strength||1,n=i.behaviors||["fall-away","split-apart","explode"],c=o-r,h=a-e,d=Math.sqrt(c*c+h*h);if(d>=l)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const u=(1-d/l)*s,m=Math.atan2(h,c),B=n[t%n.length];let p;switch(B){case"fall-away":const Y=Math.cos(m)*u*20,$=Math.sin(m)*u*40+u*30;p={x:Y,y:$,rotation:u*15,scale:1,opacity:1-u*.6};break;case"split-apart":const I=t%2===0?1:-1;p={x:I*u*50,y:(Math.random()-.5)*u*10,rotation:u*10*I,scale:1,opacity:1-u*.6};break;case"explode":const L=m+(Math.random()-.5)*.5;p={x:Math.cos(L)*u*40,y:Math.sin(L)*u*40,rotation:u*30,scale:1+u*.4,opacity:1-u*.6};break;default:p={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:p,applied:!0}}class b{constructor(e){var o;if(this.letters=[],this.animationSpeedMultiplier=1,this.animationFrame=null,this.mouseX=0,this.mouseY=0,this.mouseMoveHandler=null,this.startTime=Date.now(),this.isDestroyed=!1,this.animationInstances=new Map,this.container=e.container,this.animationTypes=e.animations||["falling","splitting","glitching","floating"],this.cycle=e.cycle!==!1,this.speed=e.speed||1,this.amplitude=e.amplitude||1,this.animationEasing=e.animationEasing||"linear",this.disintegration=e.disintegration||{enabled:!1},this.style=e.style||{},this.fadeOut=e.fadeOut||0,this.callbacks=e.callbacks,e.animationSpeed!==void 0&&(this.animationSpeedMultiplier=this.parseAnimationSpeed(e.animationSpeed)),this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",e.containerClass&&(this.textContainer.className=e.containerClass),e.containerStyle&&Object.entries(e.containerStyle).forEach(([a,t])=>{this.textContainer.style.setProperty(a,t)}),e.position){let a=e.position.x,t=e.position.y;if(e.position.constrainToViewport){this.container.getBoundingClientRect();const i=window.innerWidth,l=window.innerHeight,s=e.text.length*20;a!==void 0&&(a=Math.max(0,Math.min(a,i-s))),t!==void 0&&(t=Math.max(0,Math.min(t,l-50)))}a!==void 0&&(this.textContainer.style.left=`${a}px`),t!==void 0&&(this.textContainer.style.top=`${t}px`)}this.createLetters(e.text),this.setupMouseTracking(),this.startAnimation(),(o=this.callbacks)!=null&&o.onCreate&&this.callbacks.onCreate(this.textContainer),this.fadeOut>0&&setTimeout(()=>this.destroy(),this.fadeOut)}createLetters(e){e.toUpperCase().split("").forEach((a,t)=>{if(a===" "){const s=document.createTextNode(" ");this.textContainer.appendChild(s);return}const i=document.createElement("span");i.className="animated-letter",i.textContent=a,i.dataset.index=t.toString(),i.dataset.char=a,this.applyStyle(i),i.style.display="inline-block",i.style.position="relative",i.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(i);const l=i.getBoundingClientRect();this.letters.push({element:i,index:t,char:a,baseX:l.left,baseY:l.top})}),this.container.appendChild(this.textContainer)}applyStyle(e){this.style.fontFamily&&(e.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(e.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(e.style.color=this.style.color),this.style.fontWeight&&(e.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(e.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(e.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(e.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=e=>{this.mouseX=e.clientX,this.mouseY=e.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const e=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((a,t)=>{var h;const i=a.element.getBoundingClientRect(),l=i.left+i.width/2,s=i.top+i.height/2,n=C(l,s,this.mouseX,this.mouseY,t,this.disintegration);let c;if(n.applied)c=n.state,(h=this.callbacks)!=null&&h.onDisintegrate&&this.callbacks.onDisintegrate(t);else{const d=this.getAnimationType(t);c=this.getAnimation(d).update({x:0,y:0,rotation:0,scale:1,opacity:1},t,o,{speed:this.speed*this.animationSpeedMultiplier,amplitude:this.amplitude*(d==="falling"||d==="floating"?20:4)})}O(a.element,c)}),this.animationFrame=requestAnimationFrame(e)};this.animationFrame=requestAnimationFrame(e)}getAnimationType(e){return this.cycle?this.animationTypes[e%this.animationTypes.length]:this.animationTypes[0]}getAnimation(e){if(this.animationInstances.has(e))return this.animationInstances.get(e);let o;switch(e){case"falling":o=new f;break;case"splitting":o=new F;break;case"glitching":o=new S;break;case"floating":o=new v;break;default:o=new f}return this.animationInstances.set(e,o),o}parseAnimationSpeed(e){if(typeof e=="number")return e;switch(e){case"slow":return .5;case"normal":return 1;case"fast":return 2;default:return 1}}getAnimationSpeed(){return this.animationSpeedMultiplier}setAnimationSpeed(e){this.animationSpeedMultiplier=this.parseAnimationSpeed(e)}getAnimationEasing(){return this.animationEasing}setAnimationEasing(e){this.animationEasing=e}destroy(){var e;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),this.animationInstances.clear(),(e=this.callbacks)!=null&&e.onDestroy&&this.callbacks.onDestroy(),this.textContainer.style.transition="opacity 3s ease",this.textContainer.style.opacity="0",setTimeout(()=>{this.textContainer.parentNode&&this.textContainer.parentNode.removeChild(this.textContainer)},3e3))}getElement(){return this.textContainer}}const M=["unsettling","eerie","decayed","weathered","organic","imperfect","uneven","scratchy"],A=["subtle","moderate","intense"],k=[{name:"Hand-drawn Casual",googleFontsName:"Caveat",categories:["hand-drawn","handwriting","casual","sketchy","informal"],description:"Casual handwritten style, friendly and approachable",artistic:!1},{name:"Hand-drawn Playful",googleFontsName:"Finger Paint",categories:["hand-drawn","playful","childlike","casual","sketchy"],description:"Bold hand-drawn style, playful and energetic",artistic:!0},{name:"Hand-drawn Script",googleFontsName:"Dancing Script",categories:["hand-drawn","script","elegant","flowing","cursive"],description:"Elegant flowing script, graceful and organic",artistic:!1},{name:"Gothic Blackletter",googleFontsName:"UnifrakturMaguntia",categories:["gothic","medieval","blackletter","ornate","historical"],description:"Medieval blackletter style, ornate and historical",artistic:!0},{name:"Gothic Horror",googleFontsName:"Creepster",categories:["gothic","horror","creepy","dripping","display","striking","intense"],description:"Horror-style font with dripping effects, very striking",artistic:!0},{name:"Gothic Bold",googleFontsName:"Eater",categories:["gothic","bold","aggressive","display","striking"],description:"Bold aggressive display font, powerful impact",artistic:!0},{name:"Futuristic Digital",googleFontsName:"Orbitron",categories:["futuristic","sci-fi","digital","tech","modern","geometric"],description:"Futuristic geometric font, tech-forward and modern",artistic:!0},{name:"Futuristic Display",googleFontsName:"Bungee",categories:["futuristic","display","bold","condensed","striking"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Futuristic Outline",googleFontsName:"Bungee Shade",categories:["futuristic","outline","display","bold","striking"],description:"Outlined version of Bungee, bold and striking",artistic:!0},{name:"Retro Terminal",googleFontsName:"VT323",categories:["retro","terminal","monospace","pixel","80s","tech"],description:"Retro terminal font, pixelated and nostalgic",artistic:!0},{name:"Retro Pixel",googleFontsName:"Press Start 2P",categories:["retro","pixel","8-bit","arcade","nostalgic","display"],description:"8-bit pixel font, classic arcade style",artistic:!0},{name:"Retro Display",googleFontsName:"Frijole",categories:["retro","playful","rounded","display","casual"],description:"Playful rounded retro font, fun and casual",artistic:!0},{name:"Decorative Ornate",googleFontsName:"Fascinate",categories:["decorative","ornate","display","striking","elaborate"],description:"Highly decorative display font, ornate and elaborate",artistic:!0},{name:"Decorative Outline",googleFontsName:"Fascinate Inline",categories:["decorative","outline","display","ornate","striking"],description:"Outlined decorative font, ornate and striking",artistic:!0},{name:"Decorative Script",googleFontsName:"Fredericka the Great",categories:["decorative","script","ornate","elegant","display"],description:"Elegant decorative script, ornate and sophisticated",artistic:!0},{name:"Horror Dripping",googleFontsName:"Nosifer",categories:["horror","creepy","dripping","blood","striking","display","intense"],description:"Creepy font with blood-dripping effects, very striking",artistic:!0},{name:"Tech Monospace",googleFontsName:"Share Tech Mono",categories:["tech","monospace","terminal","code","modern"],description:"Clean tech monospace font, modern and readable",artistic:!1},{name:"Tech Display",googleFontsName:"Rajdhani",categories:["tech","modern","geometric","sans-serif","futuristic"],description:"Modern geometric tech font, clean and futuristic",artistic:!1},{name:"Organic Flowing",googleFontsName:"Dancing Script",categories:["organic","flowing","natural","script","elegant"],description:"Flowing organic script, natural and elegant",artistic:!1},{name:"Modern Sans",googleFontsName:"Roboto",categories:["modern","clean","sans-serif","readable","professional"],description:"Clean modern sans-serif, professional and readable",artistic:!1},{name:"Modern Serif",googleFontsName:"Playfair Display",categories:["modern","serif","elegant","sophisticated","readable"],description:"Elegant modern serif, sophisticated and readable",artistic:!1},{name:"Bold Condensed",googleFontsName:"Bungee",categories:["bold","condensed","display","striking","impact"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Bold Aggressive",googleFontsName:"Eater",categories:["bold","aggressive","display","striking","powerful"],description:"Bold aggressive display font, powerful and striking",artistic:!0},{name:"Handwritten Thin",googleFontsName:"Amatic SC",categories:["hand-drawn","uneven","organic","unsettling","subtle","scratchy"],description:"Thin hand-drawn letters with subtle irregularity, organic feel",artistic:!0},{name:"Rough Handwriting",googleFontsName:"Rock Salt",categories:["hand-drawn","scratchy","weathered","rough","unsettling","moderate"],description:"Rough, weathered handwriting with natural imperfection",artistic:!0},{name:"Typewriter Degraded",googleFontsName:"Special Elite",categories:["typewriter","decayed","weathered","imperfect","unsettling","moderate"],description:"Degraded typewriter font, vintage with imperfection",artistic:!0},{name:"Casual Handwriting",googleFontsName:"Handlee",categories:["hand-drawn","casual","imperfect","organic","subtle"],description:"Casual handwriting with subtle imperfection",artistic:!1},{name:"Childlike Organic",googleFontsName:"Indie Flower",categories:["hand-drawn","childlike","organic","imperfect","eerie","subtle"],description:"Childlike handwriting, can feel innocent or eerie depending on context",artistic:!1},{name:"Scratchy Personal",googleFontsName:"Shadows Into Light",categories:["hand-drawn","scratchy","personal","unsettling","uneven","moderate"],description:"Scratchy personal handwriting with unsettling quality",artistic:!0},{name:"Hurried Scratchy",googleFontsName:"Reenie Beanie",categories:["hand-drawn","scratchy","hurried","uneven","unsettling","moderate"],description:"Hurried scratchy handwriting with nervous energy",artistic:!0},{name:"Architectural Irregular",googleFontsName:"Architects Daughter",categories:["hand-drawn","imperfect","uneven","organic","subtle"],description:"Hand-drawn with architectural irregularity",artistic:!1},{name:"Informal Unsettling",googleFontsName:"Coming Soon",categories:["hand-drawn","informal","imperfect","unsettling","subtle"],description:"Informal handwriting that feels slightly off",artistic:!1},{name:"Manic Handwriting",googleFontsName:"Gloria Hallelujah",categories:["hand-drawn","playful","manic","uneven","unsettling","moderate"],description:"Playful handwriting that can feel manic or unsettled",artistic:!0},{name:"Quick Imperfect",googleFontsName:"Just Another Hand",categories:["hand-drawn","scratchy","quick","imperfect","uneven","subtle"],description:"Quick scratchy handwriting with natural imperfection",artistic:!1},{name:"Organic Handwriting",googleFontsName:"Kalam",categories:["hand-drawn","organic","natural","flowing","subtle"],description:"Organic natural handwriting with flowing quality",artistic:!1},{name:"Flowing Tension",googleFontsName:"Satisfy",categories:["script","flowing","tension","elegant","unsettling","subtle"],description:"Flowing script with underlying tension",artistic:!0},{name:"Unsettling Elegance",googleFontsName:"Yellowtail",categories:["script","elegant","stylized","unsettling","uneven","moderate"],description:"Stylized elegance with unsettling undertones",artistic:!0},{name:"Typewriter Imperfect",googleFontsName:"Cutive Mono",categories:["typewriter","monospace","imperfect","decayed","vintage","subtle"],description:"Imperfect vintage typewriter with character",artistic:!0}];function G(r){const e=r.toLowerCase().split(/\s+/).filter(t=>t.length>0),o=[],a=[];for(const t of e)t.startsWith("-")&&t.length>1?a.push(t.slice(1)):o.push(t);return{positive:o,negative:a}}function P(r,e){const o=new Set,a=new Map,t=2,i=[];for(const l of r){if(i.length>=e)break;if(o.has(l.font.googleFontsName))continue;const s=l.font.categories[0],n=a.get(s)||0;n>=t||(o.add(l.font.googleFontsName),a.set(s,n+1),i.push(l.font))}return i}function y(r,e){const{positive:o,negative:a}=G(r),t=(e==null?void 0:e.limit)??10,l=k.map(s=>{let n=0;for(const c of o){for(const h of s.categories)(h.includes(c)||c.includes(h))&&(n+=10);s.name.toLowerCase().includes(c)&&(n+=15),s.description.toLowerCase().includes(c)&&(n+=8)}for(const c of a){for(const h of s.categories)(h.includes(c)||c.includes(h))&&(n-=20);s.name.toLowerCase().includes(c)&&(n-=15),s.description.toLowerCase().includes(c)&&(n-=10)}return s.artistic&&(n+=1),{font:s,score:n}}).filter(s=>s.score>0).sort((s,n)=>n.score-s.score);return P(l,t)}function x(r){return y(r)[0]}const w=new Set;function N(r){return new Promise((e,o)=>{const a=r.replace(/\s+/g,"+");if(w.has(a)){e();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${a}"]`)){w.add(a),e();return}const i=document.createElement("link");i.rel="stylesheet",i.href=`https://fonts.googleapis.com/css2?family=${a}:wght@400&display=swap`,i.onload=()=>{w.add(a),e()},i.onerror=()=>{console.warn(`Failed to load Google Font: ${r}`),o(new Error(`Failed to load Google Font: ${r}`))},document.head.appendChild(i)})}function E(r){return Promise.all(r.map(e=>N(e)))}function D(r){const e=r.replace(/\s+/g,"+");return w.has(e)}function H(r,e="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great","Amatic SC","Handlee","Indie Flower","Shadows Into Light","Rock Salt","Reenie Beanie","Architects Daughter","Coming Soon","Gloria Hallelujah","Just Another Hand","Kalam","Satisfy","Yellowtail"],a=["VT323","Press Start 2P","Share Tech Mono","Special Elite","Cutive Mono"];let t=e;return o.includes(r)?t="cursive":a.includes(r)&&(t="monospace"),`'${r}', ${t}`}function T(r,e){const o=r.toLowerCase(),a=e.rejectedFont.toLowerCase(),t=e.negativeAspects.map(n=>n.toLowerCase()),i=e.positiveAspects.map(n=>n.toLowerCase());return y(r).filter(n=>n.googleFontsName.toLowerCase()!==a&&n.name.toLowerCase()!==a).map(n=>{let c=0;for(const d of n.categories)o.includes(d)&&(c+=5);for(const d of i)(n.categories.some(m=>m.includes(d)||d.includes(m))||n.name.toLowerCase().includes(d)||n.description.toLowerCase().includes(d))&&(c+=15);for(const d of t)(n.categories.some(m=>m.includes(d)||d.includes(m))||n.name.toLowerCase().includes(d)||n.description.toLowerCase().includes(d))&&(c-=20);const h=i.some(d=>d.includes("striking")||d.includes("artistic")||d.includes("unique"));return h&&n.artistic&&(c+=10),h&&!n.artistic&&(c-=5),{font:n,score:c}}).filter(n=>n.score>0).sort((n,c)=>c.score-n.score).map(n=>n.font)}function R(r,e){return T(r,e)[0]}if(typeof window<"u"){const r={AnimatedText:b,FallingAnimation:f,SplittingAnimation:F,GlitchingAnimation:S,FloatingAnimation:v,calculateDisintegration:C,fontSuggestions:k,suggestFonts:y,suggestFont:x,loadGoogleFont:N,loadGoogleFonts:E,isFontLoaded:D,getFontFamily:H,refineSuggestion:T,refineFont:R,MOOD_CATEGORIES:M,INTENSITY_CATEGORIES:A};window.TypographyToolkit=r,window.AnimatedText=b}return g.AnimatedText=b,g.FallingAnimation=f,g.FloatingAnimation=v,g.GlitchingAnimation=S,g.INTENSITY_CATEGORIES=A,g.MOOD_CATEGORIES=M,g.SplittingAnimation=F,g.calculateDisintegration=C,g.fontSuggestions=k,g.getFontFamily=H,g.isFontLoaded=D,g.loadGoogleFont=N,g.loadGoogleFonts=E,g.refineFont=R,g.refineSuggestion=T,g.suggestFont=x,g.suggestFonts=y,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"}),g}({});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(d,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(d=typeof globalThis<"u"?globalThis:d||self,p(d.TypographyToolkit={}))})(this,function(d){"use strict";class p{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||20,r=o*.2,c=(n*10*i+r*5)%l-l/2;return{...e,y:c}}}class F{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||4,r=o*.2,a=Math.sin(n*.5*i+r)*l;return{...e,x:a}}}class v{constructor(){this.lastUpdate=0,this.glitchX=0,this.glitchY=0,this.glitchRot=0}update(e,o,n,t={}){const i=t.amplitude||3;return n-this.lastUpdate>.1&&(this.glitchX=(Math.random()-.5)*i,this.glitchY=(Math.random()-.5)*(i*.67),this.glitchRot=(Math.random()-.5)*i,this.lastUpdate=n),{...e,x:this.glitchX,y:this.glitchY,rotation:this.glitchRot}}}class C{update(e,o,n,t={}){const i=t.speed||1,l=t.amplitude||15,r=o*.2,c=-((n*8*i+r*4)%l-l/2);return{...e,y:c}}}function G(s,e){const{x:o,y:n,rotation:t,scale:i,opacity:l}=e;s.style.transform=`translate(${o}px, ${n}px) rotate(${t}deg) scale(${i})`,s.style.opacity=l.toString()}function S(s,e,o,n,t,i){if(!i.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const l=i.radius||80,r=i.strength||1,a=i.behaviors||["fall-away","split-apart","explode"],c=o-s,h=n-e,g=Math.sqrt(c*c+h*h);if(g>=l)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const u=(1-g/l)*r,m=Math.atan2(h,c),B=a[t%a.length];let f;switch(B){case"fall-away":const Y=Math.cos(m)*u*20,$=Math.sin(m)*u*40+u*30;f={x:Y,y:$,rotation:u*15,scale:1,opacity:1-u*.6};break;case"split-apart":const L=t%2===0?1:-1;f={x:L*u*50,y:(Math.random()-.5)*u*10,rotation:u*10*L,scale:1,opacity:1-u*.6};break;case"explode":const O=m+(Math.random()-.5)*.5;f={x:Math.cos(O)*u*40,y:Math.sin(O)*u*40,rotation:u*30,scale:1+u*.4,opacity:1-u*.6};break;default:f={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:f,applied:!0}}class b{constructor(e){var o;if(this.letters=[],this.animationFrame=null,this.mouseX=0,this.mouseY=0,this.mouseMoveHandler=null,this.startTime=Date.now(),this.isDestroyed=!1,this.container=e.container,this.animationTypes=e.animations||["falling","splitting","glitching","floating"],this.cycle=e.cycle!==!1,this.speed=e.speed||1,this.amplitude=e.amplitude||1,this.disintegration=e.disintegration||{enabled:!1},this.style=e.style||{},this.fadeOut=e.fadeOut||0,this.callbacks=e.callbacks,this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",e.containerClass&&(this.textContainer.className=e.containerClass),e.containerStyle&&Object.entries(e.containerStyle).forEach(([n,t])=>{this.textContainer.style.setProperty(n,t)}),e.position){let n=e.position.x,t=e.position.y;if(e.position.constrainToViewport){this.container.getBoundingClientRect();const i=window.innerWidth,l=window.innerHeight,r=e.text.length*20;n!==void 0&&(n=Math.max(0,Math.min(n,i-r))),t!==void 0&&(t=Math.max(0,Math.min(t,l-50)))}n!==void 0&&(this.textContainer.style.left=`${n}px`),t!==void 0&&(this.textContainer.style.top=`${t}px`)}this.createLetters(e.text),this.setupMouseTracking(),this.startAnimation(),(o=this.callbacks)!=null&&o.onCreate&&this.callbacks.onCreate(this.textContainer),this.fadeOut>0&&setTimeout(()=>this.destroy(),this.fadeOut)}createLetters(e){e.toUpperCase().split("").forEach((n,t)=>{if(n===" "){const r=document.createTextNode(" ");this.textContainer.appendChild(r);return}const i=document.createElement("span");i.className="animated-letter",i.textContent=n,i.dataset.index=t.toString(),i.dataset.char=n,this.applyStyle(i),i.style.display="inline-block",i.style.position="relative",i.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(i);const l=i.getBoundingClientRect();this.letters.push({element:i,index:t,char:n,baseX:l.left,baseY:l.top})}),this.container.appendChild(this.textContainer)}applyStyle(e){this.style.fontFamily&&(e.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(e.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(e.style.color=this.style.color),this.style.fontWeight&&(e.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(e.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(e.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(e.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=e=>{this.mouseX=e.clientX,this.mouseY=e.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const e=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((n,t)=>{var h;const i=n.element.getBoundingClientRect(),l=i.left+i.width/2,r=i.top+i.height/2,a=S(l,r,this.mouseX,this.mouseY,t,this.disintegration);let c;if(a.applied)c=a.state,(h=this.callbacks)!=null&&h.onDisintegrate&&this.callbacks.onDisintegrate(t);else{const g=this.getAnimationType(t);c=this.getAnimation(g).update({x:0,y:0,rotation:0,scale:1,opacity:1},t,o,{speed:this.speed,amplitude:this.amplitude*(g==="falling"||g==="floating"?20:4)})}G(n.element,c)}),this.animationFrame=requestAnimationFrame(e)};this.animationFrame=requestAnimationFrame(e)}getAnimationType(e){return this.cycle?this.animationTypes[e%this.animationTypes.length]:this.animationTypes[0]}getAnimation(e){switch(e){case"falling":return new p;case"splitting":return new F;case"glitching":return new v;case"floating":return new C;default:return new p}}destroy(){var e;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),(e=this.callbacks)!=null&&e.onDestroy&&this.callbacks.onDestroy(),this.textContainer.style.transition="opacity 3s ease",this.textContainer.style.opacity="0",setTimeout(()=>{this.textContainer.parentNode&&this.textContainer.parentNode.removeChild(this.textContainer)},3e3))}getElement(){return this.textContainer}}const x=["unsettling","eerie","decayed","weathered","organic","imperfect","uneven","scratchy"],M=["subtle","moderate","intense"],k=[{name:"Hand-drawn Casual",googleFontsName:"Caveat",categories:["hand-drawn","handwriting","casual","sketchy","informal"],description:"Casual handwritten style, friendly and approachable",artistic:!1},{name:"Hand-drawn Playful",googleFontsName:"Finger Paint",categories:["hand-drawn","playful","childlike","casual","sketchy"],description:"Bold hand-drawn style, playful and energetic",artistic:!0},{name:"Hand-drawn Script",googleFontsName:"Dancing Script",categories:["hand-drawn","script","elegant","flowing","cursive"],description:"Elegant flowing script, graceful and organic",artistic:!1},{name:"Gothic Blackletter",googleFontsName:"UnifrakturMaguntia",categories:["gothic","medieval","blackletter","ornate","historical"],description:"Medieval blackletter style, ornate and historical",artistic:!0},{name:"Gothic Horror",googleFontsName:"Creepster",categories:["gothic","horror","creepy","dripping","display","striking","intense"],description:"Horror-style font with dripping effects, very striking",artistic:!0},{name:"Gothic Bold",googleFontsName:"Eater",categories:["gothic","bold","aggressive","display","striking"],description:"Bold aggressive display font, powerful impact",artistic:!0},{name:"Futuristic Digital",googleFontsName:"Orbitron",categories:["futuristic","sci-fi","digital","tech","modern","geometric"],description:"Futuristic geometric font, tech-forward and modern",artistic:!0},{name:"Futuristic Display",googleFontsName:"Bungee",categories:["futuristic","display","bold","condensed","striking"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Futuristic Outline",googleFontsName:"Bungee Shade",categories:["futuristic","outline","display","bold","striking"],description:"Outlined version of Bungee, bold and striking",artistic:!0},{name:"Retro Terminal",googleFontsName:"VT323",categories:["retro","terminal","monospace","pixel","80s","tech"],description:"Retro terminal font, pixelated and nostalgic",artistic:!0},{name:"Retro Pixel",googleFontsName:"Press Start 2P",categories:["retro","pixel","8-bit","arcade","nostalgic","display"],description:"8-bit pixel font, classic arcade style",artistic:!0},{name:"Retro Display",googleFontsName:"Frijole",categories:["retro","playful","rounded","display","casual"],description:"Playful rounded retro font, fun and casual",artistic:!0},{name:"Decorative Ornate",googleFontsName:"Fascinate",categories:["decorative","ornate","display","striking","elaborate"],description:"Highly decorative display font, ornate and elaborate",artistic:!0},{name:"Decorative Outline",googleFontsName:"Fascinate Inline",categories:["decorative","outline","display","ornate","striking"],description:"Outlined decorative font, ornate and striking",artistic:!0},{name:"Decorative Script",googleFontsName:"Fredericka the Great",categories:["decorative","script","ornate","elegant","display"],description:"Elegant decorative script, ornate and sophisticated",artistic:!0},{name:"Horror Dripping",googleFontsName:"Nosifer",categories:["horror","creepy","dripping","blood","striking","display","intense"],description:"Creepy font with blood-dripping effects, very striking",artistic:!0},{name:"Tech Monospace",googleFontsName:"Share Tech Mono",categories:["tech","monospace","terminal","code","modern"],description:"Clean tech monospace font, modern and readable",artistic:!1},{name:"Tech Display",googleFontsName:"Rajdhani",categories:["tech","modern","geometric","sans-serif","futuristic"],description:"Modern geometric tech font, clean and futuristic",artistic:!1},{name:"Organic Flowing",googleFontsName:"Dancing Script",categories:["organic","flowing","natural","script","elegant"],description:"Flowing organic script, natural and elegant",artistic:!1},{name:"Modern Sans",googleFontsName:"Roboto",categories:["modern","clean","sans-serif","readable","professional"],description:"Clean modern sans-serif, professional and readable",artistic:!1},{name:"Modern Serif",googleFontsName:"Playfair Display",categories:["modern","serif","elegant","sophisticated","readable"],description:"Elegant modern serif, sophisticated and readable",artistic:!1},{name:"Bold Condensed",googleFontsName:"Bungee",categories:["bold","condensed","display","striking","impact"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Bold Aggressive",googleFontsName:"Eater",categories:["bold","aggressive","display","striking","powerful"],description:"Bold aggressive display font, powerful and striking",artistic:!0},{name:"Handwritten Thin",googleFontsName:"Amatic SC",categories:["hand-drawn","uneven","organic","unsettling","subtle","scratchy"],description:"Thin hand-drawn letters with subtle irregularity, organic feel",artistic:!0},{name:"Rough Handwriting",googleFontsName:"Rock Salt",categories:["hand-drawn","scratchy","weathered","rough","unsettling","moderate"],description:"Rough, weathered handwriting with natural imperfection",artistic:!0},{name:"Typewriter Degraded",googleFontsName:"Special Elite",categories:["typewriter","decayed","weathered","imperfect","unsettling","moderate"],description:"Degraded typewriter font, vintage with imperfection",artistic:!0},{name:"Casual Handwriting",googleFontsName:"Handlee",categories:["hand-drawn","casual","imperfect","organic","subtle"],description:"Casual handwriting with subtle imperfection",artistic:!1},{name:"Childlike Organic",googleFontsName:"Indie Flower",categories:["hand-drawn","childlike","organic","imperfect","eerie","subtle"],description:"Childlike handwriting, can feel innocent or eerie depending on context",artistic:!1},{name:"Scratchy Personal",googleFontsName:"Shadows Into Light",categories:["hand-drawn","scratchy","personal","unsettling","uneven","moderate"],description:"Scratchy personal handwriting with unsettling quality",artistic:!0},{name:"Hurried Scratchy",googleFontsName:"Reenie Beanie",categories:["hand-drawn","scratchy","hurried","uneven","unsettling","moderate"],description:"Hurried scratchy handwriting with nervous energy",artistic:!0},{name:"Architectural Irregular",googleFontsName:"Architects Daughter",categories:["hand-drawn","imperfect","uneven","organic","subtle"],description:"Hand-drawn with architectural irregularity",artistic:!1},{name:"Informal Unsettling",googleFontsName:"Coming Soon",categories:["hand-drawn","informal","imperfect","unsettling","subtle"],description:"Informal handwriting that feels slightly off",artistic:!1},{name:"Manic Handwriting",googleFontsName:"Gloria Hallelujah",categories:["hand-drawn","playful","manic","uneven","unsettling","moderate"],description:"Playful handwriting that can feel manic or unsettled",artistic:!0},{name:"Quick Imperfect",googleFontsName:"Just Another Hand",categories:["hand-drawn","scratchy","quick","imperfect","uneven","subtle"],description:"Quick scratchy handwriting with natural imperfection",artistic:!1},{name:"Organic Handwriting",googleFontsName:"Kalam",categories:["hand-drawn","organic","natural","flowing","subtle"],description:"Organic natural handwriting with flowing quality",artistic:!1},{name:"Flowing Tension",googleFontsName:"Satisfy",categories:["script","flowing","tension","elegant","unsettling","subtle"],description:"Flowing script with underlying tension",artistic:!0},{name:"Unsettling Elegance",googleFontsName:"Yellowtail",categories:["script","elegant","stylized","unsettling","uneven","moderate"],description:"Stylized elegance with unsettling undertones",artistic:!0},{name:"Typewriter Imperfect",googleFontsName:"Cutive Mono",categories:["typewriter","monospace","imperfect","decayed","vintage","subtle"],description:"Imperfect vintage typewriter with character",artistic:!0}];function I(s){const e=s.toLowerCase().split(/\s+/).filter(t=>t.length>0),o=[],n=[];for(const t of e)t.startsWith("-")&&t.length>1?n.push(t.slice(1)):o.push(t);return{positive:o,negative:n}}function P(s,e){const o=new Set,n=new Map,t=2,i=[];for(const l of s){if(i.length>=e)break;if(o.has(l.font.googleFontsName))continue;const r=l.font.categories[0],a=n.get(r)||0;a>=t||(o.add(l.font.googleFontsName),n.set(r,a+1),i.push(l.font))}return i}function y(s,e){const{positive:o,negative:n}=I(s),t=(e==null?void 0:e.limit)??10,l=k.map(r=>{let a=0;for(const c of o){for(const h of r.categories)(h.includes(c)||c.includes(h))&&(a+=10);r.name.toLowerCase().includes(c)&&(a+=15),r.description.toLowerCase().includes(c)&&(a+=8)}for(const c of n){for(const h of r.categories)(h.includes(c)||c.includes(h))&&(a-=20);r.name.toLowerCase().includes(c)&&(a-=15),r.description.toLowerCase().includes(c)&&(a-=10)}return r.artistic&&(a+=1),{font:r,score:a}}).filter(r=>r.score>0).sort((r,a)=>a.score-r.score);return P(l,t)}function A(s){return y(s)[0]}const w=new Set;function N(s){return new Promise((e,o)=>{const n=s.replace(/\s+/g,"+");if(w.has(n)){e();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${n}"]`)){w.add(n),e();return}const i=document.createElement("link");i.rel="stylesheet",i.href=`https://fonts.googleapis.com/css2?family=${n}:wght@400&display=swap`,i.onload=()=>{w.add(n),e()},i.onerror=()=>{console.warn(`Failed to load Google Font: ${s}`),o(new Error(`Failed to load Google Font: ${s}`))},document.head.appendChild(i)})}function D(s){return Promise.all(s.map(e=>N(e)))}function E(s){const e=s.replace(/\s+/g,"+");return w.has(e)}function H(s,e="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great","Amatic SC","Handlee","Indie Flower","Shadows Into Light","Rock Salt","Reenie Beanie","Architects Daughter","Coming Soon","Gloria Hallelujah","Just Another Hand","Kalam","Satisfy","Yellowtail"],n=["VT323","Press Start 2P","Share Tech Mono","Special Elite","Cutive Mono"];let t=e;return o.includes(s)?t="cursive":n.includes(s)&&(t="monospace"),`'${s}', ${t}`}function T(s,e){const o=s.toLowerCase(),n=e.rejectedFont.toLowerCase(),t=e.negativeAspects.map(a=>a.toLowerCase()),i=e.positiveAspects.map(a=>a.toLowerCase());return y(s).filter(a=>a.googleFontsName.toLowerCase()!==n&&a.name.toLowerCase()!==n).map(a=>{let c=0;for(const g of a.categories)o.includes(g)&&(c+=5);for(const g of i)(a.categories.some(m=>m.includes(g)||g.includes(m))||a.name.toLowerCase().includes(g)||a.description.toLowerCase().includes(g))&&(c+=15);for(const g of t)(a.categories.some(m=>m.includes(g)||g.includes(m))||a.name.toLowerCase().includes(g)||a.description.toLowerCase().includes(g))&&(c-=20);const h=i.some(g=>g.includes("striking")||g.includes("artistic")||g.includes("unique"));return h&&a.artistic&&(c+=10),h&&!a.artistic&&(c-=5),{font:a,score:c}}).filter(a=>a.score>0).sort((a,c)=>c.score-a.score).map(a=>a.font)}function R(s,e){return T(s,e)[0]}if(typeof window<"u"){const s={AnimatedText:b,FallingAnimation:p,SplittingAnimation:F,GlitchingAnimation:v,FloatingAnimation:C,calculateDisintegration:S,fontSuggestions:k,suggestFonts:y,suggestFont:A,loadGoogleFont:N,loadGoogleFonts:D,isFontLoaded:E,getFontFamily:H,refineSuggestion:T,refineFont:R,MOOD_CATEGORIES:x,INTENSITY_CATEGORIES:M};window.TypographyToolkit=s,window.AnimatedText=b}d.AnimatedText=b,d.FallingAnimation=p,d.FloatingAnimation=C,d.GlitchingAnimation=v,d.INTENSITY_CATEGORIES=M,d.MOOD_CATEGORIES=x,d.SplittingAnimation=F,d.calculateDisintegration=S,d.fontSuggestions=k,d.getFontFamily=H,d.isFontLoaded=E,d.loadGoogleFont=N,d.loadGoogleFonts=D,d.refineFont=R,d.refineSuggestion=T,d.suggestFont=A,d.suggestFonts=y,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(d,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(d=typeof globalThis<"u"?globalThis:d||self,p(d.TypographyToolkit={}))})(this,function(d){"use strict";class p{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||20,s=o*.2,c=(a*10*i+s*5)%l-l/2;return{...e,y:c}}}class F{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||4,s=o*.2,n=Math.sin(a*.5*i+s)*l;return{...e,x:n}}}class S{constructor(){this.letterStates=new Map}update(e,o,a,t={}){const i=t.amplitude||3,l=t.speed||1;let s=this.letterStates.get(o);s||(s={lastUpdate:a,glitchX:0,glitchY:0,glitchRot:0},this.letterStates.set(o,s));const n=.1/l;return a-s.lastUpdate>n&&(s.glitchX=(Math.random()-.5)*i,s.glitchY=(Math.random()-.5)*(i*.67),s.glitchRot=(Math.random()-.5)*i,s.lastUpdate=a),{...e,x:s.glitchX,y:s.glitchY,rotation:s.glitchRot}}}class v{update(e,o,a,t={}){const i=t.speed||1,l=t.amplitude||15,s=o*.2,c=-((a*8*i+s*4)%l-l/2);return{...e,y:c}}}function O(r,e){const{x:o,y:a,rotation:t,scale:i,opacity:l}=e;r.style.transform=`translate(${o}px, ${a}px) rotate(${t}deg) scale(${i})`,r.style.opacity=l.toString()}function C(r,e,o,a,t,i){if(!i.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const l=i.radius||80,s=i.strength||1,n=i.behaviors||["fall-away","split-apart","explode"],c=o-r,h=a-e,g=Math.sqrt(c*c+h*h);if(g>=l)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const u=(1-g/l)*s,m=Math.atan2(h,c),B=n[t%n.length];let f;switch(B){case"fall-away":const Y=Math.cos(m)*u*20,$=Math.sin(m)*u*40+u*30;f={x:Y,y:$,rotation:u*15,scale:1,opacity:1-u*.6};break;case"split-apart":const I=t%2===0?1:-1;f={x:I*u*50,y:(Math.random()-.5)*u*10,rotation:u*10*I,scale:1,opacity:1-u*.6};break;case"explode":const L=m+(Math.random()-.5)*.5;f={x:Math.cos(L)*u*40,y:Math.sin(L)*u*40,rotation:u*30,scale:1+u*.4,opacity:1-u*.6};break;default:f={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:f,applied:!0}}class b{constructor(e){var o;if(this.letters=[],this.animationSpeedMultiplier=1,this.animationFrame=null,this.mouseX=0,this.mouseY=0,this.mouseMoveHandler=null,this.startTime=Date.now(),this.isDestroyed=!1,this.animationInstances=new Map,this.container=e.container,this.animationTypes=e.animations||["falling","splitting","glitching","floating"],this.cycle=e.cycle!==!1,this.speed=e.speed||1,this.amplitude=e.amplitude||1,this.animationEasing=e.animationEasing||"linear",this.disintegration=e.disintegration||{enabled:!1},this.style=e.style||{},this.fadeOut=e.fadeOut||0,this.callbacks=e.callbacks,e.animationSpeed!==void 0&&(this.animationSpeedMultiplier=this.parseAnimationSpeed(e.animationSpeed)),this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",e.containerClass&&(this.textContainer.className=e.containerClass),e.containerStyle&&Object.entries(e.containerStyle).forEach(([a,t])=>{this.textContainer.style.setProperty(a,t)}),e.position){let a=e.position.x,t=e.position.y;if(e.position.constrainToViewport){this.container.getBoundingClientRect();const i=window.innerWidth,l=window.innerHeight,s=e.text.length*20;a!==void 0&&(a=Math.max(0,Math.min(a,i-s))),t!==void 0&&(t=Math.max(0,Math.min(t,l-50)))}a!==void 0&&(this.textContainer.style.left=`${a}px`),t!==void 0&&(this.textContainer.style.top=`${t}px`)}this.createLetters(e.text),this.setupMouseTracking(),this.startAnimation(),(o=this.callbacks)!=null&&o.onCreate&&this.callbacks.onCreate(this.textContainer),this.fadeOut>0&&setTimeout(()=>this.destroy(),this.fadeOut)}createLetters(e){e.toUpperCase().split("").forEach((a,t)=>{if(a===" "){const s=document.createTextNode(" ");this.textContainer.appendChild(s);return}const i=document.createElement("span");i.className="animated-letter",i.textContent=a,i.dataset.index=t.toString(),i.dataset.char=a,this.applyStyle(i),i.style.display="inline-block",i.style.position="relative",i.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(i);const l=i.getBoundingClientRect();this.letters.push({element:i,index:t,char:a,baseX:l.left,baseY:l.top})}),this.container.appendChild(this.textContainer)}applyStyle(e){this.style.fontFamily&&(e.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(e.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(e.style.color=this.style.color),this.style.fontWeight&&(e.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(e.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(e.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(e.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=e=>{this.mouseX=e.clientX,this.mouseY=e.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const e=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((a,t)=>{var h;const i=a.element.getBoundingClientRect(),l=i.left+i.width/2,s=i.top+i.height/2,n=C(l,s,this.mouseX,this.mouseY,t,this.disintegration);let c;if(n.applied)c=n.state,(h=this.callbacks)!=null&&h.onDisintegrate&&this.callbacks.onDisintegrate(t);else{const g=this.getAnimationType(t);c=this.getAnimation(g).update({x:0,y:0,rotation:0,scale:1,opacity:1},t,o,{speed:this.speed*this.animationSpeedMultiplier,amplitude:this.amplitude*(g==="falling"||g==="floating"?20:4)})}O(a.element,c)}),this.animationFrame=requestAnimationFrame(e)};this.animationFrame=requestAnimationFrame(e)}getAnimationType(e){return this.cycle?this.animationTypes[e%this.animationTypes.length]:this.animationTypes[0]}getAnimation(e){if(this.animationInstances.has(e))return this.animationInstances.get(e);let o;switch(e){case"falling":o=new p;break;case"splitting":o=new F;break;case"glitching":o=new S;break;case"floating":o=new v;break;default:o=new p}return this.animationInstances.set(e,o),o}parseAnimationSpeed(e){if(typeof e=="number")return e;switch(e){case"slow":return .5;case"normal":return 1;case"fast":return 2;default:return 1}}getAnimationSpeed(){return this.animationSpeedMultiplier}setAnimationSpeed(e){this.animationSpeedMultiplier=this.parseAnimationSpeed(e)}getAnimationEasing(){return this.animationEasing}setAnimationEasing(e){this.animationEasing=e}destroy(){var e;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),this.animationInstances.clear(),(e=this.callbacks)!=null&&e.onDestroy&&this.callbacks.onDestroy(),this.textContainer.style.transition="opacity 3s ease",this.textContainer.style.opacity="0",setTimeout(()=>{this.textContainer.parentNode&&this.textContainer.parentNode.removeChild(this.textContainer)},3e3))}getElement(){return this.textContainer}}const x=["unsettling","eerie","decayed","weathered","organic","imperfect","uneven","scratchy"],M=["subtle","moderate","intense"],k=[{name:"Hand-drawn Casual",googleFontsName:"Caveat",categories:["hand-drawn","handwriting","casual","sketchy","informal"],description:"Casual handwritten style, friendly and approachable",artistic:!1},{name:"Hand-drawn Playful",googleFontsName:"Finger Paint",categories:["hand-drawn","playful","childlike","casual","sketchy"],description:"Bold hand-drawn style, playful and energetic",artistic:!0},{name:"Hand-drawn Script",googleFontsName:"Dancing Script",categories:["hand-drawn","script","elegant","flowing","cursive"],description:"Elegant flowing script, graceful and organic",artistic:!1},{name:"Gothic Blackletter",googleFontsName:"UnifrakturMaguntia",categories:["gothic","medieval","blackletter","ornate","historical"],description:"Medieval blackletter style, ornate and historical",artistic:!0},{name:"Gothic Horror",googleFontsName:"Creepster",categories:["gothic","horror","creepy","dripping","display","striking","intense"],description:"Horror-style font with dripping effects, very striking",artistic:!0},{name:"Gothic Bold",googleFontsName:"Eater",categories:["gothic","bold","aggressive","display","striking"],description:"Bold aggressive display font, powerful impact",artistic:!0},{name:"Futuristic Digital",googleFontsName:"Orbitron",categories:["futuristic","sci-fi","digital","tech","modern","geometric"],description:"Futuristic geometric font, tech-forward and modern",artistic:!0},{name:"Futuristic Display",googleFontsName:"Bungee",categories:["futuristic","display","bold","condensed","striking"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Futuristic Outline",googleFontsName:"Bungee Shade",categories:["futuristic","outline","display","bold","striking"],description:"Outlined version of Bungee, bold and striking",artistic:!0},{name:"Retro Terminal",googleFontsName:"VT323",categories:["retro","terminal","monospace","pixel","80s","tech"],description:"Retro terminal font, pixelated and nostalgic",artistic:!0},{name:"Retro Pixel",googleFontsName:"Press Start 2P",categories:["retro","pixel","8-bit","arcade","nostalgic","display"],description:"8-bit pixel font, classic arcade style",artistic:!0},{name:"Retro Display",googleFontsName:"Frijole",categories:["retro","playful","rounded","display","casual"],description:"Playful rounded retro font, fun and casual",artistic:!0},{name:"Decorative Ornate",googleFontsName:"Fascinate",categories:["decorative","ornate","display","striking","elaborate"],description:"Highly decorative display font, ornate and elaborate",artistic:!0},{name:"Decorative Outline",googleFontsName:"Fascinate Inline",categories:["decorative","outline","display","ornate","striking"],description:"Outlined decorative font, ornate and striking",artistic:!0},{name:"Decorative Script",googleFontsName:"Fredericka the Great",categories:["decorative","script","ornate","elegant","display"],description:"Elegant decorative script, ornate and sophisticated",artistic:!0},{name:"Horror Dripping",googleFontsName:"Nosifer",categories:["horror","creepy","dripping","blood","striking","display","intense"],description:"Creepy font with blood-dripping effects, very striking",artistic:!0},{name:"Tech Monospace",googleFontsName:"Share Tech Mono",categories:["tech","monospace","terminal","code","modern"],description:"Clean tech monospace font, modern and readable",artistic:!1},{name:"Tech Display",googleFontsName:"Rajdhani",categories:["tech","modern","geometric","sans-serif","futuristic"],description:"Modern geometric tech font, clean and futuristic",artistic:!1},{name:"Organic Flowing",googleFontsName:"Dancing Script",categories:["organic","flowing","natural","script","elegant"],description:"Flowing organic script, natural and elegant",artistic:!1},{name:"Modern Sans",googleFontsName:"Roboto",categories:["modern","clean","sans-serif","readable","professional"],description:"Clean modern sans-serif, professional and readable",artistic:!1},{name:"Modern Serif",googleFontsName:"Playfair Display",categories:["modern","serif","elegant","sophisticated","readable"],description:"Elegant modern serif, sophisticated and readable",artistic:!1},{name:"Bold Condensed",googleFontsName:"Bungee",categories:["bold","condensed","display","striking","impact"],description:"Bold condensed display font, high impact",artistic:!0},{name:"Bold Aggressive",googleFontsName:"Eater",categories:["bold","aggressive","display","striking","powerful"],description:"Bold aggressive display font, powerful and striking",artistic:!0},{name:"Handwritten Thin",googleFontsName:"Amatic SC",categories:["hand-drawn","uneven","organic","unsettling","subtle","scratchy"],description:"Thin hand-drawn letters with subtle irregularity, organic feel",artistic:!0},{name:"Rough Handwriting",googleFontsName:"Rock Salt",categories:["hand-drawn","scratchy","weathered","rough","unsettling","moderate"],description:"Rough, weathered handwriting with natural imperfection",artistic:!0},{name:"Typewriter Degraded",googleFontsName:"Special Elite",categories:["typewriter","decayed","weathered","imperfect","unsettling","moderate"],description:"Degraded typewriter font, vintage with imperfection",artistic:!0},{name:"Casual Handwriting",googleFontsName:"Handlee",categories:["hand-drawn","casual","imperfect","organic","subtle"],description:"Casual handwriting with subtle imperfection",artistic:!1},{name:"Childlike Organic",googleFontsName:"Indie Flower",categories:["hand-drawn","childlike","organic","imperfect","eerie","subtle"],description:"Childlike handwriting, can feel innocent or eerie depending on context",artistic:!1},{name:"Scratchy Personal",googleFontsName:"Shadows Into Light",categories:["hand-drawn","scratchy","personal","unsettling","uneven","moderate"],description:"Scratchy personal handwriting with unsettling quality",artistic:!0},{name:"Hurried Scratchy",googleFontsName:"Reenie Beanie",categories:["hand-drawn","scratchy","hurried","uneven","unsettling","moderate"],description:"Hurried scratchy handwriting with nervous energy",artistic:!0},{name:"Architectural Irregular",googleFontsName:"Architects Daughter",categories:["hand-drawn","imperfect","uneven","organic","subtle"],description:"Hand-drawn with architectural irregularity",artistic:!1},{name:"Informal Unsettling",googleFontsName:"Coming Soon",categories:["hand-drawn","informal","imperfect","unsettling","subtle"],description:"Informal handwriting that feels slightly off",artistic:!1},{name:"Manic Handwriting",googleFontsName:"Gloria Hallelujah",categories:["hand-drawn","playful","manic","uneven","unsettling","moderate"],description:"Playful handwriting that can feel manic or unsettled",artistic:!0},{name:"Quick Imperfect",googleFontsName:"Just Another Hand",categories:["hand-drawn","scratchy","quick","imperfect","uneven","subtle"],description:"Quick scratchy handwriting with natural imperfection",artistic:!1},{name:"Organic Handwriting",googleFontsName:"Kalam",categories:["hand-drawn","organic","natural","flowing","subtle"],description:"Organic natural handwriting with flowing quality",artistic:!1},{name:"Flowing Tension",googleFontsName:"Satisfy",categories:["script","flowing","tension","elegant","unsettling","subtle"],description:"Flowing script with underlying tension",artistic:!0},{name:"Unsettling Elegance",googleFontsName:"Yellowtail",categories:["script","elegant","stylized","unsettling","uneven","moderate"],description:"Stylized elegance with unsettling undertones",artistic:!0},{name:"Typewriter Imperfect",googleFontsName:"Cutive Mono",categories:["typewriter","monospace","imperfect","decayed","vintage","subtle"],description:"Imperfect vintage typewriter with character",artistic:!0}];function G(r){const e=r.toLowerCase().split(/\s+/).filter(t=>t.length>0),o=[],a=[];for(const t of e)t.startsWith("-")&&t.length>1?a.push(t.slice(1)):o.push(t);return{positive:o,negative:a}}function P(r,e){const o=new Set,a=new Map,t=2,i=[];for(const l of r){if(i.length>=e)break;if(o.has(l.font.googleFontsName))continue;const s=l.font.categories[0],n=a.get(s)||0;n>=t||(o.add(l.font.googleFontsName),a.set(s,n+1),i.push(l.font))}return i}function y(r,e){const{positive:o,negative:a}=G(r),t=(e==null?void 0:e.limit)??10,l=k.map(s=>{let n=0;for(const c of o){for(const h of s.categories)(h.includes(c)||c.includes(h))&&(n+=10);s.name.toLowerCase().includes(c)&&(n+=15),s.description.toLowerCase().includes(c)&&(n+=8)}for(const c of a){for(const h of s.categories)(h.includes(c)||c.includes(h))&&(n-=20);s.name.toLowerCase().includes(c)&&(n-=15),s.description.toLowerCase().includes(c)&&(n-=10)}return s.artistic&&(n+=1),{font:s,score:n}}).filter(s=>s.score>0).sort((s,n)=>n.score-s.score);return P(l,t)}function A(r){return y(r)[0]}const w=new Set;function N(r){return new Promise((e,o)=>{const a=r.replace(/\s+/g,"+");if(w.has(a)){e();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${a}"]`)){w.add(a),e();return}const i=document.createElement("link");i.rel="stylesheet",i.href=`https://fonts.googleapis.com/css2?family=${a}:wght@400&display=swap`,i.onload=()=>{w.add(a),e()},i.onerror=()=>{console.warn(`Failed to load Google Font: ${r}`),o(new Error(`Failed to load Google Font: ${r}`))},document.head.appendChild(i)})}function E(r){return Promise.all(r.map(e=>N(e)))}function D(r){const e=r.replace(/\s+/g,"+");return w.has(e)}function H(r,e="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great","Amatic SC","Handlee","Indie Flower","Shadows Into Light","Rock Salt","Reenie Beanie","Architects Daughter","Coming Soon","Gloria Hallelujah","Just Another Hand","Kalam","Satisfy","Yellowtail"],a=["VT323","Press Start 2P","Share Tech Mono","Special Elite","Cutive Mono"];let t=e;return o.includes(r)?t="cursive":a.includes(r)&&(t="monospace"),`'${r}', ${t}`}function T(r,e){const o=r.toLowerCase(),a=e.rejectedFont.toLowerCase(),t=e.negativeAspects.map(n=>n.toLowerCase()),i=e.positiveAspects.map(n=>n.toLowerCase());return y(r).filter(n=>n.googleFontsName.toLowerCase()!==a&&n.name.toLowerCase()!==a).map(n=>{let c=0;for(const g of n.categories)o.includes(g)&&(c+=5);for(const g of i)(n.categories.some(m=>m.includes(g)||g.includes(m))||n.name.toLowerCase().includes(g)||n.description.toLowerCase().includes(g))&&(c+=15);for(const g of t)(n.categories.some(m=>m.includes(g)||g.includes(m))||n.name.toLowerCase().includes(g)||n.description.toLowerCase().includes(g))&&(c-=20);const h=i.some(g=>g.includes("striking")||g.includes("artistic")||g.includes("unique"));return h&&n.artistic&&(c+=10),h&&!n.artistic&&(c-=5),{font:n,score:c}}).filter(n=>n.score>0).sort((n,c)=>c.score-n.score).map(n=>n.font)}function R(r,e){return T(r,e)[0]}if(typeof window<"u"){const r={AnimatedText:b,FallingAnimation:p,SplittingAnimation:F,GlitchingAnimation:S,FloatingAnimation:v,calculateDisintegration:C,fontSuggestions:k,suggestFonts:y,suggestFont:A,loadGoogleFont:N,loadGoogleFonts:E,isFontLoaded:D,getFontFamily:H,refineSuggestion:T,refineFont:R,MOOD_CATEGORIES:x,INTENSITY_CATEGORIES:M};window.TypographyToolkit=r,window.AnimatedText=b}d.AnimatedText=b,d.FallingAnimation=p,d.FloatingAnimation=v,d.GlitchingAnimation=S,d.INTENSITY_CATEGORIES=M,d.MOOD_CATEGORIES=x,d.SplittingAnimation=F,d.calculateDisintegration=C,d.fontSuggestions=k,d.getFontFamily=H,d.isFontLoaded=D,d.loadGoogleFont=N,d.loadGoogleFonts=E,d.refineFont=R,d.refineSuggestion=T,d.suggestFont=A,d.suggestFonts=y,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typography-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Letter-by-letter text animations with proximity-based disintegration effects and Google Fonts selection",
|
|
5
5
|
"main": "dist/typography-toolkit.umd.js",
|
|
6
6
|
"module": "dist/typography-toolkit.esm.js",
|