@hortonstudio/main 1.4.4 → 1.4.5
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/animations/text.js +202 -316
- package/index.js +1 -1
- package/package.json +1 -1
package/animations/text.js
CHANGED
@@ -106,28 +106,10 @@ async function waitForFonts() {
|
|
106
106
|
}
|
107
107
|
|
108
108
|
function findTextElement(container) {
|
109
|
-
//
|
110
|
-
//
|
111
|
-
const
|
112
|
-
|
113
|
-
return directTextElement;
|
114
|
-
}
|
115
|
-
|
116
|
-
// Fallback: check if container itself has text
|
117
|
-
if (container.textContent.trim()) {
|
118
|
-
return container;
|
119
|
-
}
|
120
|
-
|
121
|
-
// Last resort: find any element with text content
|
122
|
-
const textElements = container.querySelectorAll('*');
|
123
|
-
for (let i = 0; i < textElements.length; i++) {
|
124
|
-
const el = textElements[i];
|
125
|
-
if (el.textContent.trim() && !el.querySelector('*')) {
|
126
|
-
return el;
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
return container;
|
109
|
+
// Simple direct approach: if container has direct text content, use it
|
110
|
+
// Otherwise use first child with text content
|
111
|
+
const firstChild = container.firstElementChild;
|
112
|
+
return firstChild && firstChild.textContent.trim() ? firstChild : container;
|
131
113
|
}
|
132
114
|
|
133
115
|
function showElementsWithoutAnimation() {
|
@@ -163,56 +145,21 @@ const CharSplitAnimations = {
|
|
163
145
|
|
164
146
|
const elements = document.querySelectorAll('[data-hs-anim="char"]');
|
165
147
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
for (let i = index; i < endIndex; i++) {
|
175
|
-
const container = elements[i];
|
176
|
-
|
177
|
-
// Skip if already processed
|
178
|
-
if (container.hasAttribute('data-split-processed')) continue;
|
179
|
-
|
180
|
-
const textElement = findTextElement(container);
|
181
|
-
if (!textElement) continue;
|
182
|
-
|
183
|
-
try {
|
184
|
-
const split = SplitText.create(textElement, {
|
185
|
-
type: "words,chars",
|
186
|
-
mask: "chars",
|
187
|
-
charsClass: "char",
|
188
|
-
});
|
189
|
-
container.splitTextInstance = split;
|
190
|
-
container.setAttribute('data-split-processed', 'true');
|
191
|
-
|
192
|
-
gsap.set(split.chars, {
|
193
|
-
yPercent: config.charSplit.yPercent,
|
194
|
-
});
|
195
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
196
|
-
} catch (error) {
|
197
|
-
console.warn("Error creating char split:", error);
|
198
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
199
|
-
}
|
200
|
-
}
|
201
|
-
|
202
|
-
index = endIndex;
|
203
|
-
|
204
|
-
if (index < elements.length) {
|
205
|
-
requestAnimationFrame(processBatch);
|
206
|
-
} else {
|
207
|
-
resolve();
|
208
|
-
}
|
209
|
-
};
|
210
|
-
|
211
|
-
processBatch();
|
148
|
+
elements.forEach((container) => {
|
149
|
+
const textElement = findTextElement(container);
|
150
|
+
|
151
|
+
const split = SplitText.create(textElement, {
|
152
|
+
type: "words,chars",
|
153
|
+
mask: "chars",
|
154
|
+
charsClass: "char",
|
212
155
|
});
|
213
|
-
|
156
|
+
container.splitTextInstance = split;
|
214
157
|
|
215
|
-
|
158
|
+
gsap.set(split.chars, {
|
159
|
+
yPercent: config.charSplit.yPercent,
|
160
|
+
});
|
161
|
+
gsap.set(textElement, { autoAlpha: 1 });
|
162
|
+
});
|
216
163
|
},
|
217
164
|
|
218
165
|
async animate() {
|
@@ -222,48 +169,35 @@ const CharSplitAnimations = {
|
|
222
169
|
return;
|
223
170
|
}
|
224
171
|
|
225
|
-
// Safari optimization: Cache elements and reduce DOM queries
|
226
172
|
const elements = document.querySelectorAll('[data-hs-anim="char"]');
|
227
173
|
|
228
174
|
elements.forEach((container) => {
|
229
|
-
const
|
230
|
-
if (!textElement) return;
|
175
|
+
const chars = container.querySelectorAll(".char");
|
231
176
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
tl.to(chars, {
|
257
|
-
yPercent: 0,
|
258
|
-
duration: config.charSplit.duration,
|
259
|
-
stagger: config.charSplit.stagger,
|
260
|
-
ease: config.charSplit.ease,
|
261
|
-
});
|
262
|
-
|
263
|
-
activeAnimations.push({ timeline: tl, element: textElement });
|
264
|
-
} catch (error) {
|
265
|
-
console.warn("Error animating char split:", error);
|
266
|
-
}
|
177
|
+
const tl = gsap.timeline({
|
178
|
+
scrollTrigger: {
|
179
|
+
trigger: container,
|
180
|
+
start: config.charSplit.start,
|
181
|
+
invalidateOnRefresh: true,
|
182
|
+
toggleActions: "play none none none",
|
183
|
+
once: true,
|
184
|
+
},
|
185
|
+
onComplete: () => {
|
186
|
+
if (container.splitTextInstance) {
|
187
|
+
container.splitTextInstance.revert();
|
188
|
+
delete container.splitTextInstance;
|
189
|
+
}
|
190
|
+
},
|
191
|
+
});
|
192
|
+
|
193
|
+
tl.to(chars, {
|
194
|
+
yPercent: 0,
|
195
|
+
duration: config.charSplit.duration,
|
196
|
+
stagger: config.charSplit.stagger,
|
197
|
+
ease: config.charSplit.ease,
|
198
|
+
});
|
199
|
+
|
200
|
+
activeAnimations.push({ timeline: tl, element: container });
|
267
201
|
});
|
268
202
|
},
|
269
203
|
};
|
@@ -279,28 +213,19 @@ const WordSplitAnimations = {
|
|
279
213
|
const elements = document.querySelectorAll('[data-hs-anim="word"]');
|
280
214
|
|
281
215
|
elements.forEach((container) => {
|
282
|
-
// Skip if already processed
|
283
|
-
if (container.hasAttribute('data-split-processed')) return;
|
284
|
-
|
285
216
|
const textElement = findTextElement(container);
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
});
|
299
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
300
|
-
} catch (error) {
|
301
|
-
console.warn("Error creating word split:", error);
|
302
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
303
|
-
}
|
217
|
+
|
218
|
+
const split = SplitText.create(textElement, {
|
219
|
+
type: "words",
|
220
|
+
mask: "words",
|
221
|
+
wordsClass: "word",
|
222
|
+
});
|
223
|
+
container.splitTextInstance = split;
|
224
|
+
|
225
|
+
gsap.set(split.words, {
|
226
|
+
yPercent: config.wordSplit.yPercent,
|
227
|
+
});
|
228
|
+
gsap.set(textElement, { autoAlpha: 1 });
|
304
229
|
});
|
305
230
|
},
|
306
231
|
|
@@ -311,42 +236,36 @@ const WordSplitAnimations = {
|
|
311
236
|
return;
|
312
237
|
}
|
313
238
|
|
314
|
-
document
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
container.removeAttribute('data-split-processed');
|
334
|
-
}
|
335
|
-
},
|
336
|
-
});
|
337
|
-
|
338
|
-
tl.to(words, {
|
339
|
-
yPercent: 0,
|
340
|
-
duration: config.wordSplit.duration,
|
341
|
-
stagger: config.wordSplit.stagger,
|
342
|
-
ease: config.wordSplit.ease,
|
343
|
-
});
|
344
|
-
|
345
|
-
activeAnimations.push({ timeline: tl, element: textElement });
|
346
|
-
} catch (error) {
|
347
|
-
console.warn("Error animating word split:", error);
|
348
|
-
}
|
239
|
+
const elements = document.querySelectorAll('[data-hs-anim="word"]');
|
240
|
+
|
241
|
+
elements.forEach((container) => {
|
242
|
+
const words = container.querySelectorAll(".word");
|
243
|
+
|
244
|
+
const tl = gsap.timeline({
|
245
|
+
scrollTrigger: {
|
246
|
+
trigger: container,
|
247
|
+
start: config.wordSplit.start,
|
248
|
+
invalidateOnRefresh: true,
|
249
|
+
toggleActions: "play none none none",
|
250
|
+
once: true,
|
251
|
+
},
|
252
|
+
onComplete: () => {
|
253
|
+
if (container.splitTextInstance) {
|
254
|
+
container.splitTextInstance.revert();
|
255
|
+
delete container.splitTextInstance;
|
256
|
+
}
|
257
|
+
},
|
349
258
|
});
|
259
|
+
|
260
|
+
tl.to(words, {
|
261
|
+
yPercent: 0,
|
262
|
+
duration: config.wordSplit.duration,
|
263
|
+
stagger: config.wordSplit.stagger,
|
264
|
+
ease: config.wordSplit.ease,
|
265
|
+
});
|
266
|
+
|
267
|
+
activeAnimations.push({ timeline: tl, element: container });
|
268
|
+
});
|
350
269
|
},
|
351
270
|
};
|
352
271
|
|
@@ -361,28 +280,19 @@ const LineSplitAnimations = {
|
|
361
280
|
const elements = document.querySelectorAll('[data-hs-anim="line"]');
|
362
281
|
|
363
282
|
elements.forEach((container) => {
|
364
|
-
// Skip if already processed
|
365
|
-
if (container.hasAttribute('data-split-processed')) return;
|
366
|
-
|
367
283
|
const textElement = findTextElement(container);
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
});
|
381
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
382
|
-
} catch (error) {
|
383
|
-
console.warn("Error creating line split:", error);
|
384
|
-
gsap.set(textElement, { autoAlpha: 1 });
|
385
|
-
}
|
284
|
+
|
285
|
+
const split = SplitText.create(textElement, {
|
286
|
+
type: "lines",
|
287
|
+
mask: "lines",
|
288
|
+
linesClass: "line",
|
289
|
+
});
|
290
|
+
container.splitTextInstance = split;
|
291
|
+
|
292
|
+
gsap.set(split.lines, {
|
293
|
+
yPercent: config.lineSplit.yPercent,
|
294
|
+
});
|
295
|
+
gsap.set(textElement, { autoAlpha: 1 });
|
386
296
|
});
|
387
297
|
},
|
388
298
|
|
@@ -393,42 +303,36 @@ const LineSplitAnimations = {
|
|
393
303
|
return;
|
394
304
|
}
|
395
305
|
|
396
|
-
document
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
duration: config.lineSplit.duration,
|
423
|
-
stagger: config.lineSplit.stagger,
|
424
|
-
ease: config.lineSplit.ease,
|
425
|
-
});
|
426
|
-
|
427
|
-
activeAnimations.push({ timeline: tl, element: textElement });
|
428
|
-
} catch (error) {
|
429
|
-
console.warn("Error animating line split:", error);
|
430
|
-
}
|
306
|
+
const elements = document.querySelectorAll('[data-hs-anim="line"]');
|
307
|
+
|
308
|
+
elements.forEach((container) => {
|
309
|
+
const lines = container.querySelectorAll(".line");
|
310
|
+
|
311
|
+
const tl = gsap.timeline({
|
312
|
+
scrollTrigger: {
|
313
|
+
trigger: container,
|
314
|
+
start: config.lineSplit.start,
|
315
|
+
invalidateOnRefresh: true,
|
316
|
+
toggleActions: "play none none none",
|
317
|
+
once: true,
|
318
|
+
},
|
319
|
+
onComplete: () => {
|
320
|
+
if (container.splitTextInstance) {
|
321
|
+
container.splitTextInstance.revert();
|
322
|
+
delete container.splitTextInstance;
|
323
|
+
}
|
324
|
+
},
|
325
|
+
});
|
326
|
+
|
327
|
+
tl.to(lines, {
|
328
|
+
yPercent: 0,
|
329
|
+
duration: config.lineSplit.duration,
|
330
|
+
stagger: config.lineSplit.stagger,
|
331
|
+
ease: config.lineSplit.ease,
|
431
332
|
});
|
333
|
+
|
334
|
+
activeAnimations.push({ timeline: tl, element: container });
|
335
|
+
});
|
432
336
|
},
|
433
337
|
};
|
434
338
|
|
@@ -442,14 +346,10 @@ const AppearAnimations = {
|
|
442
346
|
|
443
347
|
const elements = document.querySelectorAll('[data-hs-anim="appear"]');
|
444
348
|
elements.forEach((element) => {
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
});
|
450
|
-
} catch (error) {
|
451
|
-
console.warn("Error setting appear initial state:", error);
|
452
|
-
}
|
349
|
+
gsap.set(element, {
|
350
|
+
y: config.appear.y,
|
351
|
+
opacity: 0,
|
352
|
+
});
|
453
353
|
});
|
454
354
|
},
|
455
355
|
|
@@ -460,29 +360,27 @@ const AppearAnimations = {
|
|
460
360
|
return;
|
461
361
|
}
|
462
362
|
|
463
|
-
document.querySelectorAll('[data-hs-anim="appear"]')
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
}
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
console.warn("Error animating appear:", error);
|
485
|
-
}
|
363
|
+
const elements = document.querySelectorAll('[data-hs-anim="appear"]');
|
364
|
+
|
365
|
+
elements.forEach((element) => {
|
366
|
+
const tl = gsap.timeline({
|
367
|
+
scrollTrigger: {
|
368
|
+
trigger: element,
|
369
|
+
start: config.appear.start,
|
370
|
+
invalidateOnRefresh: true,
|
371
|
+
toggleActions: "play none none none",
|
372
|
+
once: true,
|
373
|
+
},
|
374
|
+
});
|
375
|
+
|
376
|
+
tl.to(element, {
|
377
|
+
y: 0,
|
378
|
+
opacity: 1,
|
379
|
+
duration: config.appear.duration,
|
380
|
+
ease: config.appear.ease,
|
381
|
+
});
|
382
|
+
|
383
|
+
activeAnimations.push({ timeline: tl, element: element });
|
486
384
|
});
|
487
385
|
},
|
488
386
|
};
|
@@ -497,14 +395,10 @@ const RevealAnimations = {
|
|
497
395
|
|
498
396
|
const elements = document.querySelectorAll('[data-hs-anim="reveal"]');
|
499
397
|
elements.forEach((element) => {
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
});
|
505
|
-
} catch (error) {
|
506
|
-
console.warn("Error setting reveal initial state:", error);
|
507
|
-
}
|
398
|
+
gsap.set(element, {
|
399
|
+
y: config.reveal.y,
|
400
|
+
opacity: 0,
|
401
|
+
});
|
508
402
|
});
|
509
403
|
},
|
510
404
|
|
@@ -515,29 +409,27 @@ const RevealAnimations = {
|
|
515
409
|
return;
|
516
410
|
}
|
517
411
|
|
518
|
-
document.querySelectorAll('[data-hs-anim="reveal"]')
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
}
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
console.warn("Error animating reveal:", error);
|
540
|
-
}
|
412
|
+
const elements = document.querySelectorAll('[data-hs-anim="reveal"]');
|
413
|
+
|
414
|
+
elements.forEach((element) => {
|
415
|
+
const tl = gsap.timeline({
|
416
|
+
scrollTrigger: {
|
417
|
+
trigger: element,
|
418
|
+
start: config.reveal.start,
|
419
|
+
invalidateOnRefresh: true,
|
420
|
+
toggleActions: "play none none none",
|
421
|
+
once: true,
|
422
|
+
},
|
423
|
+
});
|
424
|
+
|
425
|
+
tl.to(element, {
|
426
|
+
y: 0,
|
427
|
+
opacity: 1,
|
428
|
+
duration: config.reveal.duration,
|
429
|
+
ease: config.reveal.ease,
|
430
|
+
});
|
431
|
+
|
432
|
+
activeAnimations.push({ timeline: tl, element: element });
|
541
433
|
});
|
542
434
|
},
|
543
435
|
};
|
@@ -552,15 +444,11 @@ const GroupAnimations = {
|
|
552
444
|
|
553
445
|
const elements = document.querySelectorAll('[data-hs-anim="group"]');
|
554
446
|
elements.forEach((element) => {
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
});
|
561
|
-
} catch (error) {
|
562
|
-
console.warn("Error setting group initial state:", error);
|
563
|
-
}
|
447
|
+
const children = Array.from(element.children);
|
448
|
+
gsap.set(children, {
|
449
|
+
y: config.appear.y,
|
450
|
+
opacity: 0,
|
451
|
+
});
|
564
452
|
});
|
565
453
|
},
|
566
454
|
|
@@ -571,31 +459,29 @@ const GroupAnimations = {
|
|
571
459
|
return;
|
572
460
|
}
|
573
461
|
|
574
|
-
document.querySelectorAll('[data-hs-anim="group"]')
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
}
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
console.warn("Error animating group:", error);
|
598
|
-
}
|
462
|
+
const elements = document.querySelectorAll('[data-hs-anim="group"]');
|
463
|
+
|
464
|
+
elements.forEach((element) => {
|
465
|
+
const children = Array.from(element.children);
|
466
|
+
const tl = gsap.timeline({
|
467
|
+
scrollTrigger: {
|
468
|
+
trigger: element,
|
469
|
+
start: config.appear.start,
|
470
|
+
invalidateOnRefresh: true,
|
471
|
+
toggleActions: "play none none none",
|
472
|
+
once: true,
|
473
|
+
},
|
474
|
+
});
|
475
|
+
|
476
|
+
tl.to(children, {
|
477
|
+
y: 0,
|
478
|
+
opacity: 1,
|
479
|
+
duration: config.appear.duration,
|
480
|
+
ease: config.appear.ease,
|
481
|
+
stagger: 0.1,
|
482
|
+
});
|
483
|
+
|
484
|
+
activeAnimations.push({ timeline: tl, element: element });
|
599
485
|
});
|
600
486
|
},
|
601
487
|
};
|
package/index.js
CHANGED