typography-toolkit 1.2.0 → 1.2.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,191 +1,191 @@
|
|
|
1
1
|
class f {
|
|
2
|
-
update(
|
|
3
|
-
const
|
|
2
|
+
update(e, o, n, t = {}) {
|
|
3
|
+
const i = t.speed || 1, l = t.amplitude || 20, r = o * 0.2, c = (n * 10 * i + r * 5) % l - l / 2;
|
|
4
4
|
return {
|
|
5
|
-
...
|
|
6
|
-
y:
|
|
5
|
+
...e,
|
|
6
|
+
y: c
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
class C {
|
|
11
|
-
update(
|
|
12
|
-
const
|
|
11
|
+
update(e, o, n, t = {}) {
|
|
12
|
+
const i = t.speed || 1, l = t.amplitude || 4, r = o * 0.2, a = Math.sin(n * 0.5 * i + r) * l;
|
|
13
13
|
return {
|
|
14
|
-
...
|
|
14
|
+
...e,
|
|
15
15
|
x: a
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
class
|
|
19
|
+
class x {
|
|
20
20
|
constructor() {
|
|
21
21
|
this.lastUpdate = 0, this.glitchX = 0, this.glitchY = 0, this.glitchRot = 0;
|
|
22
22
|
}
|
|
23
|
-
update(
|
|
24
|
-
const
|
|
25
|
-
return
|
|
26
|
-
...
|
|
23
|
+
update(e, o, n, t = {}) {
|
|
24
|
+
const i = t.amplitude || 3;
|
|
25
|
+
return n - this.lastUpdate > 0.1 && (this.glitchX = (Math.random() - 0.5) * i, this.glitchY = (Math.random() - 0.5) * (i * 0.67), this.glitchRot = (Math.random() - 0.5) * i, this.lastUpdate = n), {
|
|
26
|
+
...e,
|
|
27
27
|
x: this.glitchX,
|
|
28
28
|
y: this.glitchY,
|
|
29
29
|
rotation: this.glitchRot
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
class
|
|
34
|
-
update(
|
|
35
|
-
const
|
|
33
|
+
class S {
|
|
34
|
+
update(e, o, n, t = {}) {
|
|
35
|
+
const i = t.speed || 1, l = t.amplitude || 15, r = o * 0.2, c = -((n * 8 * i + r * 4) % l - l / 2);
|
|
36
36
|
return {
|
|
37
|
-
...
|
|
38
|
-
y:
|
|
37
|
+
...e,
|
|
38
|
+
y: c
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
const { x: o, y:
|
|
44
|
-
|
|
42
|
+
function H(s, e) {
|
|
43
|
+
const { x: o, y: n, rotation: t, scale: i, opacity: l } = e;
|
|
44
|
+
s.style.transform = `translate(${o}px, ${n}px) rotate(${t}deg) scale(${i})`, s.style.opacity = l.toString();
|
|
45
45
|
}
|
|
46
|
-
function b(
|
|
47
|
-
if (!
|
|
46
|
+
function b(s, e, o, n, t, i) {
|
|
47
|
+
if (!i.enabled)
|
|
48
48
|
return {
|
|
49
49
|
state: { x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 },
|
|
50
50
|
applied: !1
|
|
51
51
|
};
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
52
|
+
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);
|
|
53
|
+
if (d >= l)
|
|
54
54
|
return {
|
|
55
55
|
state: { x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 },
|
|
56
56
|
applied: !1
|
|
57
57
|
};
|
|
58
|
-
const
|
|
59
|
-
let
|
|
60
|
-
switch (
|
|
58
|
+
const g = (1 - d / l) * r, u = Math.atan2(h, c), M = a[t % a.length];
|
|
59
|
+
let m;
|
|
60
|
+
switch (M) {
|
|
61
61
|
case "fall-away":
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
x:
|
|
65
|
-
y:
|
|
66
|
-
rotation:
|
|
62
|
+
const A = Math.cos(u) * g * 20, D = Math.sin(u) * g * 40 + g * 30;
|
|
63
|
+
m = {
|
|
64
|
+
x: A,
|
|
65
|
+
y: D,
|
|
66
|
+
rotation: g * 15,
|
|
67
67
|
scale: 1,
|
|
68
|
-
opacity: 1 -
|
|
68
|
+
opacity: 1 - g * 0.6
|
|
69
69
|
};
|
|
70
70
|
break;
|
|
71
71
|
case "split-apart":
|
|
72
|
-
const w =
|
|
73
|
-
|
|
74
|
-
x: w *
|
|
75
|
-
y: (Math.random() - 0.5) *
|
|
76
|
-
rotation:
|
|
72
|
+
const w = t % 2 === 0 ? 1 : -1;
|
|
73
|
+
m = {
|
|
74
|
+
x: w * g * 50,
|
|
75
|
+
y: (Math.random() - 0.5) * g * 10,
|
|
76
|
+
rotation: g * 10 * w,
|
|
77
77
|
scale: 1,
|
|
78
|
-
opacity: 1 -
|
|
78
|
+
opacity: 1 - g * 0.6
|
|
79
79
|
};
|
|
80
80
|
break;
|
|
81
81
|
case "explode":
|
|
82
|
-
const F =
|
|
83
|
-
|
|
84
|
-
x: Math.cos(F) *
|
|
85
|
-
y: Math.sin(F) *
|
|
86
|
-
rotation:
|
|
87
|
-
scale: 1 +
|
|
88
|
-
opacity: 1 -
|
|
82
|
+
const F = u + (Math.random() - 0.5) * 0.5;
|
|
83
|
+
m = {
|
|
84
|
+
x: Math.cos(F) * g * 40,
|
|
85
|
+
y: Math.sin(F) * g * 40,
|
|
86
|
+
rotation: g * 30,
|
|
87
|
+
scale: 1 + g * 0.4,
|
|
88
|
+
opacity: 1 - g * 0.6
|
|
89
89
|
};
|
|
90
90
|
break;
|
|
91
91
|
default:
|
|
92
|
-
|
|
92
|
+
m = { x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 };
|
|
93
93
|
}
|
|
94
94
|
return {
|
|
95
|
-
state:
|
|
95
|
+
state: m,
|
|
96
96
|
applied: !0
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
|
-
class
|
|
100
|
-
constructor(
|
|
99
|
+
class v {
|
|
100
|
+
constructor(e) {
|
|
101
101
|
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 =
|
|
103
|
-
this.textContainer.style.setProperty(
|
|
104
|
-
}),
|
|
105
|
-
let
|
|
106
|
-
if (
|
|
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(([n, t]) => {
|
|
103
|
+
this.textContainer.style.setProperty(n, t);
|
|
104
|
+
}), e.position) {
|
|
105
|
+
let n = e.position.x, t = e.position.y;
|
|
106
|
+
if (e.position.constrainToViewport) {
|
|
107
107
|
this.container.getBoundingClientRect();
|
|
108
|
-
const
|
|
109
|
-
|
|
108
|
+
const i = window.innerWidth, l = window.innerHeight, r = e.text.length * 20;
|
|
109
|
+
n !== void 0 && (n = Math.max(0, Math.min(n, i - r))), t !== void 0 && (t = Math.max(0, Math.min(t, l - 50)));
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
n !== void 0 && (this.textContainer.style.left = `${n}px`), t !== void 0 && (this.textContainer.style.top = `${t}px`);
|
|
112
112
|
}
|
|
113
|
-
this.createLetters(
|
|
113
|
+
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
114
|
}
|
|
115
|
-
createLetters(
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
const
|
|
119
|
-
this.textContainer.appendChild(
|
|
115
|
+
createLetters(e) {
|
|
116
|
+
e.toUpperCase().split("").forEach((n, t) => {
|
|
117
|
+
if (n === " ") {
|
|
118
|
+
const r = document.createTextNode(" ");
|
|
119
|
+
this.textContainer.appendChild(r);
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
const
|
|
122
|
+
const i = document.createElement("span");
|
|
123
|
+
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);
|
|
124
|
+
const l = i.getBoundingClientRect();
|
|
125
125
|
this.letters.push({
|
|
126
|
-
element:
|
|
127
|
-
index:
|
|
128
|
-
char:
|
|
129
|
-
baseX:
|
|
130
|
-
baseY:
|
|
126
|
+
element: i,
|
|
127
|
+
index: t,
|
|
128
|
+
char: n,
|
|
129
|
+
baseX: l.left,
|
|
130
|
+
baseY: l.top
|
|
131
131
|
});
|
|
132
132
|
}), this.container.appendChild(this.textContainer);
|
|
133
133
|
}
|
|
134
|
-
applyStyle(
|
|
135
|
-
this.style.fontFamily && (
|
|
134
|
+
applyStyle(e) {
|
|
135
|
+
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);
|
|
136
136
|
}
|
|
137
137
|
setupMouseTracking() {
|
|
138
|
-
this.disintegration.enabled && (this.mouseMoveHandler = (
|
|
139
|
-
this.mouseX =
|
|
138
|
+
this.disintegration.enabled && (this.mouseMoveHandler = (e) => {
|
|
139
|
+
this.mouseX = e.clientX, this.mouseY = e.clientY;
|
|
140
140
|
}, document.addEventListener("mousemove", this.mouseMoveHandler));
|
|
141
141
|
}
|
|
142
142
|
startAnimation() {
|
|
143
|
-
const
|
|
143
|
+
const e = () => {
|
|
144
144
|
if (this.isDestroyed) return;
|
|
145
145
|
const o = (Date.now() - this.startTime) * 1e-3;
|
|
146
|
-
this.letters.forEach((
|
|
146
|
+
this.letters.forEach((n, t) => {
|
|
147
147
|
var h;
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
const i = n.element.getBoundingClientRect(), l = i.left + i.width / 2, r = i.top + i.height / 2, a = b(
|
|
149
|
+
l,
|
|
150
|
+
r,
|
|
151
151
|
this.mouseX,
|
|
152
152
|
this.mouseY,
|
|
153
|
-
|
|
153
|
+
t,
|
|
154
154
|
this.disintegration
|
|
155
155
|
);
|
|
156
|
-
let
|
|
156
|
+
let c;
|
|
157
157
|
if (a.applied)
|
|
158
|
-
|
|
158
|
+
c = a.state, (h = this.callbacks) != null && h.onDisintegrate && this.callbacks.onDisintegrate(t);
|
|
159
159
|
else {
|
|
160
|
-
const
|
|
161
|
-
|
|
160
|
+
const d = this.getAnimationType(t);
|
|
161
|
+
c = this.getAnimation(d).update(
|
|
162
162
|
{ x: 0, y: 0, rotation: 0, scale: 1, opacity: 1 },
|
|
163
|
-
|
|
163
|
+
t,
|
|
164
164
|
o,
|
|
165
165
|
{
|
|
166
166
|
speed: this.speed,
|
|
167
|
-
amplitude: this.amplitude * (
|
|
167
|
+
amplitude: this.amplitude * (d === "falling" || d === "floating" ? 20 : 4)
|
|
168
168
|
}
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
|
-
|
|
172
|
-
}), this.animationFrame = requestAnimationFrame(
|
|
171
|
+
H(n.element, c);
|
|
172
|
+
}), this.animationFrame = requestAnimationFrame(e);
|
|
173
173
|
};
|
|
174
|
-
this.animationFrame = requestAnimationFrame(
|
|
174
|
+
this.animationFrame = requestAnimationFrame(e);
|
|
175
175
|
}
|
|
176
|
-
getAnimationType(
|
|
177
|
-
return this.cycle ? this.animationTypes[
|
|
176
|
+
getAnimationType(e) {
|
|
177
|
+
return this.cycle ? this.animationTypes[e % this.animationTypes.length] : this.animationTypes[0];
|
|
178
178
|
}
|
|
179
|
-
getAnimation(
|
|
180
|
-
switch (
|
|
179
|
+
getAnimation(e) {
|
|
180
|
+
switch (e) {
|
|
181
181
|
case "falling":
|
|
182
182
|
return new f();
|
|
183
183
|
case "splitting":
|
|
184
184
|
return new C();
|
|
185
185
|
case "glitching":
|
|
186
|
-
return new
|
|
186
|
+
return new x();
|
|
187
187
|
case "floating":
|
|
188
|
-
return new
|
|
188
|
+
return new S();
|
|
189
189
|
default:
|
|
190
190
|
return new f();
|
|
191
191
|
}
|
|
@@ -194,8 +194,8 @@ class x {
|
|
|
194
194
|
* Destroy the animated text instance
|
|
195
195
|
*/
|
|
196
196
|
destroy() {
|
|
197
|
-
var
|
|
198
|
-
this.isDestroyed || (this.isDestroyed = !0, this.animationFrame !== null && cancelAnimationFrame(this.animationFrame), this.mouseMoveHandler && document.removeEventListener("mousemove", this.mouseMoveHandler), (
|
|
197
|
+
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(() => {
|
|
199
199
|
this.textContainer.parentNode && this.textContainer.parentNode.removeChild(this.textContainer);
|
|
200
200
|
}, 3e3));
|
|
201
201
|
}
|
|
@@ -206,7 +206,16 @@ class x {
|
|
|
206
206
|
return this.textContainer;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
-
const
|
|
209
|
+
const E = [
|
|
210
|
+
"unsettling",
|
|
211
|
+
"eerie",
|
|
212
|
+
"decayed",
|
|
213
|
+
"weathered",
|
|
214
|
+
"organic",
|
|
215
|
+
"imperfect",
|
|
216
|
+
"uneven",
|
|
217
|
+
"scratchy"
|
|
218
|
+
], R = ["subtle", "moderate", "intense"], k = [
|
|
210
219
|
// Hand-drawn / Handwriting
|
|
211
220
|
{
|
|
212
221
|
name: "Hand-drawn Casual",
|
|
@@ -240,7 +249,7 @@ const S = [
|
|
|
240
249
|
{
|
|
241
250
|
name: "Gothic Horror",
|
|
242
251
|
googleFontsName: "Creepster",
|
|
243
|
-
categories: ["gothic", "horror", "creepy", "dripping", "display", "striking"],
|
|
252
|
+
categories: ["gothic", "horror", "creepy", "dripping", "display", "striking", "intense"],
|
|
244
253
|
description: "Horror-style font with dripping effects, very striking",
|
|
245
254
|
artistic: !0
|
|
246
255
|
},
|
|
@@ -321,7 +330,7 @@ const S = [
|
|
|
321
330
|
{
|
|
322
331
|
name: "Horror Dripping",
|
|
323
332
|
googleFontsName: "Nosifer",
|
|
324
|
-
categories: ["horror", "creepy", "dripping", "blood", "striking", "display"],
|
|
333
|
+
categories: ["horror", "creepy", "dripping", "blood", "striking", "display", "intense"],
|
|
325
334
|
description: "Creepy font with blood-dripping effects, very striking",
|
|
326
335
|
artistic: !0
|
|
327
336
|
},
|
|
@@ -377,110 +386,271 @@ const S = [
|
|
|
377
386
|
categories: ["bold", "aggressive", "display", "striking", "powerful"],
|
|
378
387
|
description: "Bold aggressive display font, powerful and striking",
|
|
379
388
|
artistic: !0
|
|
389
|
+
},
|
|
390
|
+
// Subtle Unsettling / Organic Imperfect
|
|
391
|
+
{
|
|
392
|
+
name: "Handwritten Thin",
|
|
393
|
+
googleFontsName: "Amatic SC",
|
|
394
|
+
categories: ["hand-drawn", "uneven", "organic", "unsettling", "subtle", "scratchy"],
|
|
395
|
+
description: "Thin hand-drawn letters with subtle irregularity, organic feel",
|
|
396
|
+
artistic: !0
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
name: "Rough Handwriting",
|
|
400
|
+
googleFontsName: "Rock Salt",
|
|
401
|
+
categories: ["hand-drawn", "scratchy", "weathered", "rough", "unsettling", "moderate"],
|
|
402
|
+
description: "Rough, weathered handwriting with natural imperfection",
|
|
403
|
+
artistic: !0
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: "Typewriter Degraded",
|
|
407
|
+
googleFontsName: "Special Elite",
|
|
408
|
+
categories: ["typewriter", "decayed", "weathered", "imperfect", "unsettling", "moderate"],
|
|
409
|
+
description: "Degraded typewriter font, vintage with imperfection",
|
|
410
|
+
artistic: !0
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: "Casual Handwriting",
|
|
414
|
+
googleFontsName: "Handlee",
|
|
415
|
+
categories: ["hand-drawn", "casual", "imperfect", "organic", "subtle"],
|
|
416
|
+
description: "Casual handwriting with subtle imperfection",
|
|
417
|
+
artistic: !1
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
name: "Childlike Organic",
|
|
421
|
+
googleFontsName: "Indie Flower",
|
|
422
|
+
categories: ["hand-drawn", "childlike", "organic", "imperfect", "eerie", "subtle"],
|
|
423
|
+
description: "Childlike handwriting, can feel innocent or eerie depending on context",
|
|
424
|
+
artistic: !1
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: "Scratchy Personal",
|
|
428
|
+
googleFontsName: "Shadows Into Light",
|
|
429
|
+
categories: ["hand-drawn", "scratchy", "personal", "unsettling", "uneven", "moderate"],
|
|
430
|
+
description: "Scratchy personal handwriting with unsettling quality",
|
|
431
|
+
artistic: !0
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: "Hurried Scratchy",
|
|
435
|
+
googleFontsName: "Reenie Beanie",
|
|
436
|
+
categories: ["hand-drawn", "scratchy", "hurried", "uneven", "unsettling", "moderate"],
|
|
437
|
+
description: "Hurried scratchy handwriting with nervous energy",
|
|
438
|
+
artistic: !0
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
name: "Architectural Irregular",
|
|
442
|
+
googleFontsName: "Architects Daughter",
|
|
443
|
+
categories: ["hand-drawn", "imperfect", "uneven", "organic", "subtle"],
|
|
444
|
+
description: "Hand-drawn with architectural irregularity",
|
|
445
|
+
artistic: !1
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: "Informal Unsettling",
|
|
449
|
+
googleFontsName: "Coming Soon",
|
|
450
|
+
categories: ["hand-drawn", "informal", "imperfect", "unsettling", "subtle"],
|
|
451
|
+
description: "Informal handwriting that feels slightly off",
|
|
452
|
+
artistic: !1
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "Manic Handwriting",
|
|
456
|
+
googleFontsName: "Gloria Hallelujah",
|
|
457
|
+
categories: ["hand-drawn", "playful", "manic", "uneven", "unsettling", "moderate"],
|
|
458
|
+
description: "Playful handwriting that can feel manic or unsettled",
|
|
459
|
+
artistic: !0
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
name: "Quick Imperfect",
|
|
463
|
+
googleFontsName: "Just Another Hand",
|
|
464
|
+
categories: ["hand-drawn", "scratchy", "quick", "imperfect", "uneven", "subtle"],
|
|
465
|
+
description: "Quick scratchy handwriting with natural imperfection",
|
|
466
|
+
artistic: !1
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
name: "Organic Handwriting",
|
|
470
|
+
googleFontsName: "Kalam",
|
|
471
|
+
categories: ["hand-drawn", "organic", "natural", "flowing", "subtle"],
|
|
472
|
+
description: "Organic natural handwriting with flowing quality",
|
|
473
|
+
artistic: !1
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: "Flowing Tension",
|
|
477
|
+
googleFontsName: "Satisfy",
|
|
478
|
+
categories: ["script", "flowing", "tension", "elegant", "unsettling", "subtle"],
|
|
479
|
+
description: "Flowing script with underlying tension",
|
|
480
|
+
artistic: !0
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "Unsettling Elegance",
|
|
484
|
+
googleFontsName: "Yellowtail",
|
|
485
|
+
categories: ["script", "elegant", "stylized", "unsettling", "uneven", "moderate"],
|
|
486
|
+
description: "Stylized elegance with unsettling undertones",
|
|
487
|
+
artistic: !0
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "Typewriter Imperfect",
|
|
491
|
+
googleFontsName: "Cutive Mono",
|
|
492
|
+
categories: ["typewriter", "monospace", "imperfect", "decayed", "vintage", "subtle"],
|
|
493
|
+
description: "Imperfect vintage typewriter with character",
|
|
494
|
+
artistic: !0
|
|
380
495
|
}
|
|
381
496
|
];
|
|
382
|
-
function
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
497
|
+
function L(s) {
|
|
498
|
+
const e = s.toLowerCase().split(/\s+/).filter((t) => t.length > 0), o = [], n = [];
|
|
499
|
+
for (const t of e)
|
|
500
|
+
t.startsWith("-") && t.length > 1 ? n.push(t.slice(1)) : o.push(t);
|
|
501
|
+
return { positive: o, negative: n };
|
|
502
|
+
}
|
|
503
|
+
function O(s, e) {
|
|
504
|
+
const o = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Map(), t = 2, i = [];
|
|
505
|
+
for (const l of s) {
|
|
506
|
+
if (i.length >= e) break;
|
|
507
|
+
if (o.has(l.font.googleFontsName))
|
|
508
|
+
continue;
|
|
509
|
+
const r = l.font.categories[0], a = n.get(r) || 0;
|
|
510
|
+
a >= t || (o.add(l.font.googleFontsName), n.set(r, a + 1), i.push(l.font));
|
|
511
|
+
}
|
|
512
|
+
return i;
|
|
513
|
+
}
|
|
514
|
+
function y(s, e) {
|
|
515
|
+
const { positive: o, negative: n } = L(s), t = (e == null ? void 0 : e.limit) ?? 10, l = k.map((r) => {
|
|
516
|
+
let a = 0;
|
|
517
|
+
for (const c of o) {
|
|
518
|
+
for (const h of r.categories)
|
|
519
|
+
(h.includes(c) || c.includes(h)) && (a += 10);
|
|
520
|
+
r.name.toLowerCase().includes(c) && (a += 15), r.description.toLowerCase().includes(c) && (a += 8);
|
|
521
|
+
}
|
|
522
|
+
for (const c of n) {
|
|
523
|
+
for (const h of r.categories)
|
|
524
|
+
(h.includes(c) || c.includes(h)) && (a -= 20);
|
|
525
|
+
r.name.toLowerCase().includes(c) && (a -= 15), r.description.toLowerCase().includes(c) && (a -= 10);
|
|
526
|
+
}
|
|
527
|
+
return r.artistic && (a += 1), { font: r, score: a };
|
|
528
|
+
}).filter((r) => r.score > 0).sort((r, a) => a.score - r.score);
|
|
529
|
+
return O(l, t);
|
|
390
530
|
}
|
|
391
|
-
function
|
|
392
|
-
return y(
|
|
531
|
+
function P(s) {
|
|
532
|
+
return y(s)[0];
|
|
393
533
|
}
|
|
394
|
-
const
|
|
395
|
-
function
|
|
396
|
-
return new Promise((
|
|
397
|
-
const
|
|
398
|
-
if (
|
|
399
|
-
|
|
534
|
+
const p = /* @__PURE__ */ new Set();
|
|
535
|
+
function N(s) {
|
|
536
|
+
return new Promise((e, o) => {
|
|
537
|
+
const n = s.replace(/\s+/g, "+");
|
|
538
|
+
if (p.has(n)) {
|
|
539
|
+
e();
|
|
400
540
|
return;
|
|
401
541
|
}
|
|
402
542
|
if (document.querySelector(
|
|
403
|
-
`link[href*="fonts.googleapis.com"][href*="${
|
|
543
|
+
`link[href*="fonts.googleapis.com"][href*="${n}"]`
|
|
404
544
|
)) {
|
|
405
|
-
|
|
545
|
+
p.add(n), e();
|
|
406
546
|
return;
|
|
407
547
|
}
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
},
|
|
412
|
-
console.warn(`Failed to load Google Font: ${
|
|
413
|
-
}, document.head.appendChild(
|
|
548
|
+
const i = document.createElement("link");
|
|
549
|
+
i.rel = "stylesheet", i.href = `https://fonts.googleapis.com/css2?family=${n}:wght@400&display=swap`, i.onload = () => {
|
|
550
|
+
p.add(n), e();
|
|
551
|
+
}, i.onerror = () => {
|
|
552
|
+
console.warn(`Failed to load Google Font: ${s}`), o(new Error(`Failed to load Google Font: ${s}`));
|
|
553
|
+
}, document.head.appendChild(i);
|
|
414
554
|
});
|
|
415
555
|
}
|
|
416
|
-
function B(
|
|
417
|
-
return Promise.all(
|
|
556
|
+
function B(s) {
|
|
557
|
+
return Promise.all(s.map((e) => N(e)));
|
|
418
558
|
}
|
|
419
|
-
function
|
|
420
|
-
const
|
|
421
|
-
return
|
|
559
|
+
function G(s) {
|
|
560
|
+
const e = s.replace(/\s+/g, "+");
|
|
561
|
+
return p.has(e);
|
|
422
562
|
}
|
|
423
|
-
function
|
|
424
|
-
const o = [
|
|
425
|
-
|
|
426
|
-
|
|
563
|
+
function I(s, e = "sans-serif") {
|
|
564
|
+
const o = [
|
|
565
|
+
"Caveat",
|
|
566
|
+
"Dancing Script",
|
|
567
|
+
"Finger Paint",
|
|
568
|
+
"Fredericka the Great",
|
|
569
|
+
// Subtle unsettling / organic fonts
|
|
570
|
+
"Amatic SC",
|
|
571
|
+
"Handlee",
|
|
572
|
+
"Indie Flower",
|
|
573
|
+
"Shadows Into Light",
|
|
574
|
+
"Rock Salt",
|
|
575
|
+
"Reenie Beanie",
|
|
576
|
+
"Architects Daughter",
|
|
577
|
+
"Coming Soon",
|
|
578
|
+
"Gloria Hallelujah",
|
|
579
|
+
"Just Another Hand",
|
|
580
|
+
"Kalam",
|
|
581
|
+
"Satisfy",
|
|
582
|
+
"Yellowtail"
|
|
583
|
+
], n = [
|
|
584
|
+
"VT323",
|
|
585
|
+
"Press Start 2P",
|
|
586
|
+
"Share Tech Mono",
|
|
587
|
+
// Typewriter fonts
|
|
588
|
+
"Special Elite",
|
|
589
|
+
"Cutive Mono"
|
|
590
|
+
];
|
|
591
|
+
let t = e;
|
|
592
|
+
return o.includes(s) ? t = "cursive" : n.includes(s) && (t = "monospace"), `'${s}', ${t}`;
|
|
427
593
|
}
|
|
428
|
-
function
|
|
429
|
-
const o =
|
|
430
|
-
return y(
|
|
431
|
-
(a) => a.googleFontsName.toLowerCase() !==
|
|
594
|
+
function T(s, e) {
|
|
595
|
+
const o = s.toLowerCase(), n = e.rejectedFont.toLowerCase(), t = e.negativeAspects.map((a) => a.toLowerCase()), i = e.positiveAspects.map((a) => a.toLowerCase());
|
|
596
|
+
return y(s).filter(
|
|
597
|
+
(a) => a.googleFontsName.toLowerCase() !== n && a.name.toLowerCase() !== n
|
|
432
598
|
).map((a) => {
|
|
433
|
-
let
|
|
434
|
-
for (const
|
|
435
|
-
o.includes(
|
|
436
|
-
for (const
|
|
437
|
-
(a.categories.some((
|
|
438
|
-
for (const
|
|
439
|
-
(a.categories.some((
|
|
440
|
-
const h =
|
|
441
|
-
(
|
|
599
|
+
let c = 0;
|
|
600
|
+
for (const d of a.categories)
|
|
601
|
+
o.includes(d) && (c += 5);
|
|
602
|
+
for (const d of i)
|
|
603
|
+
(a.categories.some((u) => u.includes(d) || d.includes(u)) || a.name.toLowerCase().includes(d) || a.description.toLowerCase().includes(d)) && (c += 15);
|
|
604
|
+
for (const d of t)
|
|
605
|
+
(a.categories.some((u) => u.includes(d) || d.includes(u)) || a.name.toLowerCase().includes(d) || a.description.toLowerCase().includes(d)) && (c -= 20);
|
|
606
|
+
const h = i.some(
|
|
607
|
+
(d) => d.includes("striking") || d.includes("artistic") || d.includes("unique")
|
|
442
608
|
);
|
|
443
|
-
return h && a.artistic && (
|
|
444
|
-
}).filter((a) => a.score > 0).sort((a,
|
|
609
|
+
return h && a.artistic && (c += 10), h && !a.artistic && (c -= 5), { font: a, score: c };
|
|
610
|
+
}).filter((a) => a.score > 0).sort((a, c) => c.score - a.score).map((a) => a.font);
|
|
445
611
|
}
|
|
446
|
-
function
|
|
447
|
-
return
|
|
612
|
+
function Y(s, e) {
|
|
613
|
+
return T(s, e)[0];
|
|
448
614
|
}
|
|
449
615
|
if (typeof window < "u") {
|
|
450
|
-
const
|
|
451
|
-
AnimatedText:
|
|
616
|
+
const s = {
|
|
617
|
+
AnimatedText: v,
|
|
452
618
|
FallingAnimation: f,
|
|
453
619
|
SplittingAnimation: C,
|
|
454
|
-
GlitchingAnimation:
|
|
455
|
-
FloatingAnimation:
|
|
620
|
+
GlitchingAnimation: x,
|
|
621
|
+
FloatingAnimation: S,
|
|
456
622
|
calculateDisintegration: b,
|
|
457
623
|
// Font utilities
|
|
458
|
-
fontSuggestions:
|
|
624
|
+
fontSuggestions: k,
|
|
459
625
|
suggestFonts: y,
|
|
460
|
-
suggestFont:
|
|
461
|
-
loadGoogleFont:
|
|
626
|
+
suggestFont: P,
|
|
627
|
+
loadGoogleFont: N,
|
|
462
628
|
loadGoogleFonts: B,
|
|
463
|
-
isFontLoaded:
|
|
464
|
-
getFontFamily:
|
|
465
|
-
refineSuggestion:
|
|
466
|
-
refineFont:
|
|
629
|
+
isFontLoaded: G,
|
|
630
|
+
getFontFamily: I,
|
|
631
|
+
refineSuggestion: T,
|
|
632
|
+
refineFont: Y,
|
|
633
|
+
MOOD_CATEGORIES: E,
|
|
634
|
+
INTENSITY_CATEGORIES: R
|
|
467
635
|
};
|
|
468
|
-
window.TypographyToolkit =
|
|
636
|
+
window.TypographyToolkit = s, window.AnimatedText = v;
|
|
469
637
|
}
|
|
470
638
|
export {
|
|
471
|
-
|
|
639
|
+
v as AnimatedText,
|
|
472
640
|
f as FallingAnimation,
|
|
473
|
-
|
|
474
|
-
|
|
641
|
+
S as FloatingAnimation,
|
|
642
|
+
x as GlitchingAnimation,
|
|
643
|
+
R as INTENSITY_CATEGORIES,
|
|
644
|
+
E as MOOD_CATEGORIES,
|
|
475
645
|
C as SplittingAnimation,
|
|
476
646
|
b as calculateDisintegration,
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
647
|
+
k as fontSuggestions,
|
|
648
|
+
I as getFontFamily,
|
|
649
|
+
G as isFontLoaded,
|
|
650
|
+
N as loadGoogleFont,
|
|
481
651
|
B as loadGoogleFonts,
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
652
|
+
Y as refineFont,
|
|
653
|
+
T as refineSuggestion,
|
|
654
|
+
P as suggestFont,
|
|
485
655
|
y as suggestFonts
|
|
486
656
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var TypographyToolkit=function(d){"use strict";class f{update(t,o,e,i={}){const s=i.speed||1,l=i.amplitude||20,h=o*.2,c=(e*10*s+h*5)%l-l/2;return{...t,y:c}}}class w{update(t,o,e,i={}){const s=i.speed||1,l=i.amplitude||4,h=o*.2,a=Math.sin(e*.5*s+h)*l;return{...t,x:a}}}class C{constructor(){this.lastUpdate=0,this.glitchX=0,this.glitchY=0,this.glitchRot=0}update(t,o,e,i={}){const s=i.amplitude||3;return e-this.lastUpdate>.1&&(this.glitchX=(Math.random()-.5)*s,this.glitchY=(Math.random()-.5)*(s*.67),this.glitchRot=(Math.random()-.5)*s,this.lastUpdate=e),{...t,x:this.glitchX,y:this.glitchY,rotation:this.glitchRot}}}class v{update(t,o,e,i={}){const s=i.speed||1,l=i.amplitude||15,h=o*.2,c=-((e*8*s+h*4)%l-l/2);return{...t,y:c}}}function B(n,t){const{x:o,y:e,rotation:i,scale:s,opacity:l}=t;n.style.transform=`translate(${o}px, ${e}px) rotate(${i}deg) scale(${s})`,n.style.opacity=l.toString()}function k(n,t,o,e,i,s){if(!s.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const l=s.radius||80,h=s.strength||1,a=s.behaviors||["fall-away","split-apart","explode"],c=o-n,u=e-t,r=Math.sqrt(c*c+u*u);if(r>=l)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const g=(1-r/l)*h,m=Math.atan2(u,c),R=a[i%a.length];let p;switch(R){case"fall-away":const H=Math.cos(m)*g*20,G=Math.sin(m)*g*40+g*30;p={x:H,y:G,rotation:g*15,scale:1,opacity:1-g*.6};break;case"split-apart":const E=i%2===0?1:-1;p={x:E*g*50,y:(Math.random()-.5)*g*10,rotation:g*10*E,scale:1,opacity:1-g*.6};break;case"explode":const P=m+(Math.random()-.5)*.5;p={x:Math.cos(P)*g*40,y:Math.sin(P)*g*40,rotation:g*30,scale:1+g*.4,opacity:1-g*.6};break;default:p={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:p,applied:!0}}class b{constructor(t){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=t.container,this.animationTypes=t.animations||["falling","splitting","glitching","floating"],this.cycle=t.cycle!==!1,this.speed=t.speed||1,this.amplitude=t.amplitude||1,this.disintegration=t.disintegration||{enabled:!1},this.style=t.style||{},this.fadeOut=t.fadeOut||0,this.callbacks=t.callbacks,this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",t.containerClass&&(this.textContainer.className=t.containerClass),t.containerStyle&&Object.entries(t.containerStyle).forEach(([e,i])=>{this.textContainer.style.setProperty(e,i)}),t.position){let e=t.position.x,i=t.position.y;if(t.position.constrainToViewport){this.container.getBoundingClientRect();const s=window.innerWidth,l=window.innerHeight,h=t.text.length*20;e!==void 0&&(e=Math.max(0,Math.min(e,s-h))),i!==void 0&&(i=Math.max(0,Math.min(i,l-50)))}e!==void 0&&(this.textContainer.style.left=`${e}px`),i!==void 0&&(this.textContainer.style.top=`${i}px`)}this.createLetters(t.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(t){t.toUpperCase().split("").forEach((e,i)=>{if(e===" "){const h=document.createTextNode(" ");this.textContainer.appendChild(h);return}const s=document.createElement("span");s.className="animated-letter",s.textContent=e,s.dataset.index=i.toString(),s.dataset.char=e,this.applyStyle(s),s.style.display="inline-block",s.style.position="relative",s.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(s);const l=s.getBoundingClientRect();this.letters.push({element:s,index:i,char:e,baseX:l.left,baseY:l.top})}),this.container.appendChild(this.textContainer)}applyStyle(t){this.style.fontFamily&&(t.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(t.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(t.style.color=this.style.color),this.style.fontWeight&&(t.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(t.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(t.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(t.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=t=>{this.mouseX=t.clientX,this.mouseY=t.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const t=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((e,i)=>{var u;const s=e.element.getBoundingClientRect(),l=s.left+s.width/2,h=s.top+s.height/2,a=k(l,h,this.mouseX,this.mouseY,i,this.disintegration);let c;if(a.applied)c=a.state,(u=this.callbacks)!=null&&u.onDisintegrate&&this.callbacks.onDisintegrate(i);else{const r=this.getAnimationType(i);c=this.getAnimation(r).update({x:0,y:0,rotation:0,scale:1,opacity:1},i,o,{speed:this.speed,amplitude:this.amplitude*(r==="falling"||r==="floating"?20:4)})}B(e.element,c)}),this.animationFrame=requestAnimationFrame(t)};this.animationFrame=requestAnimationFrame(t)}getAnimationType(t){return this.cycle?this.animationTypes[t%this.animationTypes.length]:this.animationTypes[0]}getAnimation(t){switch(t){case"falling":return new f;case"splitting":return new w;case"glitching":return new C;case"floating":return new v;default:return new f}}destroy(){var t;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),(t=this.callbacks)!=null&&t.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=[{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"],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"],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}];function y(n){const t=n.toLowerCase();return x.map(e=>{let i=0;for(const s of e.categories)t.includes(s)&&(i+=10);return(e.name.toLowerCase().includes(t)||t.includes(e.name.toLowerCase()))&&(i+=15),(e.description.toLowerCase().includes(t)||t.includes(e.description.toLowerCase()))&&(i+=8),e.artistic&&(i+=1),{font:e,score:i}}).filter(e=>e.score>0).sort((e,i)=>i.score-e.score).map(e=>e.font)}function M(n){return y(n)[0]}const F=new Set;function S(n){return new Promise((t,o)=>{const e=n.replace(/\s+/g,"+");if(F.has(e)){t();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${e}"]`)){F.add(e),t();return}const s=document.createElement("link");s.rel="stylesheet",s.href=`https://fonts.googleapis.com/css2?family=${e}:wght@400&display=swap`,s.onload=()=>{F.add(e),t()},s.onerror=()=>{console.warn(`Failed to load Google Font: ${n}`),o(new Error(`Failed to load Google Font: ${n}`))},document.head.appendChild(s)})}function N(n){return Promise.all(n.map(t=>S(t)))}function D(n){const t=n.replace(/\s+/g,"+");return F.has(t)}function A(n,t="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great"],e=["VT323","Press Start 2P","Share Tech Mono"];let i=t;return o.includes(n)?i="cursive":e.includes(n)&&(i="monospace"),`'${n}', ${i}`}function T(n,t){const o=n.toLowerCase(),e=t.rejectedFont.toLowerCase(),i=t.negativeAspects.map(a=>a.toLowerCase()),s=t.positiveAspects.map(a=>a.toLowerCase());return y(n).filter(a=>a.googleFontsName.toLowerCase()!==e&&a.name.toLowerCase()!==e).map(a=>{let c=0;for(const r of a.categories)o.includes(r)&&(c+=5);for(const r of s)(a.categories.some(m=>m.includes(r)||r.includes(m))||a.name.toLowerCase().includes(r)||a.description.toLowerCase().includes(r))&&(c+=15);for(const r of i)(a.categories.some(m=>m.includes(r)||r.includes(m))||a.name.toLowerCase().includes(r)||a.description.toLowerCase().includes(r))&&(c-=20);const u=s.some(r=>r.includes("striking")||r.includes("artistic")||r.includes("unique"));return u&&a.artistic&&(c+=10),u&&!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 L(n,t){return T(n,t)[0]}if(typeof window<"u"){const n={AnimatedText:b,FallingAnimation:f,SplittingAnimation:w,GlitchingAnimation:C,FloatingAnimation:v,calculateDisintegration:k,fontSuggestions:x,suggestFonts:y,suggestFont:M,loadGoogleFont:S,loadGoogleFonts:N,isFontLoaded:D,getFontFamily:A,refineSuggestion:T,refineFont:L};window.TypographyToolkit=n,window.AnimatedText=b}return d.AnimatedText=b,d.FallingAnimation=f,d.FloatingAnimation=v,d.GlitchingAnimation=C,d.SplittingAnimation=w,d.calculateDisintegration=k,d.fontSuggestions=x,d.getFontFamily=A,d.isFontLoaded=D,d.loadGoogleFont=S,d.loadGoogleFonts=N,d.refineFont=L,d.refineSuggestion=T,d.suggestFont=M,d.suggestFonts=y,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}),d}({});
|
|
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 +1 @@
|
|
|
1
|
-
(function(l,m){typeof exports=="object"&&typeof module<"u"?m(exports):typeof define=="function"&&define.amd?define(["exports"],m):(l=typeof globalThis<"u"?globalThis:l||self,m(l.TypographyToolkit={}))})(this,function(l){"use strict";class m{update(t,o,e,i={}){const s=i.speed||1,c=i.amplitude||20,h=o*.2,d=(e*10*s+h*5)%c-c/2;return{...t,y:d}}}class w{update(t,o,e,i={}){const s=i.speed||1,c=i.amplitude||4,h=o*.2,n=Math.sin(e*.5*s+h)*c;return{...t,x:n}}}class C{constructor(){this.lastUpdate=0,this.glitchX=0,this.glitchY=0,this.glitchRot=0}update(t,o,e,i={}){const s=i.amplitude||3;return e-this.lastUpdate>.1&&(this.glitchX=(Math.random()-.5)*s,this.glitchY=(Math.random()-.5)*(s*.67),this.glitchRot=(Math.random()-.5)*s,this.lastUpdate=e),{...t,x:this.glitchX,y:this.glitchY,rotation:this.glitchRot}}}class v{update(t,o,e,i={}){const s=i.speed||1,c=i.amplitude||15,h=o*.2,d=-((e*8*s+h*4)%c-c/2);return{...t,y:d}}}function B(a,t){const{x:o,y:e,rotation:i,scale:s,opacity:c}=t;a.style.transform=`translate(${o}px, ${e}px) rotate(${i}deg) scale(${s})`,a.style.opacity=c.toString()}function x(a,t,o,e,i,s){if(!s.enabled)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const c=s.radius||80,h=s.strength||1,n=s.behaviors||["fall-away","split-apart","explode"],d=o-a,u=e-t,r=Math.sqrt(d*d+u*u);if(r>=c)return{state:{x:0,y:0,rotation:0,scale:1,opacity:1},applied:!1};const g=(1-r/c)*h,p=Math.atan2(u,d),R=n[i%n.length];let f;switch(R){case"fall-away":const H=Math.cos(p)*g*20,G=Math.sin(p)*g*40+g*30;f={x:H,y:G,rotation:g*15,scale:1,opacity:1-g*.6};break;case"split-apart":const E=i%2===0?1:-1;f={x:E*g*50,y:(Math.random()-.5)*g*10,rotation:g*10*E,scale:1,opacity:1-g*.6};break;case"explode":const P=p+(Math.random()-.5)*.5;f={x:Math.cos(P)*g*40,y:Math.sin(P)*g*40,rotation:g*30,scale:1+g*.4,opacity:1-g*.6};break;default:f={x:0,y:0,rotation:0,scale:1,opacity:1}}return{state:f,applied:!0}}class b{constructor(t){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=t.container,this.animationTypes=t.animations||["falling","splitting","glitching","floating"],this.cycle=t.cycle!==!1,this.speed=t.speed||1,this.amplitude=t.amplitude||1,this.disintegration=t.disintegration||{enabled:!1},this.style=t.style||{},this.fadeOut=t.fadeOut||0,this.callbacks=t.callbacks,this.textContainer=document.createElement("div"),this.textContainer.style.position="absolute",this.textContainer.style.pointerEvents="none",this.textContainer.style.zIndex="1",t.containerClass&&(this.textContainer.className=t.containerClass),t.containerStyle&&Object.entries(t.containerStyle).forEach(([e,i])=>{this.textContainer.style.setProperty(e,i)}),t.position){let e=t.position.x,i=t.position.y;if(t.position.constrainToViewport){this.container.getBoundingClientRect();const s=window.innerWidth,c=window.innerHeight,h=t.text.length*20;e!==void 0&&(e=Math.max(0,Math.min(e,s-h))),i!==void 0&&(i=Math.max(0,Math.min(i,c-50)))}e!==void 0&&(this.textContainer.style.left=`${e}px`),i!==void 0&&(this.textContainer.style.top=`${i}px`)}this.createLetters(t.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(t){t.toUpperCase().split("").forEach((e,i)=>{if(e===" "){const h=document.createTextNode(" ");this.textContainer.appendChild(h);return}const s=document.createElement("span");s.className="animated-letter",s.textContent=e,s.dataset.index=i.toString(),s.dataset.char=e,this.applyStyle(s),s.style.display="inline-block",s.style.position="relative",s.style.transition="transform 0.1s ease-out",this.textContainer.appendChild(s);const c=s.getBoundingClientRect();this.letters.push({element:s,index:i,char:e,baseX:c.left,baseY:c.top})}),this.container.appendChild(this.textContainer)}applyStyle(t){this.style.fontFamily&&(t.style.fontFamily=this.style.fontFamily),this.style.fontSize&&(t.style.fontSize=`${this.style.fontSize}px`),this.style.color&&(t.style.color=this.style.color),this.style.fontWeight&&(t.style.fontWeight=this.style.fontWeight),this.style.textShadow&&(t.style.textShadow=this.style.textShadow),this.style.letterSpacing&&(t.style.letterSpacing=this.style.letterSpacing),this.style.textTransform&&(t.style.textTransform=this.style.textTransform)}setupMouseTracking(){this.disintegration.enabled&&(this.mouseMoveHandler=t=>{this.mouseX=t.clientX,this.mouseY=t.clientY},document.addEventListener("mousemove",this.mouseMoveHandler))}startAnimation(){const t=()=>{if(this.isDestroyed)return;const o=(Date.now()-this.startTime)*.001;this.letters.forEach((e,i)=>{var u;const s=e.element.getBoundingClientRect(),c=s.left+s.width/2,h=s.top+s.height/2,n=x(c,h,this.mouseX,this.mouseY,i,this.disintegration);let d;if(n.applied)d=n.state,(u=this.callbacks)!=null&&u.onDisintegrate&&this.callbacks.onDisintegrate(i);else{const r=this.getAnimationType(i);d=this.getAnimation(r).update({x:0,y:0,rotation:0,scale:1,opacity:1},i,o,{speed:this.speed,amplitude:this.amplitude*(r==="falling"||r==="floating"?20:4)})}B(e.element,d)}),this.animationFrame=requestAnimationFrame(t)};this.animationFrame=requestAnimationFrame(t)}getAnimationType(t){return this.cycle?this.animationTypes[t%this.animationTypes.length]:this.animationTypes[0]}getAnimation(t){switch(t){case"falling":return new m;case"splitting":return new w;case"glitching":return new C;case"floating":return new v;default:return new m}}destroy(){var t;this.isDestroyed||(this.isDestroyed=!0,this.animationFrame!==null&&cancelAnimationFrame(this.animationFrame),this.mouseMoveHandler&&document.removeEventListener("mousemove",this.mouseMoveHandler),(t=this.callbacks)!=null&&t.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 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"],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"],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}];function y(a){const t=a.toLowerCase();return k.map(e=>{let i=0;for(const s of e.categories)t.includes(s)&&(i+=10);return(e.name.toLowerCase().includes(t)||t.includes(e.name.toLowerCase()))&&(i+=15),(e.description.toLowerCase().includes(t)||t.includes(e.description.toLowerCase()))&&(i+=8),e.artistic&&(i+=1),{font:e,score:i}}).filter(e=>e.score>0).sort((e,i)=>i.score-e.score).map(e=>e.font)}function M(a){return y(a)[0]}const F=new Set;function S(a){return new Promise((t,o)=>{const e=a.replace(/\s+/g,"+");if(F.has(e)){t();return}if(document.querySelector(`link[href*="fonts.googleapis.com"][href*="${e}"]`)){F.add(e),t();return}const s=document.createElement("link");s.rel="stylesheet",s.href=`https://fonts.googleapis.com/css2?family=${e}:wght@400&display=swap`,s.onload=()=>{F.add(e),t()},s.onerror=()=>{console.warn(`Failed to load Google Font: ${a}`),o(new Error(`Failed to load Google Font: ${a}`))},document.head.appendChild(s)})}function N(a){return Promise.all(a.map(t=>S(t)))}function D(a){const t=a.replace(/\s+/g,"+");return F.has(t)}function A(a,t="sans-serif"){const o=["Caveat","Dancing Script","Finger Paint","Fredericka the Great"],e=["VT323","Press Start 2P","Share Tech Mono"];let i=t;return o.includes(a)?i="cursive":e.includes(a)&&(i="monospace"),`'${a}', ${i}`}function T(a,t){const o=a.toLowerCase(),e=t.rejectedFont.toLowerCase(),i=t.negativeAspects.map(n=>n.toLowerCase()),s=t.positiveAspects.map(n=>n.toLowerCase());return y(a).filter(n=>n.googleFontsName.toLowerCase()!==e&&n.name.toLowerCase()!==e).map(n=>{let d=0;for(const r of n.categories)o.includes(r)&&(d+=5);for(const r of s)(n.categories.some(p=>p.includes(r)||r.includes(p))||n.name.toLowerCase().includes(r)||n.description.toLowerCase().includes(r))&&(d+=15);for(const r of i)(n.categories.some(p=>p.includes(r)||r.includes(p))||n.name.toLowerCase().includes(r)||n.description.toLowerCase().includes(r))&&(d-=20);const u=s.some(r=>r.includes("striking")||r.includes("artistic")||r.includes("unique"));return u&&n.artistic&&(d+=10),u&&!n.artistic&&(d-=5),{font:n,score:d}}).filter(n=>n.score>0).sort((n,d)=>d.score-n.score).map(n=>n.font)}function L(a,t){return T(a,t)[0]}if(typeof window<"u"){const a={AnimatedText:b,FallingAnimation:m,SplittingAnimation:w,GlitchingAnimation:C,FloatingAnimation:v,calculateDisintegration:x,fontSuggestions:k,suggestFonts:y,suggestFont:M,loadGoogleFont:S,loadGoogleFonts:N,isFontLoaded:D,getFontFamily:A,refineSuggestion:T,refineFont:L};window.TypographyToolkit=a,window.AnimatedText=b}l.AnimatedText=b,l.FallingAnimation=m,l.FloatingAnimation=v,l.GlitchingAnimation=C,l.SplittingAnimation=w,l.calculateDisintegration=x,l.fontSuggestions=k,l.getFontFamily=A,l.isFontLoaded=D,l.loadGoogleFont=S,l.loadGoogleFonts=N,l.refineFont=L,l.refineSuggestion=T,l.suggestFont=M,l.suggestFonts=y,Object.defineProperty(l,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,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"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typography-toolkit",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.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",
|