rosary: remove scroll polyfill and optimize SVGs
Some checks failed
CI / update (push) Has been cancelled
Some checks failed
CI / update (push) Has been cancelled
Drop the smooth-scroll polyfill (now universally supported) and run SVGO on benedictus.svg (35KB→19KB) and the cross glyph path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,7 +70,7 @@
|
||||
<svg class="linear-rosary" viewBox="-100 -100 250 2200" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMin meet">
|
||||
<defs>
|
||||
<symbol id="cross-glyph" viewBox="0 0 1304 1497">
|
||||
<path transform="translate(-132, 1497) scale(1, -1)" d="M315 948Q293 903 245 857Q292 813 315 768L410 835V881ZM1159 880V834L1253 767Q1276 813 1323 857Q1276 903 1253 948ZM875 1314Q831 1337 784 1384Q740 1337 695 1314L763 1219H808ZM807 277H762L695 182Q740 159 784 112Q830 159 875 182ZM868 941H1096L1304 1067Q1314 962 1436 856Q1314 752 1304 648L1096 774H868V340L994 132Q888 121 783 0Q679 121 575 132L701 340V774H473L265 648Q254 752 132 857Q254 962 265 1067L473 941H701V1155L575 1364Q679 1375 784 1497Q888 1375 994 1364L868 1155ZM758 1040V881H642V835H758V451H812V835H928V881H812V1040Z" />
|
||||
<path d="M183 549q-22 45-70 91 47 44 70 89l95-67v-46Zm844 68v46l94 67q23-46 70-90-47-46-70-91ZM743 183q-44-23-91-70-44 47-89 70l68 95h45Zm-68 1037h-45l-67 95q45 23 89 70 46-47 91-70Zm61-664h228l208-126q10 105 132 211-122 104-132 208L964 723H736v434l126 208q-106 11-211 132-104-121-208-132l126-208V723H341L133 849Q122 745 0 640q122-105 133-210l208 126h228V342L443 133Q547 122 652 0q104 122 210 133L736 342Zm-110-99v159H510v46h116v384h54V662h116v-46H680V457Z"/>
|
||||
</symbol>
|
||||
</defs>
|
||||
|
||||
|
||||
@@ -30,86 +30,6 @@ export function setupScrollSync({
|
||||
}, duration);
|
||||
};
|
||||
|
||||
// Check if browser supports smooth scrolling
|
||||
const supportsNativeSmoothScroll = (() => {
|
||||
if (!('scrollBehavior' in document.documentElement.style)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const testElement = document.createElement('div');
|
||||
testElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
// Smooth scroll polyfill for window scrolling
|
||||
const smoothScrollTo = (targetY, duration = 500) => {
|
||||
if (supportsNativeSmoothScroll) {
|
||||
try {
|
||||
window.scrollTo({ top: targetY, behavior: 'smooth' });
|
||||
return;
|
||||
} catch (e) {
|
||||
// Fall through to polyfill
|
||||
}
|
||||
}
|
||||
|
||||
const startY = window.scrollY || window.pageYOffset;
|
||||
const distance = targetY - startY;
|
||||
const startTime = performance.now();
|
||||
|
||||
const easeInOutQuad = (t) => {
|
||||
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
};
|
||||
|
||||
const scroll = (currentTime) => {
|
||||
const elapsed = currentTime - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
const ease = easeInOutQuad(progress);
|
||||
window.scrollTo(0, startY + distance * ease);
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(scroll);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(scroll);
|
||||
};
|
||||
|
||||
// Smooth scroll polyfill for element scrolling (for SVG container)
|
||||
const smoothScrollElement = (element, targetY, duration = 500) => {
|
||||
if (supportsNativeSmoothScroll) {
|
||||
try {
|
||||
element.scrollTo({ top: targetY, behavior: 'smooth' });
|
||||
return;
|
||||
} catch (e) {
|
||||
// Fall through to polyfill
|
||||
}
|
||||
}
|
||||
|
||||
const startY = element.scrollTop;
|
||||
const distance = targetY - startY;
|
||||
const startTime = performance.now();
|
||||
|
||||
const easeInOutQuad = (t) => {
|
||||
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
};
|
||||
|
||||
const scroll = (currentTime) => {
|
||||
const elapsed = currentTime - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
const ease = easeInOutQuad(progress);
|
||||
element.scrollTop = startY + distance * ease;
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(scroll);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(scroll);
|
||||
};
|
||||
|
||||
// Helper: convert SVG section position to pixel scroll target
|
||||
function svgSectionToPixel(svg, section) {
|
||||
const svgYPosition = sectionPositions[section];
|
||||
@@ -134,8 +54,7 @@ export function setupScrollSync({
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && scrollLock !== 'svg' && scrollLock !== 'click') {
|
||||
// Skip observer updates when at the top — handleWindowScroll handles this
|
||||
const scrollY = window.scrollY || window.pageYOffset;
|
||||
if (scrollY < 50) return;
|
||||
if (window.scrollY < 50) return;
|
||||
|
||||
const section = entry.target.dataset.section;
|
||||
setActiveSection(section);
|
||||
@@ -150,7 +69,7 @@ export function setupScrollSync({
|
||||
const targetScroll = pixelPosition - 100;
|
||||
|
||||
setScrollLock('prayer');
|
||||
smoothScrollElement(svgContainer, Math.max(0, targetScroll));
|
||||
svgContainer.scrollTo({ top: Math.max(0, targetScroll), behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -174,7 +93,7 @@ export function setupScrollSync({
|
||||
if (scrollLock === 'svg' || scrollLock === 'click' || !svgContainer) return;
|
||||
|
||||
const viewportHeight = window.innerHeight;
|
||||
const scrollY = window.scrollY || window.pageYOffset;
|
||||
const scrollY = window.scrollY;
|
||||
const documentHeight = document.documentElement.scrollHeight;
|
||||
|
||||
const firstSection = sectionElements.cross;
|
||||
@@ -198,23 +117,23 @@ export function setupScrollSync({
|
||||
const maxScroll = svgContainer.scrollHeight - svgContainer.clientHeight;
|
||||
if (svgContainer.scrollTop < maxScroll - 10) {
|
||||
setScrollLock('prayer');
|
||||
smoothScrollElement(svgContainer, maxScroll);
|
||||
svgContainer.scrollTo({ top: maxScroll, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
else if (firstSectionRect.top > viewportHeight * 0.6) {
|
||||
if (svgContainer.scrollTop > 10) {
|
||||
setScrollLock('prayer');
|
||||
smoothScrollElement(svgContainer, 0);
|
||||
svgContainer.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
if (mysteryImageContainer && mysteryImageContainer.scrollTop > 10) {
|
||||
smoothScrollElement(mysteryImageContainer, 0);
|
||||
mysteryImageContainer.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
else if (finalSectionRect.bottom < viewportHeight * 0.4) {
|
||||
const maxScroll = svgContainer.scrollHeight - svgContainer.clientHeight;
|
||||
if (svgContainer.scrollTop < maxScroll - 10) {
|
||||
setScrollLock('prayer');
|
||||
smoothScrollElement(svgContainer, maxScroll);
|
||||
svgContainer.scrollTo({ top: maxScroll, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -264,7 +183,7 @@ export function setupScrollSync({
|
||||
const elementTop = element.getBoundingClientRect().top + window.scrollY;
|
||||
const offset = parseFloat(getComputedStyle(document.documentElement).fontSize) * 3;
|
||||
|
||||
smoothScrollTo(elementTop - offset);
|
||||
window.scrollTo({ top: elementTop - offset, behavior: 'smooth' });
|
||||
}
|
||||
}, 150);
|
||||
};
|
||||
@@ -292,7 +211,7 @@ export function setupScrollSync({
|
||||
const pixelPosition = svgSectionToPixel(svg, section);
|
||||
if (pixelPosition !== null) {
|
||||
const targetScroll = pixelPosition - 100;
|
||||
smoothScrollElement(svgContainer, Math.max(0, targetScroll));
|
||||
svgContainer.scrollTo({ top: Math.max(0, targetScroll), behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,7 +221,7 @@ export function setupScrollSync({
|
||||
const elementTop = element.getBoundingClientRect().top + window.scrollY;
|
||||
const offset = parseFloat(getComputedStyle(document.documentElement).fontSize) * 3;
|
||||
|
||||
smoothScrollTo(elementTop - offset);
|
||||
window.scrollTo({ top: elementTop - offset, behavior: 'smooth' });
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user