Closed slavonika closed 1 year ago
Нет, такой возможности нет. Это никому не было нужно. И если делать по уму, то надо многие зависимости перенести в peerDependencies, да и сам Viewer выделить в React компонент. И желания заниматься этим у меня сейчас нет.
Также для работы нужна библиотека, а она сейчас тоже через <script />
подключается.
Как я понимаю, это все нужно только для оптимизации размера сборки. Однако, это все равно существенно увеличит размер сборки и замедлит загрузку сайта. Для пользователя может быть лучше, если вы подключите Viewer отдельным скриптом, как это и предполагается делать.
Но если хочется все собрать в единый файл, то да, просто включите исходники в проект, а библиотеку подключите скриптом. Как заработает, то можно будет и библиотеку включить в сборку. Подскажу, если нужно.
Сейчас никто не хочет морочиться с загрузкой софта для просмотра djvu, и для сайта электронной библиотеки ваш компонент просто находка.
Спасибо, я так и собирался сделать. Хотел было оптимизировать размер главной и важных страниц, но вы правы, не выйдет. Видимо, viewer надо делать на отдельной странице, а не на странице каталога книг. Всё равно сам файл djvu будет загружаться относительно долго.
То что не собираетесь сделать React компонент и пакет в npm – жаль, конечно, пригодилось бы.
И огромное спасибо за библиотеку :)
Я вам советую начать с подключения сборки через скрипты в head
как здесь показано.
https://djvu.js.org/downloads
Можно добавить к ним defer
, но тогда придется проверять появился ли DjVu.Viewer
или нет.
И написать простой компонент Viewer, который будет создавать пустой div, получать его через ref, и создавать DjVuViewer.
Когда компонент удаляется, надо будет вызвать метод .destroy()
. Он не указан в документации, но он есть. Его туда стоит добавить.
Таким образом вы получите React компонент, который можно использовать где угодно и сколько угодно раз. Например, книгу можно будет отображать в модальном окне.
Если проект открытый, то поделитесь ссылкой, пожалуйста. Будет интересно посмотреть.
Спасибо за ответы.
Сейчас ещё рассматриваю вариант ленивой загрузки Viewer'а (например) или его загрузки по клику на кнопке просмотра документа. Всё-таки не очень нравится идея создавать лишние страницы.
Тут ещё один момент. Мобильная аудитория возросла в разы. Сейчас их 80-90% от общего числа пользователей. А ведь раньше было наоборот. Надо сказать, что Viewer вполне себя хорошо ведет в мобильном браузере. Не хватает разве что масштабирования двумя пальцами.
Наш сайт был создан лет 15 назад, пора переписывать. Пока код в закрытом репозитории, смотреть особо нечего, мы три дня назад начали работу :) Если получится что-то интересное, откроем репозиторий.
Please take a look at the license. It's kind of GPL. Some years ago I did a separate page for the browsing of djvu documents to match the licensing. So I don't think that mixing-in this library to your commercial web site would play well with licenses. Unless нам по@бать на эту западную ху@ню.
"use client";
import { useState } from "react";
const DjvuViewer = () => {
const [areScriptsLoaded, setAreScriptsLoaded] = useState(false);
const handleLoadScript = () => {
if (!document.querySelector("script[src='/scripts/djvu.js']")) {
const djvuLibJs = document.createElement("script");
djvuLibJs.src = "/scripts/djvu.js";
djvuLibJs.async = true;
document.body.appendChild(djvuLibJs);
}
if (!document.querySelector("script[src='/scripts/djvu_viewer.js']")) {
const viewerJs = document.createElement("script");
viewerJs.src = "/scripts/djvu_viewer.js";
viewerJs.async = true;
document.body.appendChild(viewerJs);
}
const checkScriptsLoaded = () => {
if (
typeof DjVu !== "undefined" &&
typeof DjVu.Viewer !== "undefined"
) {
// Create a new instance of the DjVu viewer and render it.
window.ViewerInstance = new DjVu.Viewer();
window.ViewerInstance.render(document.querySelector("#for_viewer"));
setAreScriptsLoaded(true);
} else {
setTimeout(checkScriptsLoaded, 100);
}
};
checkScriptsLoaded();
};
return (
<>
<button onClick={handleLoadScript}>Просмотр</button>
<div id="for_viewer"></div>
</>
);
};
export default DjvuViewer;
Интересно, а можно ли принудительно включить полностраничный режим и выставить масштаб страницы по ширине окна Viewer'а? В конфигурации я такого не нашёл (не понял).
Подход был правильный, код с некоторыми доработками даёт результат. Но вот в целом юзабилити страницы с кучей вьюверов (или одним внизу страницы) как-то не зашёл. Попробую идею с просмотровщиком на отдельном урле, файл передам через параметры.
Включить полностраничный режим должно быть несложно. Нужно создать вот это событие https://github.com/RussCoder/djvujs/blob/master/viewer/src/components/misc/FullPageViewButton.jsx#L22 которое используется в соответствующей кнопке.
Методы DjVuViewer так и работают, инициируя события https://github.com/RussCoder/djvujs/blob/master/viewer/src/DjVuViewer.js#L166
Я бы рекомендовал, запустить проект локально и добавить подобные методы. Если они действительно будут нужны, то можно будет их сохранить в основном репозитории и внести в документацию.
А вот выставить масштаб страницы по ширине окна уже сложнее. Это не было реализовано, поэтому потребует времени.
В результате решил сделать отдельную страницу с просмотровщиком djvu и передачей пути к файлу через параметры.
С событиями пока не заморачивался, но очень не хватает полностраничного режима прям при открытии.
Масштаб по странице тоже очень нужная функция. На десктопе 100% выглядит очень мелко, на мобилке 100% – очень крупно.
Кроме того заметил, что используемый мной tailwind создает некоторые артефакты на интерфейсе вашего компонента. Видимо, потому что в css у вас не всё прописано, а ведь что-то tailwind из стилей по умолчанию сбрасывает.
Могу я создать соответствующие issue?
Да, конечно.
issue для масштаба по странице уже есть https://github.com/RussCoder/djvujs/issues/38 Если это то, что вам нужно, просто поставьте +1 туда или комментарий добавьте.
Спасибо, написал, поставил.
С монтированием скрипта в приложение next.js пришлось немного повозиться. Вот (вроде бы) рабочий вариант:
"use client";
import { useEffect } from "react";
const DjvuViewer = ({ searchParams }) => {
const viewerConfig = {
language: "ru",
uiOptions: {
changePageOnScroll: true,
},
};
useEffect(() => {
const checkScriptsLoaded = () => {
if (!document.querySelector("script[src='/scripts/djvu.js']")) {
const djvuLibJs = document.createElement("script");
djvuLibJs.src = "/scripts/djvu.js";
djvuLibJs.async = true;
document.body.appendChild(djvuLibJs);
}
if (!document.querySelector("script[src='/scripts/djvu_viewer.js']")) {
const viewerJs = document.createElement("script");
viewerJs.src = "/scripts/djvu_viewer.js";
viewerJs.async = true;
document.body.appendChild(viewerJs);
}
if (typeof DjVu !== "undefined" && typeof DjVu.Viewer !== "undefined") {
window.ViewerInstance = new DjVu.Viewer();
window.ViewerInstance.render(document.querySelector("#vw"));
window.ViewerInstance.loadDocumentByUrl(
`/djvu/${searchParams.djvu}`,
viewerConfig
);
} else {
setTimeout(checkScriptsLoaded, 200);
}
};
checkScriptsLoaded();
}, [searchParams]);
return (
<>
<div id="vw"></div>
</>
);
};
export default DjvuViewer;
Еще был вариант с компонентом
import Script from 'next/script'
но я его не стал проверять.
Есть ли возможность установки viewer'а из npm? Хочу использовать в react-приложении на next.js. Там сработала бы оптимизация. Ещё есть вариант затащить исходники в проект.