onFontSizeChange(Number(e.target.value))}
className="w-full"
/>
@@ -256,9 +354,15 @@ function SettingsPanel({
{/* Line Height */}
-
+
onLineHeightChange(Number(e.target.value))}
className="w-full"
/>
@@ -266,9 +370,14 @@ function SettingsPanel({
{/* Margin */}
-
+
onMarginChange(Number(e.target.value))}
className="w-full"
/>
@@ -276,15 +385,23 @@ function SettingsPanel({
{/* Font Family */}
-
+
@@ -297,7 +414,10 @@ function SettingsPanel({
interface PdfViewerProps {
url: string;
currentPage: number;
- onPdfLoaded: (info: { totalPages: number; outline: Array<{ title: string; page: number }> }) => void;
+ onPdfLoaded: (info: {
+ totalPages: number;
+ outline: Array<{ title: string; page: number }>;
+ }) => void;
}
function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
@@ -344,20 +464,27 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
for (const item of rawOutline) {
let pageNum = 1;
if (item.dest) {
- const dest = Array.isArray(item.dest) ? item.dest[0] : item.dest;
- if (typeof dest === 'string' && dests[dest]) {
- const destRef = Array.isArray(dests[dest]) ? dests[dest][0] : dests[dest];
+ const dest = Array.isArray(item.dest)
+ ? item.dest[0]
+ : item.dest;
+ if (typeof dest === "string" && dests[dest]) {
+ const destRef = Array.isArray(dests[dest])
+ ? dests[dest][0]
+ : dests[dest];
pageNum = (await pdf.getPageIndex(destRef)) + 1;
- } else if (dest && typeof dest === 'object' && 'num' in dest) {
+ } else if (dest && typeof dest === "object" && "num" in dest) {
pageNum = (await pdf.getPageIndex(dest)) + 1;
}
}
- outlineItems.push({ title: item.title || '未命名', page: pageNum });
+ outlineItems.push({
+ title: item.title || "未命名",
+ page: pageNum,
+ });
}
outline = outlineItems;
}
} catch (e) {
- console.warn('Failed to extract PDF outline:', e);
+ console.warn("Failed to extract PDF outline:", e);
}
onPdfLoaded({ totalPages: pdf.numPages, outline });
@@ -367,7 +494,7 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
}
} catch (err: any) {
if (!cancelled) {
- setError(err.message || '加载 PDF 失败');
+ setError(err.message || "加载 PDF 失败");
setLoading(false);
}
}
@@ -414,7 +541,7 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
try {
const page = await pdf.getPage(currentPage);
- const context = canvas.getContext('2d');
+ const context = canvas.getContext("2d");
if (!context) return;
const scale = calculateScale();
@@ -429,12 +556,15 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
// Clear and render
context.clearRect(0, 0, canvas.width, canvas.height);
- renderTaskRef.current = page.render({ canvasContext: context, viewport });
+ renderTaskRef.current = page.render({
+ canvasContext: context,
+ viewport,
+ });
await renderTaskRef.current.promise;
renderTaskRef.current = null;
} catch (err: any) {
- if (err.name !== 'RenderingCancelledException') {
- setError(err.message || '渲染页面失败');
+ if (err.name !== "RenderingCancelledException") {
+ setError(err.message || "渲染页面失败");
}
}
};
@@ -458,7 +588,7 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
}
try {
const page = await pdf.getPage(currentPage);
- const context = canvas.getContext('2d');
+ const context = canvas.getContext("2d");
if (!context) return;
const scale = calculateScale();
const viewport = page.getViewport({ scale });
@@ -467,12 +597,15 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
canvas.style.width = `${viewport.width}px`;
canvas.style.height = `${viewport.height}px`;
context.clearRect(0, 0, canvas.width, canvas.height);
- renderTaskRef.current = page.render({ canvasContext: context, viewport });
+ renderTaskRef.current = page.render({
+ canvasContext: context,
+ viewport,
+ });
await renderTaskRef.current.promise;
renderTaskRef.current = null;
} catch (err: any) {
- if (err.name !== 'RenderingCancelledException') {
- console.error('Resize render error:', err);
+ if (err.name !== "RenderingCancelledException") {
+ console.error("Resize render error:", err);
}
}
};
@@ -480,25 +613,30 @@ function PdfViewer({ url, currentPage, onPdfLoaded }: PdfViewerProps) {
}
};
- window.addEventListener('resize', handleResize);
- return () => window.removeEventListener('resize', handleResize);
+ window.addEventListener("resize", handleResize);
+ return () => window.removeEventListener("resize", handleResize);
}, [ready, currentPage, calculateScale]);
return (
-
+
{loading && (
-
加载 PDF 中...
+
+ 加载 PDF 中...
+
)}
@@ -568,8 +706,11 @@ function ReaderControls({
onMouseEnterBottom,
onMouseLeaveBottom,
}: ReaderControlsProps) {
- const progress = totalChapters > 0 ? Math.round(((currentChapter + 1) / totalChapters) * 100) : 0;
- const barTransition = 'transform 0.3s ease-in-out';
+ const progress =
+ totalChapters > 0
+ ? Math.round(((currentChapter + 1) / totalChapters) * 100)
+ : 0;
+ const barTransition = "transform 0.3s ease-in-out";
return (
<>
@@ -581,7 +722,10 @@ function ReaderControls({
>