@edwinvakayil/calligraphy 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation.d.ts +5 -2
- package/dist/index.d.ts +62 -36
- package/dist/index.esm.js +359 -73
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +359 -73
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +62 -36
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -131,55 +131,250 @@ function preloadFonts(families) {
|
|
|
131
131
|
|
|
132
132
|
const STYLE_ID = "rts-hero-animations";
|
|
133
133
|
const CSS = `
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
@keyframes rts-
|
|
144
|
-
@keyframes rts-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
@keyframes rts-
|
|
149
|
-
@keyframes rts-
|
|
150
|
-
@keyframes rts-
|
|
151
|
-
@keyframes rts-
|
|
152
|
-
@keyframes rts-
|
|
153
|
-
@keyframes rts-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
@keyframes rts-
|
|
157
|
-
@keyframes rts-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
134
|
+
/* ─── Easing tokens (reused across all keyframes) ──────────────────────────
|
|
135
|
+
All durations are tuned for perceptual smoothness:
|
|
136
|
+
- spring = cubic-bezier(0.16,1,0.3,1) — soft, natural overshoot
|
|
137
|
+
- snap = cubic-bezier(0.77,0,0.18,1) — fast-in, crisp-out
|
|
138
|
+
- bounce = cubic-bezier(0.34,1.56,0.64,1)— elastic overshoot
|
|
139
|
+
- cinema = cubic-bezier(0.4,0,0.2,1) — material easing
|
|
140
|
+
──────────────────────────────────────────────────────────────────────── */
|
|
141
|
+
|
|
142
|
+
/* ── Batch 1 — originals ─────────────────────────────────────────────────── */
|
|
143
|
+
@keyframes rts-rise {from{opacity:0;transform:translateY(32px)}to{opacity:1;transform:translateY(0)}}
|
|
144
|
+
@keyframes rts-clip {from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0% 0 0)}}
|
|
145
|
+
@keyframes rts-pop {0%{opacity:0;transform:scale(0.75)}60%{opacity:1;transform:scale(1.04)}100%{transform:scale(1)}}
|
|
146
|
+
@keyframes rts-blur {from{opacity:0;filter:blur(14px);transform:scale(1.04)}to{opacity:1;filter:blur(0);transform:scale(1)}}
|
|
147
|
+
@keyframes rts-flip {from{opacity:0;transform:perspective(600px) rotateX(30deg) translateY(20px)}to{opacity:1;transform:perspective(600px) rotateX(0) translateY(0)}}
|
|
148
|
+
@keyframes rts-swipe {from{opacity:0;transform:translateX(60px)}to{opacity:1;transform:translateX(0)}}
|
|
149
|
+
@keyframes rts-bounce {0%{opacity:0;transform:translateY(-60px)}60%{opacity:1;transform:translateY(10px)}80%{transform:translateY(-5px)}100%{transform:translateY(0)}}
|
|
150
|
+
@keyframes rts-type {from{width:0}to{width:100%}}
|
|
151
|
+
@keyframes rts-blink {50%{border-color:transparent}}
|
|
152
|
+
@keyframes rts-word-rise {from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}
|
|
153
|
+
@keyframes rts-letter-in {from{opacity:0;transform:translateX(-16px) rotate(-4deg)}to{opacity:1;transform:none}}
|
|
154
|
+
|
|
155
|
+
/* ── Batch 2 — modern ────────────────────────────────────────────────────── */
|
|
156
|
+
@keyframes rts-velvet {from{opacity:0;transform:translate(-12px,20px) skewX(4deg)}to{opacity:1;transform:none}}
|
|
157
|
+
@keyframes rts-curtain {from{clip-path:inset(0 0 100% 0)}to{clip-path:inset(0 0 0% 0)}}
|
|
158
|
+
@keyframes rts-morph {0%{opacity:0;transform:scaleY(0.3) scaleX(1.3) translateY(10px)}60%{opacity:1;transform:scaleY(1.08) scaleX(0.97)}100%{transform:none}}
|
|
159
|
+
@keyframes rts-ground {from{transform:translateY(110%);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
160
|
+
@keyframes rts-cascade {from{opacity:0;transform:translateY(-28px) translateX(10px) rotate(8deg)}to{opacity:1;transform:none}}
|
|
161
|
+
@keyframes rts-spotlight {0%{opacity:0;letter-spacing:0.3em;transform:scaleX(1.15)}100%{opacity:1;letter-spacing:-0.03em;transform:scaleX(1)}}
|
|
162
|
+
@keyframes rts-ink {0%{opacity:0;transform:translateY(6px) scale(0.96)}100%{opacity:1;transform:none}}
|
|
163
|
+
@keyframes rts-hinge {from{opacity:0;transform:perspective(400px) rotateY(-40deg) translateX(-20px)}to{opacity:1;transform:perspective(400px) rotateY(0) translateX(0)}}
|
|
164
|
+
@keyframes rts-stretch {0%{opacity:0;transform:scaleX(0.05)}60%{transform:scaleX(1.04)}100%{opacity:1;transform:none}}
|
|
165
|
+
@keyframes rts-peel {from{clip-path:inset(100% 0 0 0)}to{clip-path:inset(0% 0 0 0)}}
|
|
166
|
+
@keyframes rts-fold {from{opacity:0;transform:rotateZ(-8deg) translateY(18px)}to{opacity:1;transform:none}}
|
|
167
|
+
@keyframes rts-shear {from{opacity:0;transform:skewY(8deg) translateY(12px)}to{opacity:1;transform:none}}
|
|
168
|
+
/* ripple — elastic scale from compressed point, outward wave delay */
|
|
169
|
+
@keyframes rts-ripple-w {
|
|
170
|
+
0% {opacity:0;transform:scale(0.4) translateY(20px)}
|
|
171
|
+
55% {opacity:1;transform:scale(1.08) translateY(-3px)}
|
|
172
|
+
75% {transform:scale(0.97) translateY(1px)}
|
|
173
|
+
100%{opacity:1;transform:scale(1) translateY(0)}
|
|
174
|
+
}
|
|
175
|
+
/* cinch — character pinches on scaleX then snaps open with skew */
|
|
176
|
+
@keyframes rts-cinch {
|
|
177
|
+
0% {opacity:0;transform:scaleX(0) skewX(20deg)}
|
|
178
|
+
50% {opacity:1;transform:scaleX(1.12) skewX(-4deg)}
|
|
179
|
+
75% {transform:scaleX(0.95) skewX(1deg)}
|
|
180
|
+
100%{opacity:1;transform:scaleX(1) skewX(0)}
|
|
181
|
+
}
|
|
182
|
+
/* tiltrise — words rise while untilting from a sideways lean */
|
|
183
|
+
@keyframes rts-tiltrise {
|
|
184
|
+
0% {opacity:0;transform:translateY(36px) rotate(-6deg) skewX(8deg)}
|
|
185
|
+
65% {opacity:1;transform:translateY(-3px) rotate(0.5deg) skewX(-1deg)}
|
|
186
|
+
100%{opacity:1;transform:translateY(0) rotate(0) skewX(0)}
|
|
187
|
+
}
|
|
188
|
+
@keyframes rts-cardflip {from{opacity:0;transform:perspective(300px) rotateX(-90deg)}to{opacity:1;transform:perspective(300px) rotateX(0)}}
|
|
189
|
+
@keyframes rts-conv-l {from{opacity:0;transform:translateX(-40px)}to{opacity:1;transform:translateX(0)}}
|
|
190
|
+
@keyframes rts-conv-r {from{opacity:0;transform:translateX( 40px)}to{opacity:1;transform:translateX(0)}}
|
|
191
|
+
@keyframes rts-splitrise-t{from{opacity:0;transform:translateY(-24px)}to{opacity:1;transform:translateY(0)}}
|
|
192
|
+
@keyframes rts-splitrise-b{from{opacity:0;transform:translateY( 24px)}to{opacity:1;transform:translateY(0)}}
|
|
193
|
+
|
|
194
|
+
/* ── Batch 3 — new mechanics ─────────────────────────────────────────────── */
|
|
195
|
+
|
|
196
|
+
/* tectonic: words slam from alternating sides with skew — unique X+skew combo */
|
|
197
|
+
@keyframes rts-tec-l{from{opacity:0;transform:translateX(-55px) skewX(-7deg)}to{opacity:1;transform:none}}
|
|
198
|
+
@keyframes rts-tec-r{from{opacity:0;transform:translateX( 55px) skewX( 7deg)}to{opacity:1;transform:none}}
|
|
199
|
+
|
|
200
|
+
/* stratify: each word enters from deep Z with blur — different from blur (which is whole-el) */
|
|
201
|
+
@keyframes rts-strat{
|
|
202
|
+
from{opacity:0;transform:perspective(900px) translateZ(-200px) rotateX(10deg);filter:blur(6px)}
|
|
203
|
+
to {opacity:1;transform:perspective(900px) translateZ(0) rotateX(0); filter:blur(0)}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* unfurl: line expands from center — horizontal center-clip, not edge-clip */
|
|
207
|
+
@keyframes rts-unfurl{from{clip-path:inset(0 50% 0 50%)}to{clip-path:inset(0 0% 0 0%)}}
|
|
208
|
+
|
|
209
|
+
/* gravityWell: chars fall from sky with precise physics micro-rotation */
|
|
210
|
+
@keyframes rts-gwell{
|
|
211
|
+
0% {opacity:0;transform:translateY(-72px) scale(1.18) rotate(-3.5deg)}
|
|
212
|
+
52% {opacity:1;transform:translateY(7px) scale(0.98) rotate(0.4deg)}
|
|
213
|
+
78% {transform:translateY(-3px) scale(1.005) rotate(0)}
|
|
214
|
+
100%{opacity:1;transform:none}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* orbit: words grow from dot, rotating on Z — scale+rotation combo, unique */
|
|
218
|
+
@keyframes rts-orbit{
|
|
219
|
+
from{opacity:0;transform:scale(0.12) rotate(-28deg)}
|
|
220
|
+
58% {opacity:1;transform:scale(1.07) rotate(2.5deg)}
|
|
221
|
+
100%{opacity:1;transform:none}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* liquid: per-word squash then overshoot spring — scaleY+scaleX cross-axis */
|
|
225
|
+
@keyframes rts-liquid{
|
|
226
|
+
0% {opacity:0;transform:scaleY(0.08) scaleX(1.5) translateY(28px)}
|
|
227
|
+
40% {opacity:1;transform:scaleY(1.12) scaleX(0.94) translateY(-4px)}
|
|
228
|
+
65% {transform:scaleY(0.97) scaleX(1.015)}
|
|
229
|
+
100%{opacity:1;transform:none}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* noiseFade: 3 random opacity waveforms per word — signal-lock feel */
|
|
233
|
+
@keyframes rts-nf0{0%{opacity:0}22%{opacity:.7}44%{opacity:.1}66%{opacity:.95}88%{opacity:.4}100%{opacity:1}}
|
|
234
|
+
@keyframes rts-nf1{0%{opacity:0}18%{opacity:.8}38%{opacity:.15}58%{opacity:1}78%{opacity:.5}100%{opacity:1}}
|
|
235
|
+
@keyframes rts-nf2{0%{opacity:0}28%{opacity:.3}50%{opacity:.9}70%{opacity:.05}88%{opacity:.85}100%{opacity:1}}
|
|
236
|
+
|
|
237
|
+
/* slab: scaleX from-left stamp — fastest entrance, print-press energy */
|
|
238
|
+
@keyframes rts-slab{
|
|
239
|
+
0% {opacity:0;transform:scaleX(0) skewX(8deg)}
|
|
240
|
+
52% {opacity:1;transform:scaleX(1.05) skewX(-1deg)}
|
|
241
|
+
100%{opacity:1;transform:none}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* thread: chars ride individual sine-wave Y offsets set via CSS var */
|
|
245
|
+
@keyframes rts-thread{from{opacity:0;transform:translateY(var(--ty,18px))}to{opacity:1;transform:translateY(0)}}
|
|
246
|
+
|
|
247
|
+
/* billboard: whole-line rotateY — different axis from flip (rotateX) */
|
|
248
|
+
@keyframes rts-billboard{
|
|
249
|
+
from{opacity:0;transform:perspective(800px) rotateY(-32deg) translateX(-24px);filter:blur(3px)}
|
|
250
|
+
to {opacity:1;transform:perspective(800px) rotateY(0) translateX(0); filter:blur(0)}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
254
|
+
CLASS DECLARATIONS — all animations use animation-fill-mode: both so
|
|
255
|
+
the element stays at its final state without needing JS cleanup.
|
|
256
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
257
|
+
|
|
258
|
+
/* ── Batch 1 whole-element ───────────────────────────────────────────────── */
|
|
259
|
+
.rts-rise {animation:rts-rise 0.9s cubic-bezier(0.16,1,0.3,1) both}
|
|
260
|
+
.rts-clip {animation:rts-clip 1.1s cubic-bezier(0.77,0,0.18,1) both}
|
|
261
|
+
.rts-pop {animation:rts-pop 0.7s cubic-bezier(0.34,1.56,0.64,1) both}
|
|
262
|
+
.rts-blur {animation:rts-blur 1s cubic-bezier(0.16,1,0.3,1) both}
|
|
263
|
+
.rts-flip {animation:rts-flip 0.9s cubic-bezier(0.16,1,0.3,1) both;transform-origin:center bottom}
|
|
264
|
+
.rts-swipe {animation:rts-swipe 0.8s cubic-bezier(0.16,1,0.3,1) both}
|
|
265
|
+
.rts-bounce {animation:rts-bounce 0.9s cubic-bezier(0.36,0.07,0.19,0.97) both}
|
|
266
|
+
.rts-typewriter {overflow:hidden;white-space:nowrap;border-right:2px solid currentColor;width:0;animation:rts-type 1.6s steps(22,end) both,rts-blink 0.7s step-end 1.6s 3}
|
|
267
|
+
|
|
268
|
+
/* ── Batch 2 whole-element ───────────────────────────────────────────────── */
|
|
269
|
+
.rts-morph {animation:rts-morph 0.8s cubic-bezier(0.34,1.56,0.64,1) both}
|
|
270
|
+
.rts-spotlight {animation:rts-spotlight 1s cubic-bezier(0.16,1,0.3,1) both}
|
|
271
|
+
.rts-stretch {animation:rts-stretch 0.9s cubic-bezier(0.34,1.56,0.64,1) both}
|
|
272
|
+
|
|
273
|
+
/* ── Batch 3 whole-element ───────────────────────────────────────────────── */
|
|
274
|
+
.rts-unfurl {animation:rts-unfurl 0.95s cubic-bezier(0.77,0,0.18,1) both}
|
|
275
|
+
.rts-billboard {animation:rts-billboard 0.95s cubic-bezier(0.16,1,0.3,1) both;transform-origin:left center}
|
|
276
|
+
|
|
277
|
+
/* ── Per-word / per-char spans (batch 1+2) ───────────────────────────────── */
|
|
278
|
+
.rts-word {display:inline-block;opacity:0;transform:translateY(24px);animation:rts-word-rise 0.7s cubic-bezier(0.16,1,0.3,1) both}
|
|
279
|
+
.rts-letter {display:inline-block;opacity:0;transform:translateX(-16px) rotate(-4deg);animation:rts-letter-in 0.5s cubic-bezier(0.16,1,0.3,1) both}
|
|
280
|
+
.rts-velvet-word {display:inline-block;opacity:0;animation:rts-velvet 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
281
|
+
.rts-curtain-word {display:inline-block;overflow:hidden;animation:rts-curtain 0.7s cubic-bezier(0.77,0,0.18,1) both}
|
|
282
|
+
.rts-ground-wrap {display:inline-block;overflow:hidden;vertical-align:bottom}
|
|
283
|
+
.rts-ground-inner {display:inline-block;animation:rts-ground 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
284
|
+
.rts-cascade-ch {display:inline-block;opacity:0;animation:rts-cascade 0.45s cubic-bezier(0.34,1.56,0.64,1) both}
|
|
285
|
+
.rts-ink-word {display:inline-block;opacity:0;animation:rts-ink 0.9s cubic-bezier(0.16,1,0.3,1) both}
|
|
286
|
+
.rts-hinge-word {display:inline-block;opacity:0;transform-origin:left center;animation:rts-hinge 0.6s cubic-bezier(0.16,1,0.3,1) both}
|
|
287
|
+
.rts-peel-word {display:inline-block;overflow:hidden;animation:rts-peel 0.6s cubic-bezier(0.77,0,0.18,1) both}
|
|
288
|
+
.rts-fold-word {display:inline-block;opacity:0;transform-origin:center bottom;animation:rts-fold 0.6s cubic-bezier(0.34,1.4,0.64,1) both}
|
|
289
|
+
.rts-shear-word {display:inline-block;opacity:0;animation:rts-shear 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
290
|
+
.rts-ripple-word {display:inline-block;opacity:0;animation:rts-ripple-w 0.75s cubic-bezier(0.34,1.4,0.64,1) both}
|
|
291
|
+
.rts-cinch-ch {display:inline-block;opacity:0;transform-origin:center;animation:rts-cinch 0.55s cubic-bezier(0.34,1.2,0.64,1) both}
|
|
292
|
+
.rts-tiltrise-word{display:inline-block;opacity:0;animation:rts-tiltrise 0.8s cubic-bezier(0.16,1,0.3,1) both}
|
|
293
|
+
.rts-cardflip-ch {display:inline-block;opacity:0;transform-origin:center bottom;animation:rts-cardflip 0.4s cubic-bezier(0.34,1.4,0.64,1) both}
|
|
294
|
+
.rts-conv-l {display:inline-block;opacity:0;animation:rts-conv-l 0.7s cubic-bezier(0.16,1,0.3,1) both}
|
|
295
|
+
.rts-conv-r {display:inline-block;opacity:0;animation:rts-conv-r 0.7s cubic-bezier(0.16,1,0.3,1) both}
|
|
296
|
+
.rts-splitrise-t {display:inline-block;opacity:0;animation:rts-splitrise-t 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
297
|
+
.rts-splitrise-b {display:inline-block;opacity:0;animation:rts-splitrise-b 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
298
|
+
|
|
299
|
+
/* ── Per-word / per-char spans (batch 3) ────────────────────────────────── */
|
|
300
|
+
.rts-tec-l {display:inline-block;opacity:0;animation:rts-tec-l 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
301
|
+
.rts-tec-r {display:inline-block;opacity:0;animation:rts-tec-r 0.65s cubic-bezier(0.16,1,0.3,1) both}
|
|
302
|
+
.rts-strat-word {display:inline-block;opacity:0;animation:rts-strat 0.85s cubic-bezier(0.16,1,0.3,1) both}
|
|
303
|
+
.rts-gwell-ch {display:inline-block;opacity:0;animation:rts-gwell 0.62s cubic-bezier(0.36,0.07,0.19,0.97) both}
|
|
304
|
+
.rts-orbit-word {display:inline-block;opacity:0;transform-origin:center;animation:rts-orbit 0.65s cubic-bezier(0.34,1.4,0.64,1) both}
|
|
305
|
+
.rts-liquid-word{display:inline-block;opacity:0;transform-origin:center bottom;animation:rts-liquid 0.72s cubic-bezier(0.34,1.56,0.64,1) both}
|
|
306
|
+
.rts-nf0 {display:inline-block;opacity:0;animation:rts-nf0 0.9s ease both}
|
|
307
|
+
.rts-nf1 {display:inline-block;opacity:0;animation:rts-nf1 0.9s ease both}
|
|
308
|
+
.rts-nf2 {display:inline-block;opacity:0;animation:rts-nf2 0.9s ease both}
|
|
309
|
+
.rts-slab-word {display:inline-block;opacity:0;transform-origin:left center;animation:rts-slab 0.5s cubic-bezier(0.77,0,0.18,1) both}
|
|
310
|
+
.rts-thread-ch {display:inline-block;opacity:0;animation:rts-thread 0.55s cubic-bezier(0.16,1,0.3,1) both}
|
|
311
|
+
|
|
312
|
+
/* ── Batch 7 — 8 genuinely new mechanics ────────────────────────────────── */
|
|
313
|
+
|
|
314
|
+
/* glassReveal — backdrop-filter blur evaporates as text solidifies */
|
|
315
|
+
@keyframes rts-glass {
|
|
316
|
+
0% { opacity:0; filter:blur(0px); backdrop-filter:blur(20px); transform:scale(1.03) }
|
|
317
|
+
35% { opacity:0.6; filter:blur(2px) }
|
|
318
|
+
100%{ opacity:1; filter:blur(0px); backdrop-filter:blur(0px); transform:scale(1) }
|
|
319
|
+
}
|
|
320
|
+
.rts-glass { animation:rts-glass 1.2s cubic-bezier(0.16,1,0.3,1) both }
|
|
321
|
+
|
|
322
|
+
/* wordPop — per-word springs from 0 at its own center, pure scale */
|
|
323
|
+
@keyframes rts-wpop {
|
|
324
|
+
0% { opacity:0; transform:scale(0) }
|
|
325
|
+
55% { opacity:1; transform:scale(1.08) }
|
|
326
|
+
75% { transform:scale(0.97) }
|
|
327
|
+
100%{ transform:scale(1) }
|
|
328
|
+
}
|
|
329
|
+
.rts-wpop-word { display:inline-block; opacity:0; animation:rts-wpop 0.55s cubic-bezier(0.34,1.56,0.64,1) both }
|
|
330
|
+
|
|
331
|
+
/* charDrop — pure gravity fall, no overshoot, no rotation */
|
|
332
|
+
@keyframes rts-cdrop {
|
|
333
|
+
0% { opacity:0; transform:translateY(-48px) }
|
|
334
|
+
100%{ opacity:1; transform:translateY(0) }
|
|
335
|
+
}
|
|
336
|
+
.rts-cdrop-ch { display:inline-block; opacity:0; animation:rts-cdrop 0.6s cubic-bezier(0.55,0,1,0.45) both }
|
|
337
|
+
|
|
338
|
+
/* scanline — single-pixel horizontal clip expands to full height */
|
|
339
|
+
@keyframes rts-scan {
|
|
340
|
+
0% { clip-path:inset(49% 0 49% 0); opacity:0 }
|
|
341
|
+
15% { opacity:1 }
|
|
342
|
+
100%{ clip-path:inset(0% 0 0% 0) }
|
|
343
|
+
}
|
|
344
|
+
.rts-scan { animation:rts-scan 0.9s cubic-bezier(0.77,0,0.18,1) both }
|
|
345
|
+
|
|
346
|
+
/* chromaShift — RGB channel offsets collapse to zero */
|
|
347
|
+
@keyframes rts-chroma {
|
|
348
|
+
0% { opacity:0; text-shadow: -8px 0 0 rgba(255,0,80,0.7), 8px 0 0 rgba(0,200,255,0.7) }
|
|
349
|
+
40% { opacity:1; text-shadow: -4px 0 0 rgba(255,0,80,0.35), 4px 0 0 rgba(0,200,255,0.35) }
|
|
350
|
+
100%{ text-shadow:none }
|
|
351
|
+
}
|
|
352
|
+
.rts-chroma { animation:rts-chroma 1s cubic-bezier(0.16,1,0.3,1) both }
|
|
353
|
+
|
|
354
|
+
/* wordFade — pure cross-dissolve with warmth scale, no Y movement */
|
|
355
|
+
@keyframes rts-wfade {
|
|
356
|
+
0% { opacity:0; transform:scale(0.97) }
|
|
357
|
+
100%{ opacity:1; transform:scale(1) }
|
|
358
|
+
}
|
|
359
|
+
.rts-wfade-word { display:inline-block; opacity:0; animation:rts-wfade 0.9s cubic-bezier(0.4,0,0.2,1) both }
|
|
360
|
+
|
|
361
|
+
/* rotateIn — full Y-axis card flip per word */
|
|
362
|
+
@keyframes rts-rotatein {
|
|
363
|
+
0% { opacity:0; transform:perspective(500px) rotateY(90deg) }
|
|
364
|
+
55% { opacity:1; transform:perspective(500px) rotateY(-8deg) }
|
|
365
|
+
100%{ transform:perspective(500px) rotateY(0deg) }
|
|
366
|
+
}
|
|
367
|
+
.rts-rotatein-word { display:inline-block; opacity:0; transform-origin:center; animation:rts-rotatein 0.6s cubic-bezier(0.34,1.4,0.64,1) both }
|
|
368
|
+
|
|
369
|
+
/* pressIn — presses down to 0.92 then springs outward past 1 */
|
|
370
|
+
@keyframes rts-pressin {
|
|
371
|
+
0% { opacity:0; transform:scale(0.5) }
|
|
372
|
+
30% { opacity:1; transform:scale(0.92) }
|
|
373
|
+
60% { transform:scale(1.06) }
|
|
374
|
+
80% { transform:scale(0.98) }
|
|
375
|
+
100%{ transform:scale(1) }
|
|
376
|
+
}
|
|
377
|
+
.rts-pressin-word { display:inline-block; opacity:0; animation:rts-pressin 0.65s cubic-bezier(0.34,1.56,0.64,1) both }
|
|
183
378
|
`;
|
|
184
379
|
function injectAnimationStyles() {
|
|
185
380
|
if (typeof document === "undefined")
|
|
@@ -191,7 +386,7 @@ function injectAnimationStyles() {
|
|
|
191
386
|
style.textContent = CSS;
|
|
192
387
|
document.head.appendChild(style);
|
|
193
388
|
}
|
|
194
|
-
// ─── Whole-element
|
|
389
|
+
// ─── Whole-element animation map ─────────────────────────────────────────────
|
|
195
390
|
const WHOLE_CLASS_MAP = {
|
|
196
391
|
rise: "rts-rise",
|
|
197
392
|
clip: "rts-clip",
|
|
@@ -204,35 +399,35 @@ const WHOLE_CLASS_MAP = {
|
|
|
204
399
|
morph: "rts-morph",
|
|
205
400
|
spotlight: "rts-spotlight",
|
|
206
401
|
stretch: "rts-stretch",
|
|
402
|
+
unfurl: "rts-unfurl",
|
|
403
|
+
billboard: "rts-billboard",
|
|
404
|
+
// Batch 7 — whole-element
|
|
405
|
+
glassReveal: "rts-glass",
|
|
406
|
+
scanline: "rts-scan",
|
|
407
|
+
chromaShift: "rts-chroma",
|
|
207
408
|
};
|
|
208
|
-
/** Returns the CSS class for whole-element animations, or "" for split ones. */
|
|
209
409
|
function getAnimationClass(animation) {
|
|
210
410
|
var _a;
|
|
211
411
|
return (_a = WHOLE_CLASS_MAP[animation]) !== null && _a !== void 0 ? _a : "";
|
|
212
412
|
}
|
|
213
|
-
/** True if the animation needs the HTML to be split into word/char spans. */
|
|
214
413
|
function isSplitAnimation(animation) {
|
|
215
414
|
return !(animation in WHOLE_CLASS_MAP);
|
|
216
415
|
}
|
|
217
|
-
// ─── HTML
|
|
218
|
-
function wrapWords(html, cls,
|
|
416
|
+
// ─── HTML split builders ──────────────────────────────────────────────────────
|
|
417
|
+
function wrapWords(html, cls, step) {
|
|
219
418
|
var _a;
|
|
220
419
|
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
221
|
-
return tokens
|
|
222
|
-
|
|
223
|
-
const delay = (i * delayStep).toFixed(2);
|
|
420
|
+
return tokens.map((tok, i) => {
|
|
421
|
+
const delay = (i * step).toFixed(2);
|
|
224
422
|
if (tok.startsWith("<em>")) {
|
|
225
423
|
return `<em><span class="${cls}" style="animation-delay:${delay}s">${tok.slice(4, -5)}</span></em>`;
|
|
226
424
|
}
|
|
227
425
|
return `<span class="${cls}" style="animation-delay:${delay}s">${tok}</span>`;
|
|
228
|
-
})
|
|
229
|
-
.join(" ");
|
|
426
|
+
}).join(" ");
|
|
230
427
|
}
|
|
231
|
-
function wrapChars(html, cls,
|
|
428
|
+
function wrapChars(html, cls, step) {
|
|
232
429
|
const result = [];
|
|
233
|
-
let inEm = false;
|
|
234
|
-
let delay = 0;
|
|
235
|
-
let i = 0;
|
|
430
|
+
let inEm = false, delay = 0, i = 0;
|
|
236
431
|
while (i < html.length) {
|
|
237
432
|
if (html.startsWith("<em>", i)) {
|
|
238
433
|
inEm = true;
|
|
@@ -252,28 +447,96 @@ function wrapChars(html, cls, delayStep) {
|
|
|
252
447
|
}
|
|
253
448
|
const span = `<span class="${cls}" style="animation-delay:${delay.toFixed(2)}s">${ch}</span>`;
|
|
254
449
|
result.push(inEm ? `<em>${span}</em>` : span);
|
|
255
|
-
delay +=
|
|
450
|
+
delay += step;
|
|
256
451
|
i++;
|
|
257
452
|
}
|
|
258
453
|
return result.join("");
|
|
259
454
|
}
|
|
260
|
-
function wrapGround(html,
|
|
455
|
+
function wrapGround(html, step) {
|
|
261
456
|
var _a;
|
|
262
457
|
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
263
|
-
return tokens
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
const inner = tok.startsWith("<em>")
|
|
267
|
-
? `<em>${tok.slice(4, -5)}</em>`
|
|
268
|
-
: tok;
|
|
458
|
+
return tokens.map((tok, i) => {
|
|
459
|
+
const delay = (i * step).toFixed(2);
|
|
460
|
+
const inner = tok.startsWith("<em>") ? `<em>${tok.slice(4, -5)}</em>` : tok;
|
|
269
461
|
return `<span class="rts-ground-wrap"><span class="rts-ground-inner" style="animation-delay:${delay}s">${inner}</span></span>`;
|
|
270
|
-
})
|
|
271
|
-
|
|
462
|
+
}).join(" ");
|
|
463
|
+
}
|
|
464
|
+
function wrapTectonic(html) {
|
|
465
|
+
var _a;
|
|
466
|
+
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
467
|
+
return tokens.map((tok, i) => {
|
|
468
|
+
const cls = i % 2 === 0 ? "rts-tec-l" : "rts-tec-r";
|
|
469
|
+
const delay = (i * 0.09).toFixed(2);
|
|
470
|
+
if (tok.startsWith("<em>")) {
|
|
471
|
+
return `<em><span class="${cls}" style="animation-delay:${delay}s">${tok.slice(4, -5)}</span></em>`;
|
|
472
|
+
}
|
|
473
|
+
return `<span class="${cls}" style="animation-delay:${delay}s">${tok}</span>`;
|
|
474
|
+
}).join(" ");
|
|
475
|
+
}
|
|
476
|
+
function wrapNoiseFade(html) {
|
|
477
|
+
var _a;
|
|
478
|
+
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
479
|
+
return tokens.map((tok, i) => {
|
|
480
|
+
const cls = `rts-nf${i % 3}`;
|
|
481
|
+
const delay = (i * 0.12).toFixed(2);
|
|
482
|
+
if (tok.startsWith("<em>")) {
|
|
483
|
+
return `<em><span class="${cls}" style="animation-delay:${delay}s">${tok.slice(4, -5)}</span></em>`;
|
|
484
|
+
}
|
|
485
|
+
return `<span class="${cls}" style="animation-delay:${delay}s">${tok}</span>`;
|
|
486
|
+
}).join(" ");
|
|
487
|
+
}
|
|
488
|
+
function wrapConverge(html) {
|
|
489
|
+
var _a;
|
|
490
|
+
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
491
|
+
const mid = Math.ceil(tokens.length / 2);
|
|
492
|
+
return tokens.map((tok, i) => {
|
|
493
|
+
const isLeft = i < mid;
|
|
494
|
+
const dist = isLeft ? mid - 1 - i : i - mid;
|
|
495
|
+
const delay = (dist * 0.07).toFixed(2);
|
|
496
|
+
const cls = isLeft ? "rts-conv-l" : "rts-conv-r";
|
|
497
|
+
const inner = tok.startsWith("<em>") ? `<em>${tok.slice(4, -5)}</em>` : tok;
|
|
498
|
+
return `<span class="${cls}" style="animation-delay:${delay}s">${inner}</span>`;
|
|
499
|
+
}).join(" ");
|
|
500
|
+
}
|
|
501
|
+
function wrapRipple(html) {
|
|
502
|
+
var _a;
|
|
503
|
+
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
504
|
+
const mid = Math.floor(tokens.length / 2);
|
|
505
|
+
return tokens.map((tok, i) => {
|
|
506
|
+
const delay = (Math.abs(i - mid) * 0.1).toFixed(2);
|
|
507
|
+
if (tok.startsWith("<em>")) {
|
|
508
|
+
return `<em><span class="rts-ripple-word" style="animation-delay:${delay}s">${tok.slice(4, -5)}</span></em>`;
|
|
509
|
+
}
|
|
510
|
+
return `<span class="rts-ripple-word" style="animation-delay:${delay}s">${tok}</span>`;
|
|
511
|
+
}).join(" ");
|
|
512
|
+
}
|
|
513
|
+
function wrapSplitRise(html) {
|
|
514
|
+
var _a;
|
|
515
|
+
const tokens = (_a = html.match(/(<em>[\s\S]*?<\/em>|[^\s]+)/g)) !== null && _a !== void 0 ? _a : [];
|
|
516
|
+
return tokens.map((tok, i) => {
|
|
517
|
+
const cls = i % 2 === 0 ? "rts-splitrise-t" : "rts-splitrise-b";
|
|
518
|
+
const delay = (i * 0.08).toFixed(2);
|
|
519
|
+
if (tok.startsWith("<em>")) {
|
|
520
|
+
return `<em><span class="${cls}" style="animation-delay:${delay}s">${tok.slice(4, -5)}</span></em>`;
|
|
521
|
+
}
|
|
522
|
+
return `<span class="${cls}" style="animation-delay:${delay}s">${tok}</span>`;
|
|
523
|
+
}).join(" ");
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Thread: each char gets a sine-wave Y offset injected as a CSS custom
|
|
527
|
+
* property --ty so the keyframe can read it. Must be post-processed by
|
|
528
|
+
* Typography after innerHTML is set — see applyThreadOffsets().
|
|
529
|
+
*/
|
|
530
|
+
function wrapThread(html) {
|
|
531
|
+
return wrapChars(html, "rts-thread-ch", 0.04);
|
|
272
532
|
}
|
|
533
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
273
534
|
function buildSplitHTML(animation, html) {
|
|
274
535
|
switch (animation) {
|
|
536
|
+
// Batch 1
|
|
275
537
|
case "stagger": return wrapWords(html, "rts-word", 0.07);
|
|
276
538
|
case "letters": return wrapChars(html, "rts-letter", 0.04);
|
|
539
|
+
// Batch 2
|
|
277
540
|
case "velvet": return wrapWords(html, "rts-velvet-word", 0.08);
|
|
278
541
|
case "curtain": return wrapWords(html, "rts-curtain-word", 0.10);
|
|
279
542
|
case "ground": return wrapGround(html, 0.09);
|
|
@@ -281,6 +544,29 @@ function buildSplitHTML(animation, html) {
|
|
|
281
544
|
case "ink": return wrapWords(html, "rts-ink-word", 0.10);
|
|
282
545
|
case "hinge": return wrapWords(html, "rts-hinge-word", 0.09);
|
|
283
546
|
case "peel": return wrapWords(html, "rts-peel-word", 0.10);
|
|
547
|
+
case "fold": return wrapWords(html, "rts-fold-word", 0.09);
|
|
548
|
+
case "shear": return wrapWords(html, "rts-shear-word", 0.08);
|
|
549
|
+
case "ripple": return wrapRipple(html);
|
|
550
|
+
case "cinch": return wrapChars(html, "rts-cinch-ch", 0.048);
|
|
551
|
+
case "tiltrise": return wrapWords(html, "rts-tiltrise-word", 0.09);
|
|
552
|
+
case "cardFlip": return wrapChars(html, "rts-cardflip-ch", 0.045);
|
|
553
|
+
case "converge": return wrapConverge(html);
|
|
554
|
+
case "splitRise": return wrapSplitRise(html);
|
|
555
|
+
// Batch 3
|
|
556
|
+
case "tectonic": return wrapTectonic(html);
|
|
557
|
+
case "stratify": return wrapWords(html, "rts-strat-word", 0.10);
|
|
558
|
+
case "gravityWell": return wrapChars(html, "rts-gwell-ch", 0.05);
|
|
559
|
+
case "orbit": return wrapWords(html, "rts-orbit-word", 0.10);
|
|
560
|
+
case "liquid": return wrapWords(html, "rts-liquid-word", 0.09);
|
|
561
|
+
case "noiseFade": return wrapNoiseFade(html);
|
|
562
|
+
case "slab": return wrapWords(html, "rts-slab-word", 0.11);
|
|
563
|
+
case "thread": return wrapThread(html);
|
|
564
|
+
// Batch 7 — split
|
|
565
|
+
case "wordPop": return wrapWords(html, "rts-wpop-word", 0.07);
|
|
566
|
+
case "charDrop": return wrapChars(html, "rts-cdrop-ch", 0.04);
|
|
567
|
+
case "wordFade": return wrapWords(html, "rts-wfade-word", 0.09);
|
|
568
|
+
case "rotateIn": return wrapWords(html, "rts-rotatein-word", 0.08);
|
|
569
|
+
case "pressIn": return wrapWords(html, "rts-pressin-word", 0.08);
|
|
284
570
|
default: return html;
|
|
285
571
|
}
|
|
286
572
|
}
|