Fix slide snap + presentation keyboard nav
- html/body height 100%, html overflow-y scroll — proper snap container - box-sizing border-box on sections (padding wasn't being included) - 2px black border-top between slides — visual divider - frame display block, body margin 0 - Keyboard: ArrowDown/PageDown/Space → next, ArrowUp/PageUp → prev, Home/End → first/last Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fc8bab570e
commit
5c1ab55af0
48
index.html
48
index.html
@ -106,13 +106,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
font-size: clamp(18px, 1.6vw, 28px); /* масштабируется под экран — для проектора 24–28px */
|
font-size: clamp(18px, 1.6vw, 28px);
|
||||||
scroll-snap-type: y mandatory;
|
scroll-snap-type: y mandatory;
|
||||||
|
overflow-y: scroll;
|
||||||
|
scroll-padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PRESENTATION MODE: каждая секция = ровно 1 экран, фиксация при скролле */
|
/* PRESENTATION MODE: каждая секция = ровно 1 экран */
|
||||||
.hero,
|
.hero,
|
||||||
section.section,
|
section.section,
|
||||||
.dark-section {
|
.dark-section {
|
||||||
@ -124,7 +129,7 @@ section.section,
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-top: 4vh;
|
padding-top: 4vh;
|
||||||
padding-bottom: 4vh;
|
padding-bottom: 4vh;
|
||||||
overflow-y: auto; /* если контент длиннее — скролл внутри слайда */
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Усиливаем типографику для большого экрана */
|
/* Усиливаем типографику для большого экрана */
|
||||||
@ -184,9 +189,18 @@ body {
|
|||||||
font-family: 'Lora', Georgia, serif !important;
|
font-family: 'Lora', Georgia, serif !important;
|
||||||
background: var(--page-bg);
|
background: var(--page-bg);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame { gap: 0; min-height: 100dvh; }
|
.frame { gap: 0; min-height: 100dvh; display: block; }
|
||||||
|
|
||||||
|
/* Усиливаем визуальную границу между слайдами */
|
||||||
|
.hero, section.section, .dark-section {
|
||||||
|
border-top: 2px solid var(--text) !important;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.hero { border-top: none !important; }
|
||||||
|
|
||||||
/* Шрифты заголовков */
|
/* Шрифты заголовков */
|
||||||
.hero-title, .section-title, .dark-title,
|
.hero-title, .section-title, .dark-title,
|
||||||
@ -3061,16 +3075,18 @@ const SCHEDULE = [
|
|||||||
targets.forEach(el => io.observe(el));
|
targets.forEach(el => io.observe(el));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Slide counter — показывает текущий слайд / всего
|
// Slide counter + keyboard nav (PageDown / Arrow / Space)
|
||||||
(function() {
|
(function() {
|
||||||
const counter = document.getElementById('slide-counter');
|
const counter = document.getElementById('slide-counter');
|
||||||
if (!counter) return;
|
|
||||||
const slides = Array.from(document.querySelectorAll('.hero, section.section, .dark-section'));
|
const slides = Array.from(document.querySelectorAll('.hero, section.section, .dark-section'));
|
||||||
const total = slides.length;
|
const total = slides.length;
|
||||||
|
let current = 0;
|
||||||
const update = (idx) => {
|
const update = (idx) => {
|
||||||
counter.textContent = `— ${idx + 1} / ${total} —`;
|
current = idx;
|
||||||
|
if (counter) counter.textContent = `— ${idx + 1} / ${total} —`;
|
||||||
};
|
};
|
||||||
update(0);
|
update(0);
|
||||||
|
|
||||||
const io = new IntersectionObserver((entries) => {
|
const io = new IntersectionObserver((entries) => {
|
||||||
entries.forEach(e => {
|
entries.forEach(e => {
|
||||||
if (e.isIntersecting && e.intersectionRatio > 0.5) {
|
if (e.isIntersecting && e.intersectionRatio > 0.5) {
|
||||||
@ -3080,6 +3096,24 @@ const SCHEDULE = [
|
|||||||
});
|
});
|
||||||
}, { threshold: [0.5, 0.6, 0.75] });
|
}, { threshold: [0.5, 0.6, 0.75] });
|
||||||
slides.forEach(s => io.observe(s));
|
slides.forEach(s => io.observe(s));
|
||||||
|
|
||||||
|
const goTo = (idx) => {
|
||||||
|
idx = Math.max(0, Math.min(total - 1, idx));
|
||||||
|
slides[idx].scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (['INPUT', 'TEXTAREA'].includes(document.activeElement?.tagName)) return;
|
||||||
|
if (e.key === 'ArrowDown' || e.key === 'PageDown' || e.key === ' ') {
|
||||||
|
e.preventDefault(); goTo(current + 1);
|
||||||
|
} else if (e.key === 'ArrowUp' || e.key === 'PageUp') {
|
||||||
|
e.preventDefault(); goTo(current - 1);
|
||||||
|
} else if (e.key === 'Home') {
|
||||||
|
e.preventDefault(); goTo(0);
|
||||||
|
} else if (e.key === 'End') {
|
||||||
|
e.preventDefault(); goTo(total - 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user