@hortonstudio/main 1.1.13 → 1.1.14
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 +2 -1
- package/animations/hero.js +8 -72
- package/package.json +1 -1
- package/styles.css +6 -0
- package/test-cdn.html +0 -29
package/animations/hero.js
CHANGED
@@ -244,50 +244,6 @@ export async function init() {
|
|
244
244
|
// Animation timeline
|
245
245
|
document.fonts.ready.then(() => {
|
246
246
|
|
247
|
-
// Helper function to extract span mappings and flatten HTML
|
248
|
-
function extractSpanMappings(element) {
|
249
|
-
const spanMappings = new Map();
|
250
|
-
const spans = element.querySelectorAll('span');
|
251
|
-
|
252
|
-
spans.forEach(span => {
|
253
|
-
const text = span.textContent.trim();
|
254
|
-
const classes = Array.from(span.classList);
|
255
|
-
if (text && classes.length > 0) {
|
256
|
-
spanMappings.set(text, classes);
|
257
|
-
}
|
258
|
-
});
|
259
|
-
|
260
|
-
// Force single text node to eliminate all text node boundaries
|
261
|
-
const originalText = element.textContent;
|
262
|
-
element.textContent = originalText;
|
263
|
-
|
264
|
-
return spanMappings;
|
265
|
-
}
|
266
|
-
|
267
|
-
// Helper function to apply span classes to matching words
|
268
|
-
function applySpanClasses(splitInstance, spanMappings) {
|
269
|
-
if (!splitInstance.words || spanMappings.size === 0) return;
|
270
|
-
|
271
|
-
splitInstance.words.forEach(wordElement => {
|
272
|
-
const wordText = wordElement.textContent.trim();
|
273
|
-
|
274
|
-
// Try exact match first
|
275
|
-
if (spanMappings.has(wordText)) {
|
276
|
-
const classes = spanMappings.get(wordText);
|
277
|
-
wordElement.classList.add(...classes);
|
278
|
-
return;
|
279
|
-
}
|
280
|
-
|
281
|
-
// Try case-insensitive and normalized match
|
282
|
-
for (const [spanText, classes] of spanMappings) {
|
283
|
-
if (wordText.toLowerCase() === spanText.toLowerCase()) {
|
284
|
-
wordElement.classList.add(...classes);
|
285
|
-
break;
|
286
|
-
}
|
287
|
-
}
|
288
|
-
});
|
289
|
-
}
|
290
|
-
|
291
247
|
// Split text setup (after fonts are loaded)
|
292
248
|
headingSplits = [];
|
293
249
|
|
@@ -296,9 +252,6 @@ export async function init() {
|
|
296
252
|
const textElement = heading[index];
|
297
253
|
const splitType = parent.getAttribute('data-hs-heroconfig') || 'word';
|
298
254
|
|
299
|
-
// Extract span mappings before splitting
|
300
|
-
const spanMappings = extractSpanMappings(textElement);
|
301
|
-
|
302
255
|
let splitConfig = {};
|
303
256
|
let elementsClass = '';
|
304
257
|
|
@@ -306,25 +259,21 @@ export async function init() {
|
|
306
259
|
splitConfig = {
|
307
260
|
type: "words,chars",
|
308
261
|
mask: "chars",
|
309
|
-
charsClass: "char"
|
310
|
-
reduceWhiteSpace: false
|
262
|
+
charsClass: "char"
|
311
263
|
};
|
312
264
|
elementsClass = 'chars';
|
313
265
|
} else if (splitType === 'line') {
|
314
266
|
splitConfig = {
|
315
|
-
type: "lines
|
267
|
+
type: "lines",
|
316
268
|
mask: "lines",
|
317
|
-
linesClass: "line"
|
318
|
-
wordsClass: "word",
|
319
|
-
reduceWhiteSpace: false
|
269
|
+
linesClass: "line"
|
320
270
|
};
|
321
271
|
elementsClass = 'lines';
|
322
272
|
} else {
|
323
273
|
splitConfig = {
|
324
274
|
type: "words",
|
325
275
|
mask: "words",
|
326
|
-
wordsClass: "word"
|
327
|
-
reduceWhiteSpace: false
|
276
|
+
wordsClass: "word"
|
328
277
|
};
|
329
278
|
elementsClass = 'words';
|
330
279
|
}
|
@@ -333,9 +282,6 @@ export async function init() {
|
|
333
282
|
split.elementsClass = elementsClass;
|
334
283
|
headingSplits.push(split);
|
335
284
|
|
336
|
-
// Apply span classes to matching words
|
337
|
-
applySpanClasses(split, spanMappings);
|
338
|
-
|
339
285
|
gsap.set(split[elementsClass], { yPercent: config.headingSplit.yPercent });
|
340
286
|
gsap.set(textElement, { autoAlpha: 1 });
|
341
287
|
});
|
@@ -347,9 +293,6 @@ export async function init() {
|
|
347
293
|
const textElement = subheading[index];
|
348
294
|
const splitType = parent.getAttribute('data-hs-heroconfig') || 'word';
|
349
295
|
|
350
|
-
// Extract span mappings before splitting
|
351
|
-
const spanMappings = extractSpanMappings(textElement);
|
352
|
-
|
353
296
|
let splitConfig = {};
|
354
297
|
let elementsClass = '';
|
355
298
|
|
@@ -357,25 +300,21 @@ export async function init() {
|
|
357
300
|
splitConfig = {
|
358
301
|
type: "words,chars",
|
359
302
|
mask: "chars",
|
360
|
-
charsClass: "char"
|
361
|
-
reduceWhiteSpace: false
|
303
|
+
charsClass: "char"
|
362
304
|
};
|
363
305
|
elementsClass = 'chars';
|
364
306
|
} else if (splitType === 'line') {
|
365
307
|
splitConfig = {
|
366
|
-
type: "lines
|
308
|
+
type: "lines",
|
367
309
|
mask: "lines",
|
368
|
-
linesClass: "line"
|
369
|
-
wordsClass: "word",
|
370
|
-
reduceWhiteSpace: false
|
310
|
+
linesClass: "line"
|
371
311
|
};
|
372
312
|
elementsClass = 'lines';
|
373
313
|
} else {
|
374
314
|
splitConfig = {
|
375
315
|
type: "words",
|
376
316
|
mask: "words",
|
377
|
-
wordsClass: "word"
|
378
|
-
reduceWhiteSpace: false
|
317
|
+
wordsClass: "word"
|
379
318
|
};
|
380
319
|
elementsClass = 'words';
|
381
320
|
}
|
@@ -384,9 +323,6 @@ export async function init() {
|
|
384
323
|
split.elementsClass = elementsClass;
|
385
324
|
subheadingSplits.push(split);
|
386
325
|
|
387
|
-
// Apply span classes to matching words
|
388
|
-
applySpanClasses(split, spanMappings);
|
389
|
-
|
390
326
|
gsap.set(split[elementsClass], { yPercent: config.subheadingSplit.yPercent });
|
391
327
|
gsap.set(textElement, { autoAlpha: 1 });
|
392
328
|
});
|
package/package.json
CHANGED
package/styles.css
CHANGED
@@ -10,6 +10,12 @@ body .transition {display: block}
|
|
10
10
|
padding-inline: .1em;
|
11
11
|
margin-inline: -.1em;
|
12
12
|
}
|
13
|
+
|
14
|
+
/* safari line detection fix */
|
15
|
+
[data-hs-hero="heading"] {
|
16
|
+
contain: layout style;
|
17
|
+
}
|
18
|
+
|
13
19
|
/* scroll cleanliness */
|
14
20
|
html, body {
|
15
21
|
overscroll-behavior: none;
|
package/test-cdn.html
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title>CDN Import Test</title>
|
5
|
-
</head>
|
6
|
-
<body>
|
7
|
-
<h1>Testing CDN Module Loading</h1>
|
8
|
-
<div data-hs-hero="heading">Hero Test Element</div>
|
9
|
-
|
10
|
-
<script>
|
11
|
-
// Test both local and CDN scenarios
|
12
|
-
console.log('Testing module loading...');
|
13
|
-
|
14
|
-
// Monitor console for debug messages
|
15
|
-
window.addEventListener('load', () => {
|
16
|
-
setTimeout(() => {
|
17
|
-
if (window.hsmain) {
|
18
|
-
console.log('API Status:', window.hsmain.status());
|
19
|
-
} else {
|
20
|
-
console.error('hsmain API not loaded');
|
21
|
-
}
|
22
|
-
}, 2000);
|
23
|
-
});
|
24
|
-
</script>
|
25
|
-
|
26
|
-
<!-- Test with local file -->
|
27
|
-
<script type="module" src="./index.js" data-hs-main data-hs-anim-hero></script>
|
28
|
-
</body>
|
29
|
-
</html>
|