[html]
<head>
<style>
.book-container {
width: 800px;
height: 500px;
margin: 20px auto;
position: relative;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
font-family: 'Georgia', serif;
}
.book-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
background: url('https://example.com/path/to/book-background.jpg') center/cover no-repeat;
}
.book-pages {
display: flex;
height: 100%;
position: absolute;
left: 0;
top: 0;
min-width: 800px; /* Предотвращает сжатие при малом числе страниц */
}
.page-pair {
position: relative;
display: flex;
width: 800px;
height: 100%;
}
.page {
width: 400px;
height: 100%;
background-color: #fff;
border: 1px solid #ddd;
box-sizing: border-box;
padding: 20px;
line-height: 1.6;
position: relative;
overflow-y: auto;
color: #333;
}
.page:first-child {
border-radius: 4px 0 0 4px;
border-right: none;
}
.page:last-child {
border-radius: 0 4px 4px 0;
}
.page::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
to bottom,
rgba(255, 255, 220, 0.3),
rgba(250, 240, 200, 0.1)
);
pointer-events: none;
z-index: 1;
}
/* Сброс отступов для типографики внутри страниц */
.page h1, .page h2, .page h3, .page h4, .page h5, .page h6,
.page p, .page ul, .page ol, .page pre {
margin: 0 0 10px 0;
padding: 0;
}
.book-controls {
text-align: center;
margin-top: 10px;
}
.btn-prev, .btn-next {
background-color: #0056b3; /* Темнее для контраста */
color: #ffffff;
border: none;
padding: 8px 16px;
margin: 0 8px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.btn-prev:hover, .btn-next:hover {
background-color: #004085;
}
.btn-prev:focus, .btn-next:focus {
outline: 2px solid #4d90fe;
outline-offset: 2px;
}
/* Адаптивность: уменьшаем отступы на мобильных */
@media (max-width: 800px) {
.book-container {
width: 100%;
margin: 10px 0;
}
.page {
padding: 15px;
font-size: 14px;
}
.btn-prev, .btn-next {
padding: 6px 12px;
font-size: 13px;
}
}
</style>
</head>
<body>
<div class="book-container" role="region" aria-label="Электронная книга">
<div class="book-wrapper">
<div class="book-pages" id="bookPages" aria-live="polite">
<!-- Разворот 1 (страницы 1–2) -->
<div class="page-pair">
<div class="page">
<h3>Глава 1. Начало пути</h3>
<p>В одном далёком королевстве жил юноша по имени Эрион. Он мечтал стать великим путешественником и исследовать все уголки мира.</p>
<p>Каждое утро он выходил на дорогу, ведущую к горам, и смотрел вдаль, представляя, что ждёт его за горизонтом.</p>
</div>
<div class="page">
<h3>Глава 1. Продолжение</h3>
<p>Однажды утром Эрион собрал свой небольшой рюкзак, взял карту и отправился в путь. Солнце только начинало подниматься, а он уже шагал по тропинке, ведущей к древнему лесу.</p>
<p>«Сегодня начнётся моё великое приключение!» — подумал он.</p>
</div>
</div>
<!-- Разворот 2 (страницы 3–4) -->
<div class="page-pair">
<div class="page">
<h3>Глава 2. Таинственный лес</h3>
<p>Лес встретил Эриона тишиной и прохладой. Высокие деревья закрывали небо, а под ногами шуршали опавшие листья.</p>
<p>Он достал компас и проверил направление. Стрелка дрогнула и указала на север.</p>
</div>
<div class="page">
<h3>Глава 2. Продолжение</h3>
<p>Через несколько часов Эрион услышал странный звук — будто кто‑то шептал среди деревьев. Он остановился и прислушался.</p>
<p>«Это ветер», — решил он, но голос становился всё отчётливее.</p>
</div>
</div>
<!-- Разворот 3 (страницы 5–6) -->
<div class="page-pair">
<div class="page">
<h3>Глава 3. Встреча с мудрецом</h3>
<p>Пройдя вглубь леса, Эрион увидел старую хижину. У входа сидел седобородый старец с книгой в руках.</p>
<p>— Ты ищешь ответы, — сказал мудрец, не поднимая глаз. — Но сначала ты должен понять, что вопросы важнее.</p>
</div>
<div class="page">
<h3>Глава 3. Заключение</h3>
<p>Эрион сел рядом и начал слушать. Мудрец рассказывал о древних путях, звёздах и тайнах, скрытых в сердце каждого человека.</p>
<p>К закату юноша понял: его путешествие только начинается.</p>
</div>
</div>
</div>
</div>
<div class="book-controls">
<button
class="btn-prev"
id="btnPrev"
type="button"
aria-label="Предыдущая страница"
title="Перейти к предыдущему развороту">
< Влево
</button>
<button
class="btn-next"
id="btnNext"
type="button"
aria-label="Следующая страница"
title="Перейти к следующему развороту">
Вправо >
</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const bookPages = document.getElementById('bookPages');
const btnPrev = document.getElementById('btnPrev');
const btnNext = document.getElementById('btnNext');
// Массив контента страниц (добавляйте сколько нужно)
const pagesContent = [
'<h3>Страница 1</h3><p>Текст первой страницы. Lorem ipsum dolor sit amet.</p>',
'<h3>Страница 2</h3><p>Текст второй страницы. Consectetur adipiscing elit.</p>',
'<h3>Страница 3</h3><p>Текст третьей страницы. Sed do eiusmod tempor incididunt.</p>',
'<h3>Страница 4</h3><p>Текст четвёртой страницы. Ut labore et dolore magna aliqua.</p>',
'<h3>Страница 5</h3><p>Текст пятой страницы. Quis nostrud exercitation ullamco.</p>',
'<h3>Страница 6</h3><p>Текст шестой страницы. Laboris nisi ut aliquip ex ea commodo.</p>'
// Добавьте больше страниц по необходимости
];
let currentPairIndex = 0; // Индекс текущей пары (0, 1, 2, ...)
const PAIR_WIDTH = 800; // Ширина одной пары страниц (2 × 400px)
// Функция: создать все пары страниц
function renderPagePairs() {
// Очищаем контейнер
bookPages.innerHTML = '';
// Если страниц нет
if (pagesContent.length === 0) {
const emptyPage = document.createElement('div');
emptyPage.className = 'page';
emptyPage.style.textAlign = 'center';
emptyPage.innerHTML = '<em>Нет страниц для отображения</em>';
bookPages.appendChild(emptyPage);
return;
}
// Создаём пары страниц
for (let i = 0; i < pagesContent.length; i += 2) {
const pairDiv = document.createElement('div');
pairDiv.className = 'page-pair';
// Левая страница (всегда есть)
const leftPage = document.createElement('div');
leftPage.className = 'page';
leftPage.innerHTML = pagesContent[i];
pairDiv.appendChild(leftPage);
// Правая страница (если есть следующая)
if (i + 1 < pagesContent.length) {
const rightPage = document.createElement('div');
rightPage.className = 'page';
rightPage.innerHTML = pagesContent[i + 1];
pairDiv.appendChild(rightPage);
} else {
// Если нечётное число страниц — пустая правая страница
const emptyPage = document.createElement('div');
emptyPage.className = 'page';
emptyPage.style.backgroundColor = '#f5f5f5';
emptyPage.style.textAlign = 'center';
emptyPage.innerHTML = '<em>Конец книги</em>';
pairDiv.appendChild(emptyPage);
}
bookPages..appendChild(pairDiv);
}
// Сразу показываем первую пару
updateBookPosition();
}
// Функция: обновить позицию (мгновенное переключение)
function updateBookPosition() {
const offsetX = -currentPairIndex * PAIR_WIDTH;
bookPages.style.left = `${offsetX}px`;
// Обновляем ARIA-атрибуты для доступности
bookPages.setAttribute('aria-label', `Разворот ${currentPairIndex + 1} из ${Math.ceil(pagesContent.length / 2)}`);
}
// Функция: проверить доступность кнопок
function updateButtonState() {
const maxPairIndex = Math.max(0, Math.floor(pagesContent.length / 2) - 1);
btnPrev.disabled = currentPairIndex <= 0;
btnNext.disabled = currentPairIndex >= maxPairIndex;
// Визуальное отключение кнопок
if (btnPrev.disabled) {
btnPrev.style.opacity = '0.5';
btnPrev.style.cursor = 'not-allowed';
} else {
btnPrev.style.opacity = '1';
btnPrev.style.cursor = 'pointer';
}
if (btnNext.disabled) {
btnNext.style.opacity = '0.5';
btnNext.style.cursor = 'not-allowed';
} else {
btnNext.style.opacity = '1';
btnNext.style.cursor = 'pointer';
}
}
// Обработчики кнопок
btnNext.addEventListener('click', function() {
const maxPairIndex = Math.max(0, Math.floor(pagesContent.length / 2) - 1);
if (currentPairIndex < maxPairIndex) {
currentPairIndex++;
updateBookPosition();
updateButtonState();
}
});
btnPrev.addEventListener('click', function() {
if (currentPairIndex > 0) {
currentPairIndex--;
updateBookPosition();
updateButtonState();
}
});
// Поддержка клавиатурной навигации
btnPrev.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
btnPrev.click();
}
});
btnNext.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
btnNext.click();
}
});
// Инициализация
renderPagePairs();
updateButtonState();
// Дополнительно: обработка фокуса при навигации
btnPrev.addEventListener('focus', function() {
this.style.outline = '2px solid #4d90fe';
});
btnPrev.addEventListener('blur', function() {
this.style.outline = '';
});
btnNext.addEventListener('focus', function() {
this.style.outline = '2px solid #4d90fe';
});
btnNext.addEventListener('blur', function() {
this.style.outline = '';
});
});
</script>
</body>
[/html]



























