@hortonstudio/main 1.2.24 → 1.2.26
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/.claude/settings.local.json +3 -1
- package/animations/hero.js +78 -43
- package/animations/text.js +26 -33
- package/configure-example.js +32 -0
- package/index.js +1 -7
- package/package.json +1 -1
package/animations/hero.js
CHANGED
|
@@ -174,45 +174,18 @@ export async function init() {
|
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
// Check if there's a persistent config stored globally
|
|
178
|
-
const api = window[API_NAME] || {};
|
|
179
|
-
console.log('🔄 Hero animations init - full API object:', api);
|
|
180
|
-
console.log('🔄 Hero animations init - _persistentConfigs:', api._persistentConfigs);
|
|
181
|
-
console.log('🔄 Hero animations init - checking persistent config:', api._persistentConfigs?.heroAnimations);
|
|
182
|
-
|
|
183
|
-
// Ensure _persistentConfigs exists
|
|
184
|
-
if (!api._persistentConfigs) {
|
|
185
|
-
api._persistentConfigs = {};
|
|
186
|
-
console.log('🏗️ Hero animations - created _persistentConfigs object');
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (api._persistentConfigs?.heroAnimations) {
|
|
190
|
-
console.log('📝 Hero animations - applying persistent config:', api._persistentConfigs.heroAnimations);
|
|
191
|
-
// Merge persistent config into current config
|
|
192
|
-
updateConfig(api._persistentConfigs.heroAnimations);
|
|
193
|
-
console.log('✅ Hero animations - config after merge:', config);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
177
|
if (prefersReducedMotion()) {
|
|
197
178
|
// For reduced motion, just show elements without animation
|
|
198
179
|
showHeroElementsWithoutAnimation();
|
|
199
180
|
|
|
200
181
|
// Still expose the API for consistency
|
|
201
|
-
|
|
182
|
+
window[API_NAME] = window[API_NAME] || {};
|
|
183
|
+
window[API_NAME].heroAnimations = {
|
|
202
184
|
config: config,
|
|
203
|
-
updateConfig:
|
|
204
|
-
console.log('🔧 Hero animations - updateConfig called with:', newConfig);
|
|
205
|
-
updateConfig(newConfig);
|
|
206
|
-
// Store config in persistent storage for restart persistence
|
|
207
|
-
api._persistentConfigs = api._persistentConfigs || {};
|
|
208
|
-
api._persistentConfigs.heroAnimations = { ...config };
|
|
209
|
-
console.log('💾 Hero animations - stored persistent config:', api._persistentConfigs.heroAnimations);
|
|
210
|
-
console.log('💾 Hero animations - full _persistentConfigs after store:', api._persistentConfigs);
|
|
211
|
-
},
|
|
185
|
+
updateConfig: updateConfig,
|
|
212
186
|
start: startHeroAnimations,
|
|
213
187
|
kill: killHeroAnimations,
|
|
214
188
|
restart: () => {
|
|
215
|
-
console.log('🔄 Hero animations - restart called');
|
|
216
189
|
killHeroAnimations();
|
|
217
190
|
startHeroAnimations();
|
|
218
191
|
}
|
|
@@ -270,7 +243,7 @@ export async function init() {
|
|
|
270
243
|
headingElements.forEach(el => {
|
|
271
244
|
if (el.firstElementChild) {
|
|
272
245
|
// Get the heroconfig attribute to determine animation type
|
|
273
|
-
const heroConfig = el.getAttribute('data-hs-heroconfig') || '
|
|
246
|
+
const heroConfig = el.getAttribute('data-hs-heroconfig') || 'line'; // default to line if not specified
|
|
274
247
|
|
|
275
248
|
if (heroConfig === 'appear') {
|
|
276
249
|
headingAppearElements.push(el.firstElementChild);
|
|
@@ -346,7 +319,7 @@ export async function init() {
|
|
|
346
319
|
if (heading.length > 0) {
|
|
347
320
|
headingSplitElements.forEach((parent, index) => {
|
|
348
321
|
const textElement = heading[index];
|
|
349
|
-
const splitType = parent.getAttribute('data-hs-heroconfig') || '
|
|
322
|
+
const splitType = parent.getAttribute('data-hs-heroconfig') || 'line';
|
|
350
323
|
|
|
351
324
|
let splitConfig = {};
|
|
352
325
|
let elementsClass = '';
|
|
@@ -610,25 +583,87 @@ export async function init() {
|
|
|
610
583
|
});
|
|
611
584
|
|
|
612
585
|
// API exposure
|
|
613
|
-
|
|
586
|
+
window[API_NAME] = window[API_NAME] || {};
|
|
587
|
+
window[API_NAME].heroAnimations = {
|
|
614
588
|
config: config,
|
|
615
|
-
updateConfig:
|
|
616
|
-
console.log('🔧 Hero animations - updateConfig called with:', newConfig);
|
|
617
|
-
updateConfig(newConfig);
|
|
618
|
-
// Store config in persistent storage for restart persistence
|
|
619
|
-
api._persistentConfigs = api._persistentConfigs || {};
|
|
620
|
-
api._persistentConfigs.heroAnimations = { ...config };
|
|
621
|
-
console.log('💾 Hero animations - stored persistent config:', api._persistentConfigs.heroAnimations);
|
|
622
|
-
console.log('💾 Hero animations - full _persistentConfigs after store:', api._persistentConfigs);
|
|
623
|
-
},
|
|
589
|
+
updateConfig: updateConfig,
|
|
624
590
|
start: startHeroAnimations,
|
|
625
591
|
kill: killHeroAnimations,
|
|
626
592
|
restart: () => {
|
|
627
|
-
console.log('🔄 Hero animations - restart called');
|
|
628
593
|
killHeroAnimations();
|
|
629
594
|
startHeroAnimations();
|
|
630
595
|
}
|
|
631
596
|
};
|
|
632
597
|
|
|
598
|
+
// Add resize listener for responsive line splits
|
|
599
|
+
let heroResizeTimeout;
|
|
600
|
+
window.addEventListener('resize', () => {
|
|
601
|
+
clearTimeout(heroResizeTimeout);
|
|
602
|
+
heroResizeTimeout = setTimeout(() => {
|
|
603
|
+
// Only refresh line splits, not chars or words
|
|
604
|
+
const hasLineSplits = headingSplits.some(split => split.elementsClass === 'lines') ||
|
|
605
|
+
subheadingSplits.some(split => split.elementsClass === 'lines');
|
|
606
|
+
|
|
607
|
+
if (hasLineSplits) {
|
|
608
|
+
// Kill current line splits
|
|
609
|
+
headingSplits.forEach((split, index) => {
|
|
610
|
+
if (split.elementsClass === 'lines' && split.revert) {
|
|
611
|
+
split.revert();
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
subheadingSplits.forEach((split, index) => {
|
|
616
|
+
if (split.elementsClass === 'lines' && split.revert) {
|
|
617
|
+
split.revert();
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// Re-initialize line splits after resize
|
|
622
|
+
document.fonts.ready.then(() => {
|
|
623
|
+
// Re-split line elements
|
|
624
|
+
headingSplitElements.forEach((parent, index) => {
|
|
625
|
+
const textElement = heading[index];
|
|
626
|
+
const splitType = parent.getAttribute('data-hs-heroconfig') || 'line';
|
|
627
|
+
|
|
628
|
+
if (splitType === 'line') {
|
|
629
|
+
const splitConfig = {
|
|
630
|
+
type: "lines",
|
|
631
|
+
mask: "lines",
|
|
632
|
+
linesClass: "line"
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
const split = new SplitText(textElement, splitConfig);
|
|
636
|
+
split.elementsClass = 'lines';
|
|
637
|
+
headingSplits[index] = split;
|
|
638
|
+
|
|
639
|
+
gsap.set(split.lines, { yPercent: 0 });
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
subheadingSplitElements.forEach((parent, index) => {
|
|
644
|
+
const textElement = subheading[index];
|
|
645
|
+
const splitType = parent.getAttribute('data-hs-heroconfig') || 'word';
|
|
646
|
+
|
|
647
|
+
if (splitType === 'line') {
|
|
648
|
+
const splitConfig = {
|
|
649
|
+
type: "lines",
|
|
650
|
+
mask: "lines",
|
|
651
|
+
linesClass: "line"
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
const split = new SplitText(textElement, splitConfig);
|
|
655
|
+
split.elementsClass = 'lines';
|
|
656
|
+
subheadingSplits[index] = split;
|
|
657
|
+
|
|
658
|
+
gsap.set(split.lines, { yPercent: 0 });
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
ScrollTrigger.refresh();
|
|
665
|
+
}, 100);
|
|
666
|
+
});
|
|
667
|
+
|
|
633
668
|
return { result: 'anim-hero initialized' };
|
|
634
669
|
}
|
package/animations/text.js
CHANGED
|
@@ -11,7 +11,7 @@ const config = {
|
|
|
11
11
|
},
|
|
12
12
|
wordSplit: {
|
|
13
13
|
duration: 1.5,
|
|
14
|
-
stagger: 0.
|
|
14
|
+
stagger: 0.05,
|
|
15
15
|
yPercent: 110,
|
|
16
16
|
ease: "power4.out",
|
|
17
17
|
start: "top 97%"
|
|
@@ -25,7 +25,7 @@ const config = {
|
|
|
25
25
|
},
|
|
26
26
|
charSplit: {
|
|
27
27
|
duration: 1.2,
|
|
28
|
-
stagger: 0.
|
|
28
|
+
stagger: 0.015,
|
|
29
29
|
yPercent: 110,
|
|
30
30
|
ease: "power4.out",
|
|
31
31
|
start: "top 97%"
|
|
@@ -115,7 +115,7 @@ const CharSplitAnimations = {
|
|
|
115
115
|
|
|
116
116
|
elements.forEach((textElement) => {
|
|
117
117
|
const split = SplitText.create(textElement, {
|
|
118
|
-
type: "chars",
|
|
118
|
+
type: "words,chars",
|
|
119
119
|
mask: "chars",
|
|
120
120
|
charsClass: "char",
|
|
121
121
|
});
|
|
@@ -343,25 +343,6 @@ async function initAnimations() {
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
export async function init() {
|
|
346
|
-
// Check if there's a persistent config stored globally
|
|
347
|
-
const api = window[API_NAME] || {};
|
|
348
|
-
console.log('🔄 Text animations init - full API object:', api);
|
|
349
|
-
console.log('🔄 Text animations init - _persistentConfigs:', api._persistentConfigs);
|
|
350
|
-
console.log('🔄 Text animations init - checking persistent config:', api._persistentConfigs?.textAnimations);
|
|
351
|
-
|
|
352
|
-
// Ensure _persistentConfigs exists
|
|
353
|
-
if (!api._persistentConfigs) {
|
|
354
|
-
api._persistentConfigs = {};
|
|
355
|
-
console.log('🏗️ Text animations - created _persistentConfigs object');
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (api._persistentConfigs?.textAnimations) {
|
|
359
|
-
console.log('📝 Text animations - applying persistent config:', api._persistentConfigs.textAnimations);
|
|
360
|
-
// Merge persistent config into current config
|
|
361
|
-
updateConfig(api._persistentConfigs.textAnimations);
|
|
362
|
-
console.log('✅ Text animations - config after merge:', config);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
346
|
if (prefersReducedMotion()) {
|
|
366
347
|
// For reduced motion, just show elements without animation
|
|
367
348
|
showElementsWithoutAnimation();
|
|
@@ -370,23 +351,35 @@ export async function init() {
|
|
|
370
351
|
initAnimations();
|
|
371
352
|
}
|
|
372
353
|
|
|
373
|
-
|
|
354
|
+
let resizeTimeout;
|
|
355
|
+
window.addEventListener('resize', () => {
|
|
356
|
+
clearTimeout(resizeTimeout);
|
|
357
|
+
resizeTimeout = setTimeout(() => {
|
|
358
|
+
// Kill and restart line split animations on resize
|
|
359
|
+
const lineSplitElements = document.querySelectorAll(".a-line-split > *:first-child");
|
|
360
|
+
lineSplitElements.forEach((textElement) => {
|
|
361
|
+
if (textElement.splitTextInstance) {
|
|
362
|
+
textElement.splitTextInstance.revert();
|
|
363
|
+
delete textElement.splitTextInstance;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// Re-initialize line splits after resize
|
|
368
|
+
LineSplitAnimations.initial().then(() => {
|
|
369
|
+
LineSplitAnimations.animate();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
ScrollTrigger.refresh();
|
|
373
|
+
}, 100);
|
|
374
|
+
});
|
|
374
375
|
|
|
376
|
+
const api = window[API_NAME] || {};
|
|
375
377
|
api.textAnimations = {
|
|
376
378
|
config: config,
|
|
377
|
-
updateConfig:
|
|
378
|
-
console.log('🔧 Text animations - updateConfig called with:', newConfig);
|
|
379
|
-
updateConfig(newConfig);
|
|
380
|
-
// Store config in persistent storage for restart persistence
|
|
381
|
-
api._persistentConfigs = api._persistentConfigs || {};
|
|
382
|
-
api._persistentConfigs.textAnimations = { ...config };
|
|
383
|
-
console.log('💾 Text animations - stored persistent config:', api._persistentConfigs.textAnimations);
|
|
384
|
-
console.log('💾 Text animations - full _persistentConfigs after store:', api._persistentConfigs);
|
|
385
|
-
},
|
|
379
|
+
updateConfig: updateConfig,
|
|
386
380
|
start: startTextAnimations,
|
|
387
381
|
kill: killTextAnimations,
|
|
388
382
|
restart: () => {
|
|
389
|
-
console.log('🔄 Text animations - restart called');
|
|
390
383
|
killTextAnimations();
|
|
391
384
|
startTextAnimations();
|
|
392
385
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function configure() {
|
|
2
|
+
// Check if hsmain is loaded AND the specific animation modules are available
|
|
3
|
+
if (!window.hsmain?.loaded ||
|
|
4
|
+
!window.hsmain?.textAnimations?.updateConfig ||
|
|
5
|
+
!window.hsmain?.heroAnimations?.updateConfig) {
|
|
6
|
+
setTimeout(configure, 10);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const api = window.hsmain;
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
api.textAnimations.updateConfig({
|
|
14
|
+
// your text animation config
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
api.heroAnimations.updateConfig({
|
|
18
|
+
headingSplit: {
|
|
19
|
+
// your hero animation config
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
api.textAnimations.restart();
|
|
24
|
+
api.heroAnimations.restart();
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.warn('Animation configuration failed:', error);
|
|
27
|
+
// Retry after a short delay if needed
|
|
28
|
+
setTimeout(configure, 50);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
configure();
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version:
|
|
1
|
+
// Version:1.2.26
|
|
2
2
|
|
|
3
3
|
const API_NAME = 'hsmain';
|
|
4
4
|
|
|
@@ -109,18 +109,12 @@ const initializeHsMain = async () => {
|
|
|
109
109
|
|
|
110
110
|
const readyCallbacks = [];
|
|
111
111
|
|
|
112
|
-
// Initialize persistent config storage first, preserving any existing configs
|
|
113
|
-
const existingConfigs = window[API_NAME]?._persistentConfigs || {};
|
|
114
|
-
console.log('🏗️ Initializing main API - existing persistent configs:', existingConfigs);
|
|
115
|
-
|
|
116
112
|
window[API_NAME] = {
|
|
117
113
|
scripts,
|
|
118
114
|
modules: {},
|
|
119
115
|
process: new Set(),
|
|
120
116
|
load: loadModule,
|
|
121
117
|
loaded: false,
|
|
122
|
-
// Persistent config storage
|
|
123
|
-
_persistentConfigs: existingConfigs,
|
|
124
118
|
push(...items) {
|
|
125
119
|
for (const [moduleName, callback] of items) {
|
|
126
120
|
if (typeof callback === 'function') {
|