@hortonstudio/main 1.2.9 → 1.2.12
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/hero.js +69 -0
- package/animations/text.js +72 -8
- package/attributes-master/package.json +1 -1
- package/debug-version.html +37 -0
- package/index.js +16 -3
- package/package.json +1 -1
package/animations/hero.js
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
const API_NAME = 'hsmain';
|
2
2
|
|
3
|
+
// Check for reduced motion preference
|
4
|
+
const prefersReducedMotion = () => {
|
5
|
+
return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
6
|
+
};
|
7
|
+
|
3
8
|
// Animation timing (in seconds)
|
4
9
|
const timing = {
|
5
10
|
announce: 0,
|
@@ -119,12 +124,76 @@ function startHeroAnimations() {
|
|
119
124
|
init();
|
120
125
|
}
|
121
126
|
|
127
|
+
function showHeroElementsWithoutAnimation() {
|
128
|
+
// Simply show all hero elements without any animation or split text
|
129
|
+
const allHeroElements = [
|
130
|
+
...document.querySelectorAll('[data-hs-hero="announce"]'),
|
131
|
+
...document.querySelectorAll('[data-hs-hero="nav"]'),
|
132
|
+
...document.querySelectorAll('[data-hs-hero="nav-menu"]'),
|
133
|
+
...document.querySelectorAll('[data-hs-hero="nav-logo"]'),
|
134
|
+
...document.querySelectorAll('[data-hs-hero="nav-button"] > *:first-child'),
|
135
|
+
...document.querySelectorAll('[data-hs-hero="nav-list"] > * > *:first-child'),
|
136
|
+
...document.querySelectorAll('[data-hs-hero="heading"] > *:first-child'),
|
137
|
+
...document.querySelectorAll('[data-hs-hero="subheading"] > *:first-child'),
|
138
|
+
...document.querySelectorAll('[data-hs-hero="tag"] > *:first-child'),
|
139
|
+
...document.querySelectorAll('[data-hs-hero="button"] > *'),
|
140
|
+
...document.querySelectorAll('[data-hs-hero="image"]'),
|
141
|
+
...document.querySelectorAll('[data-hs-hero="appear"]')
|
142
|
+
];
|
143
|
+
|
144
|
+
allHeroElements.forEach(element => {
|
145
|
+
if (element) {
|
146
|
+
gsap.set(element, {
|
147
|
+
autoAlpha: 1,
|
148
|
+
opacity: 1,
|
149
|
+
y: 0,
|
150
|
+
yPercent: 0
|
151
|
+
});
|
152
|
+
// Remove any pointer-events restrictions
|
153
|
+
element.style.pointerEvents = '';
|
154
|
+
}
|
155
|
+
});
|
156
|
+
|
157
|
+
// Restore page-wide tabbing
|
158
|
+
const allFocusableElements = document.querySelectorAll('[data-original-tabindex]');
|
159
|
+
allFocusableElements.forEach(el => {
|
160
|
+
el.style.pointerEvents = '';
|
161
|
+
const originalTabindex = el.getAttribute('data-original-tabindex');
|
162
|
+
if (originalTabindex === '0') {
|
163
|
+
el.removeAttribute('tabindex');
|
164
|
+
} else {
|
165
|
+
el.setAttribute('tabindex', originalTabindex);
|
166
|
+
}
|
167
|
+
el.removeAttribute('data-original-tabindex');
|
168
|
+
});
|
169
|
+
}
|
170
|
+
|
122
171
|
export async function init() {
|
123
172
|
if (typeof window.gsap === "undefined") {
|
124
173
|
console.error('GSAP not found - hero animations disabled');
|
125
174
|
return;
|
126
175
|
}
|
127
176
|
|
177
|
+
if (prefersReducedMotion()) {
|
178
|
+
// For reduced motion, just show elements without animation
|
179
|
+
showHeroElementsWithoutAnimation();
|
180
|
+
|
181
|
+
// Still expose the API for consistency
|
182
|
+
window[API_NAME] = window[API_NAME] || {};
|
183
|
+
window[API_NAME].heroAnimations = {
|
184
|
+
config: config,
|
185
|
+
updateConfig: updateConfig,
|
186
|
+
start: startHeroAnimations,
|
187
|
+
kill: killHeroAnimations,
|
188
|
+
restart: () => {
|
189
|
+
killHeroAnimations();
|
190
|
+
startHeroAnimations();
|
191
|
+
}
|
192
|
+
};
|
193
|
+
|
194
|
+
return { result: 'anim-hero initialized (reduced motion)' };
|
195
|
+
}
|
196
|
+
|
128
197
|
gsap.registerPlugin(ScrollTrigger, SplitText);
|
129
198
|
|
130
199
|
// Element selection
|
package/animations/text.js
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
const API_NAME = 'hsmain';
|
2
2
|
|
3
|
+
// Check for reduced motion preference
|
4
|
+
const prefersReducedMotion = () => {
|
5
|
+
return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
6
|
+
};
|
7
|
+
|
3
8
|
const config = {
|
4
9
|
global: {
|
5
10
|
animationDelay: 0
|
@@ -62,6 +67,12 @@ function killTextAnimations() {
|
|
62
67
|
}
|
63
68
|
|
64
69
|
function startTextAnimations() {
|
70
|
+
if (prefersReducedMotion()) {
|
71
|
+
// For reduced motion, just show elements without animation
|
72
|
+
showElementsWithoutAnimation();
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
65
76
|
setInitialStates().then(() => {
|
66
77
|
initAnimations();
|
67
78
|
});
|
@@ -73,14 +84,36 @@ function waitForFonts() {
|
|
73
84
|
return document.fonts.ready;
|
74
85
|
}
|
75
86
|
|
87
|
+
function showElementsWithoutAnimation() {
|
88
|
+
// Simply show all text elements without any animation or split text
|
89
|
+
const allTextElements = [
|
90
|
+
...document.querySelectorAll(".a-char-split > *:first-child"),
|
91
|
+
...document.querySelectorAll(".a-word-split > *:first-child"),
|
92
|
+
...document.querySelectorAll(".a-line-split > *:first-child"),
|
93
|
+
...document.querySelectorAll('.a-appear')
|
94
|
+
];
|
95
|
+
|
96
|
+
allTextElements.forEach(element => {
|
97
|
+
gsap.set(element, {
|
98
|
+
autoAlpha: 1,
|
99
|
+
y: 0,
|
100
|
+
yPercent: 0,
|
101
|
+
opacity: 1
|
102
|
+
});
|
103
|
+
});
|
104
|
+
}
|
105
|
+
|
76
106
|
const CharSplitAnimations = {
|
77
107
|
async initial() {
|
78
108
|
await waitForFonts();
|
79
109
|
|
110
|
+
if (prefersReducedMotion()) {
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
|
80
114
|
const elements = document.querySelectorAll(".a-char-split > *:first-child");
|
81
115
|
|
82
|
-
elements.forEach((textElement
|
83
|
-
|
116
|
+
elements.forEach((textElement) => {
|
84
117
|
const split = SplitText.create(textElement, {
|
85
118
|
type: "chars",
|
86
119
|
mask: "chars",
|
@@ -98,6 +131,10 @@ const CharSplitAnimations = {
|
|
98
131
|
async animate() {
|
99
132
|
await waitForFonts();
|
100
133
|
|
134
|
+
if (prefersReducedMotion()) {
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
|
101
138
|
document.querySelectorAll(".a-char-split > *:first-child").forEach((textElement) => {
|
102
139
|
const chars = textElement.querySelectorAll('.char');
|
103
140
|
const tl = gsap.timeline({
|
@@ -127,10 +164,13 @@ const WordSplitAnimations = {
|
|
127
164
|
async initial() {
|
128
165
|
await waitForFonts();
|
129
166
|
|
167
|
+
if (prefersReducedMotion()) {
|
168
|
+
return;
|
169
|
+
}
|
170
|
+
|
130
171
|
const elements = document.querySelectorAll(".a-word-split > *:first-child");
|
131
172
|
|
132
|
-
elements.forEach((textElement
|
133
|
-
|
173
|
+
elements.forEach((textElement) => {
|
134
174
|
const split = SplitText.create(textElement, {
|
135
175
|
type: "words",
|
136
176
|
mask: "words",
|
@@ -148,6 +188,10 @@ const WordSplitAnimations = {
|
|
148
188
|
async animate() {
|
149
189
|
await waitForFonts();
|
150
190
|
|
191
|
+
if (prefersReducedMotion()) {
|
192
|
+
return;
|
193
|
+
}
|
194
|
+
|
151
195
|
document.querySelectorAll(".a-word-split > *:first-child").forEach((textElement) => {
|
152
196
|
const words = textElement.querySelectorAll('.word');
|
153
197
|
const tl = gsap.timeline({
|
@@ -177,10 +221,13 @@ const LineSplitAnimations = {
|
|
177
221
|
async initial() {
|
178
222
|
await waitForFonts();
|
179
223
|
|
224
|
+
if (prefersReducedMotion()) {
|
225
|
+
return;
|
226
|
+
}
|
227
|
+
|
180
228
|
const elements = document.querySelectorAll(".a-line-split > *:first-child");
|
181
229
|
|
182
|
-
elements.forEach((textElement
|
183
|
-
|
230
|
+
elements.forEach((textElement) => {
|
184
231
|
const split = SplitText.create(textElement, {
|
185
232
|
type: "lines",
|
186
233
|
mask: "lines",
|
@@ -198,6 +245,10 @@ const LineSplitAnimations = {
|
|
198
245
|
async animate() {
|
199
246
|
await waitForFonts();
|
200
247
|
|
248
|
+
if (prefersReducedMotion()) {
|
249
|
+
return;
|
250
|
+
}
|
251
|
+
|
201
252
|
document.querySelectorAll(".a-line-split > *:first-child").forEach((textElement) => {
|
202
253
|
const lines = textElement.querySelectorAll('.line');
|
203
254
|
const tl = gsap.timeline({
|
@@ -227,6 +278,10 @@ const AppearAnimations = {
|
|
227
278
|
async initial() {
|
228
279
|
await waitForFonts();
|
229
280
|
|
281
|
+
if (prefersReducedMotion()) {
|
282
|
+
return;
|
283
|
+
}
|
284
|
+
|
230
285
|
const elements = document.querySelectorAll('.a-appear');
|
231
286
|
elements.forEach(element => {
|
232
287
|
gsap.set(element, {
|
@@ -239,6 +294,10 @@ const AppearAnimations = {
|
|
239
294
|
async animate() {
|
240
295
|
await waitForFonts();
|
241
296
|
|
297
|
+
if (prefersReducedMotion()) {
|
298
|
+
return;
|
299
|
+
}
|
300
|
+
|
242
301
|
document.querySelectorAll('.a-appear').forEach(element => {
|
243
302
|
const tl = gsap.timeline({
|
244
303
|
scrollTrigger: {
|
@@ -284,8 +343,13 @@ async function initAnimations() {
|
|
284
343
|
}
|
285
344
|
|
286
345
|
export async function init() {
|
287
|
-
|
288
|
-
|
346
|
+
if (prefersReducedMotion()) {
|
347
|
+
// For reduced motion, just show elements without animation
|
348
|
+
showElementsWithoutAnimation();
|
349
|
+
} else {
|
350
|
+
await setInitialStates();
|
351
|
+
initAnimations();
|
352
|
+
}
|
289
353
|
|
290
354
|
window.addEventListener('resize', ScrollTrigger.refresh());
|
291
355
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>CDN Version Debug Test</title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h1>CDN Version Debug Test</h1>
|
8
|
+
<div id="results"></div>
|
9
|
+
|
10
|
+
<!-- Test with major version @1 -->
|
11
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@hortonstudio/main@1/index.js" data-hs-main data-hs-anim-hero></script>
|
12
|
+
|
13
|
+
<script>
|
14
|
+
setTimeout(() => {
|
15
|
+
const results = document.getElementById('results');
|
16
|
+
|
17
|
+
// Check what scripts are found
|
18
|
+
const scripts = [...document.querySelectorAll('script[type="module"]')];
|
19
|
+
results.innerHTML += `<h2>Found Scripts:</h2>`;
|
20
|
+
scripts.forEach((script, i) => {
|
21
|
+
results.innerHTML += `<p>Script ${i}: ${script.src}</p>`;
|
22
|
+
});
|
23
|
+
|
24
|
+
// Check if hsmain loaded and what scripts it found
|
25
|
+
if (window.hsmain) {
|
26
|
+
results.innerHTML += `<h2>HSMAIN Scripts Found:</h2>`;
|
27
|
+
results.innerHTML += `<p>Found ${window.hsmain.scripts.length} matching scripts</p>`;
|
28
|
+
window.hsmain.scripts.forEach((script, i) => {
|
29
|
+
results.innerHTML += `<p>HSMAIN Script ${i}: ${script.src}</p>`;
|
30
|
+
});
|
31
|
+
} else {
|
32
|
+
results.innerHTML += `<p>HSMAIN not loaded</p>`;
|
33
|
+
}
|
34
|
+
}, 2000);
|
35
|
+
</script>
|
36
|
+
</body>
|
37
|
+
</html>
|
package/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
// ver 1.2.
|
1
|
+
// ver 1.2.12
|
2
2
|
|
3
3
|
const API_NAME = 'hsmain';
|
4
4
|
|
@@ -73,8 +73,21 @@ const initializeHsMain = () => {
|
|
73
73
|
});
|
74
74
|
};
|
75
75
|
|
76
|
-
// Find script tags (
|
77
|
-
|
76
|
+
// Find script tags (with CDN version redirect support)
|
77
|
+
let scripts = [...document.querySelectorAll(`script[type="module"][src="${import.meta.url}"]`)];
|
78
|
+
|
79
|
+
// Handle CDN version redirects (e.g., @1 -> @1.2.11)
|
80
|
+
if (scripts.length === 0) {
|
81
|
+
const allScripts = [...document.querySelectorAll('script[type="module"][src*="@hortonstudio/main"]')];
|
82
|
+
scripts = allScripts.filter(script => {
|
83
|
+
const src = script.src;
|
84
|
+
const metaUrl = import.meta.url;
|
85
|
+
// Extract package name and check if they match (ignoring version differences)
|
86
|
+
const srcPackage = src.match(/@hortonstudio\/main(@[\d.]+)?/)?.[0];
|
87
|
+
const metaPackage = metaUrl.match(/@hortonstudio\/main(@[\d.]+)?/)?.[0];
|
88
|
+
return srcPackage && metaPackage && srcPackage.split('@')[0] === metaPackage.split('@')[0];
|
89
|
+
});
|
90
|
+
}
|
78
91
|
|
79
92
|
// Module loading function
|
80
93
|
const loadHsModule = async (moduleName) => {
|