- PVSM.RU - https://www.pvsm.ru -
Дорогиее! Давно читаю этот ресурс, но ни разу здесь не писал. Поэтому решил наконец исправить это и немного рассказать о себе. Если вкратце: немного кодер, немного разработчик, немного инженер. В общем, человек с техническим складом ума и довольно быстрым пониманием контекста. Без прилюдий, текста много.
Хочу поделиться веб‑читалкой для домашнего сервера: 3D‑перелистывание страниц на чистом CSS, книги в FB2/EPUB/TXT, закладки и позиция чтения синхронизируются через сервер, поэтому можно начать на телефоне, а продолжить на десктопе. Без сборки, без Node.js, без npm — только браузер и Python. Код на GitHub, лицензия свободная [1].
Всё из‑за закладок. Ну и из‑за приятных тонов картинки, но в основном — из‑за закладок.
У меня дома зоопарк устройств: Android, iPhone, MacBook, Windows. На каждом стоит своя читалка: когда‑то на андроиде был CoolReader (отличная штука, я им вдохновлялся), на маке — платный BookReader, на айфоне — Eboox, на винде — десктопный CoolReader, который, честно говоря, выглядит заметно скромнее своего мобильного собрата.
И всё бы ничего, но смена устройства каждый раз вызывала чувство дискомфорта. Синхронизировать закладки между этими программами невозможно в принципе, а запоминать, на какой главе остановился, у моего внимания не получается. Был ещё один веб‑сервис, которым я пользовался, но у него то ли закрылся , то ли ещё какие‑то проблемы, в общем, он исчез.
В какой‑то момент я понял, что проще написать своё. Тем более что дома уже крутится сервер с файловым хранилищем, лет 20, если не больше у меня появился первый такой — почему бы не разместить читалку там и читать свои книги с любого устройства через браузер?
Я редко пишу код «в стол», поэтому первым делом составил для себя техзадание, чтобы идти по плану и не расползаться по хотелкам. Основные пункты:
работает на домашнем сервере, доступ с любого устройства по сети, и кеш браузера.
книги хранятся на сервере обычными файлами, а не в базе;
позиция чтения и закладки — тоже на сервере, чтобы синхронизировались сами;
перелистывание страниц как у настоящей книги;
форматы: FB2, EPUB, TXT;
минимум зависимостей, никакого фронтенд‑конвейера, что бы не городить библиотеки, а развернуть можно было максимально просто.
По итогу всё из списка сделано, и результатом я доволен — работает хорошо. Есть мелкая проблема с правами доступа при запуске на удалённых машинах (сервер пишет state.json и метаданные рядом с книгами, и если каталоги не выставлены правильно — привет), но это решается парой команд chmod/chown, после копирования, ну или запуском с наивысшими провами.
Изначально я хотел сделать рендер на WebGL — насмотрелся, как ИИ делают разную анимацию в браузере и даже целые мини игры. Казалось, что там анимация перелистывания будет более зрелищной: настоящий изгиб страницы, тени, физика бумаги.
На практике оказалось, что рендерить текст шейдерами — это боль. Текст в WebGL — это либо атласы глифов, либо SDF, либо текстуры с предрендером, и всё это нужно пересчитывать при каждом изменении шрифта или размера страницы. А потом ещё эту текстуру надо натянуть на изгибающуюся сетку (mesh) страницы, и сетка эта непослушная, то текст плывёт, то края рвутся, то производительность на телефоне проседает, то под текстуры падает, корешка не слушается.
После пары недель экспериментов я принял волевое решение: выкинуть WebGL и сделать всё на CSS 3D transforms. И знаете что? Оказалось, что для «книжного» перелистывания CSS 3D хватает с головой: transform: rotateY(), perspective, transform‑origin на корешке страницы — и вот уже страница переворачивается, а браузер сам занимается рендером текста, сглаживанием и композитингом. Текст остаётся настоящим DOM‑текстом: его можно выделять, искать, он чёткий на любом DPI. Но ложка дёгтя всё ж была. Что делает все более реалистичным? Правильно освещение, пришлось повозиться с тенями и уровнями. Ну и немного с анимацией, так как она не хотела работать на Safari. Тени и текст менялись, а анимация страниц отсутствовала.
WebGL‑рендерер с изгибом страницы остался в планах — но уже как «когда‑нибудь потом, ради красоты», а не как необходимость.
Читалка
3D‑разворот книги с анимацией перелистывания. Можно листать кликом по краям, стрелками, пробелом, свайпом на телефоне, а можно ухватить угол страницы мышью или пальцем и потянуть — как бумажную.
Одностраничный режим для портретных экранов: на телефоне автоматически показывается одна страница вместо разворота.
Динамическая вёрстка: текст разбивается на страницы прямо в браузере под текущий размер экрана, шрифт и отступы. Повернул телефон — пересчиталось.
Позиция чтения не плывёт. Каждый абзац получает стабильный якорь (data‑block‑id), и позиция сохраняется по якорю, а не по номеру страницы. Меняешь шрифт — остаёшься на том же месте текста.
Закладки с превью текста, боковой панелью и визуальным маркером на краю книги.
Оглавление с переходом по главам.
5 тем: Бумага, Сепия, Ночной, Лес, Небо. Плюс настройка размера шрифта, интервала и отступов.
Библиотека: сетка карточек с обложками и прогрессом, добавление кнопкой или drag&drop, удаление с подтверждением.
Сознательно без фреймворков и сборки:
Фронтенд — чистый ES2022 JavaScript, CSS Custom Properties для тем, CSS 3D для перелистывания. Из стороннего только epub.js + JSZip, и те лежат скачанными в lib, если честно даже не тестил, у меня все книги в fb2, а там есть xml разметка.
Бэкенд — один файл server.py на стандартном http.server, без единой зависимости. Поднимает два потока: статика на 8080 и API на 8001.
Хранение — книги лежат прямыми файлами в books с исходными именами, рядом <имя>.meta.json с прогрессом и закладками, глобальные настройки в state.json. Никакой базы данных. Бэкап — это cp ‑r books/.
API крошечный: список книг, отдать текст (FB2 парсится на лету на сервере), прочитать, обновить метаданные, удалить книгу. Всё.
Проект сделан по собственному ТЗ, под собственные нужды, и я им пользуюсь каждый день. Если у вас тоже дома есть сервер, зоопарк устройств и боль с закладками — возможно, вам это тоже пригодится, спасибо за внимание.
Автор: Hiddenath
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/diy/456460
Ссылки в тексте:
[1] Код на GitHub, лицензия свободная: https://github.com/Hiddenath/book_reader
[2] хостинг: https://www.reg.ru/?rlink=reflink-717
[3] Источник: https://habr.com/ru/articles/1069526/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1069526
Нажмите здесь для печати.