@agilehub/vue-pdf-flipbook 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ import type { ReaderMode } from './types';
2
+ /**
3
+ * 按容器与 PDF 比例适配书页,双页宽度对齐整数像素。
4
+ * 调用逻辑:useBookLayout 在初始化、容器变化及模式切换时调用。
5
+ * @param width 可用容器宽度,CSS 像素。
6
+ * @param height 可用容器高度,CSS 像素。
7
+ * @param pageWidth PDF 原始页宽。
8
+ * @param pageHeight PDF 原始页高。
9
+ * @param mode 用户选择的模式;宽度不足 520px 时双页退为单页。
10
+ * @returns 包含书页容器 width、height 和实际 orientation 的对象。
11
+ */
12
+ export declare function fitBook(width: number, height: number, pageWidth: number, pageHeight: number, mode: ReaderMode): {
13
+ width: number;
14
+ height: number;
15
+ orientation: ReaderMode;
16
+ };
@@ -0,0 +1,27 @@
1
+ import type { PDFDocumentProxy } from 'pdfjs-dist';
2
+ type __VLS_Props = {
3
+ pdf: PDFDocumentProxy;
4
+ pageNumber: number;
5
+ renderScale?: number;
6
+ ariaLabel?: string;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ rendered: (payload: {
10
+ page: number;
11
+ width: number;
12
+ height: number;
13
+ }) => any;
14
+ error: (error: unknown) => any;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ onRendered?: ((payload: {
17
+ page: number;
18
+ width: number;
19
+ height: number;
20
+ }) => any) | undefined;
21
+ onError?: ((error: unknown) => any) | undefined;
22
+ }>, {
23
+ renderScale: number;
24
+ ariaLabel: string;
25
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const _default: typeof __VLS_export;
27
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import type { PDFDocumentProxy } from 'pdfjs-dist';
2
+ import type { PdfThumbnailSlotProps } from '../types';
3
+ type __VLS_Props = {
4
+ pdf: PDFDocumentProxy;
5
+ pages: number;
6
+ visiblePages: number[];
7
+ readyPages: ReadonlySet<number>;
8
+ compact?: boolean;
9
+ pageAspectRatio?: number;
10
+ };
11
+ type __VLS_Slots = {
12
+ thumbnail?: (props: PdfThumbnailSlotProps) => unknown;
13
+ };
14
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ error: (error: unknown) => any;
16
+ select: (page: number) => any;
17
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
+ onError?: ((error: unknown) => any) | undefined;
19
+ onSelect?: ((page: number) => any) | undefined;
20
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
24
+ type __VLS_WithSlots<T, S> = T & {
25
+ new (): {
26
+ $slots: S;
27
+ };
28
+ };
@@ -0,0 +1,28 @@
1
+ import type { PdfFlipbookProps, PdfFlipbookState, ReaderMode } from '../types';
2
+ export interface PageSize {
3
+ width: number;
4
+ height: number;
5
+ }
6
+ export type ResolvedFlipbookProps = Readonly<PdfFlipbookProps & Required<Pick<PdfFlipbookProps, 'initialPage' | 'initialMode' | 'height' | 'background' | 'workerSrc'>>>;
7
+ export type FlipbookEvents = {
8
+ loaded: [payload: {
9
+ pages: number;
10
+ }];
11
+ error: [error: unknown];
12
+ 'page-change': [page: number];
13
+ 'mode-change': [mode: ReaderMode];
14
+ 'state-change': [state: PdfFlipbookState];
15
+ progress: [progress: number];
16
+ };
17
+ export type FlipbookEmit = <K extends keyof FlipbookEvents>(event: K, ...args: FlipbookEvents[K]) => void;
18
+ export interface FlipEnginePort {
19
+ /** 导航层调用;无参数,返回引擎是否已创建,未就绪时不启动翻页。 */
20
+ isReady: () => boolean;
21
+ /**
22
+ * 导航完成页面准备后调用适配层启动动画。
23
+ * @param pageIndex 零基目标页索引,调用前由导航层转换一基页码。
24
+ * @param corner 起翻页角,top 为上角,bottom 为下角。
25
+ * @returns void;动画状态通过引擎事件另行同步。
26
+ */
27
+ flip: (pageIndex: number, corner: 'top' | 'bottom') => void;
28
+ }
@@ -0,0 +1,27 @@
1
+ import type { Ref } from 'vue';
2
+ import type { ReaderMode } from '../types';
3
+ import type { PageSize } from './types';
4
+ interface LayoutOptions {
5
+ viewport: Ref<HTMLElement | undefined>;
6
+ bookStage: Ref<HTMLElement | undefined>;
7
+ pageSize: Readonly<Ref<PageSize>>;
8
+ mode: Readonly<Ref<ReaderMode>>;
9
+ onUpdate: () => void;
10
+ }
11
+ /**
12
+ * 观察容器尺寸并计算保持比例的书页布局。
13
+ * 调用逻辑:由协调层创建;挂载后监听窗口和容器尺寸变化,销毁时移除监听。
14
+ * @param options 容器 ref、PDF 尺寸、阅读模式和引擎更新回调。
15
+ * @returns 书页样式、实际方向以及 fit/reset 方法。
16
+ */
17
+ export declare function useBookLayout(options: LayoutOptions): {
18
+ bookShellStyle: import("vue").ComputedRef<{
19
+ width: string;
20
+ height: string;
21
+ }>;
22
+ orientation: Ref<ReaderMode, ReaderMode>;
23
+ fit: () => void;
24
+ /** 文档重置时调用;无参数,返回 void,将旧书页尺寸清零。 */
25
+ reset: () => void;
26
+ };
27
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { Ref } from 'vue';
2
+ import type { ReaderMode } from '../types';
3
+ import type { PageSize } from './types';
4
+ interface EngineEvents {
5
+ onFlip: (pageIndex: number) => void;
6
+ onStateChange: (state: string) => void;
7
+ onOrientationChange: (mode: ReaderMode) => void;
8
+ canStartUserTurn: (forward: boolean, prepare?: boolean) => boolean;
9
+ getLayoutMode: () => ReaderMode;
10
+ }
11
+ /**
12
+ * 封装 PageFlip 实例、输入拦截和临时 Canvas 克隆。
13
+ * 调用逻辑:由协调层创建,在文档就绪时 initialize,尺寸变化时 update。
14
+ * @param flipbookElement 书页根元素 ref,由组件模板绑定。
15
+ * @param events 导航通知、手势准入和实际布局模式回调。
16
+ * @returns 初始化、销毁、尺寸更新、就绪检测和翻页接口。
17
+ */
18
+ export declare function usePageFlip(flipbookElement: Ref<HTMLElement | undefined>, events: EngineEvents): {
19
+ initialize: (pageSize: PageSize, pageCount: number, currentPage: number) => void;
20
+ destroy: () => void;
21
+ /** 导航层翻页前调用;无参数,返回引擎实例是否存在。 */
22
+ isReady: () => boolean;
23
+ update: () => void;
24
+ /** 导航准备完成后调用;pageIndex 为零基目标索引,corner 为起翻页角;返回 void。 */
25
+ flip: (pageIndex: number, corner: "top" | "bottom") => void | undefined;
26
+ };
27
+ export {};
@@ -0,0 +1,48 @@
1
+ import type { Ref } from 'vue';
2
+ import type { ReaderMode } from '../types';
3
+ import type { FlipEnginePort } from './types';
4
+ interface NavigationOptions {
5
+ pageCount: Readonly<Ref<number>>;
6
+ loading: Readonly<Ref<boolean>>;
7
+ initialMode: ReaderMode;
8
+ debounceMs?: number;
9
+ engine: FlipEnginePort;
10
+ onError: (error: unknown) => void;
11
+ onPageChange: (page: number) => void;
12
+ onModeChange: (mode: ReaderMode) => void;
13
+ }
14
+ /**
15
+ * 管理页码、预览窗口、防抖和翻页状态。
16
+ * 调用逻辑:usePdfFlipbook 在组件 setup 阶段创建;所有导航入口在此汇合。
17
+ * @param options 文档响应式状态、引擎接口、事件回调及可选防抖时间(当前默认 150ms)。
18
+ * @returns 只读状态、页面挂载集合和导航方法。
19
+ */
20
+ export declare function usePageNavigation(options: NavigationOptions): {
21
+ currentPage: Readonly<Ref<number, number>>;
22
+ mode: Readonly<Ref<ReaderMode, ReaderMode>>;
23
+ orientation: Readonly<Ref<ReaderMode, ReaderMode>>;
24
+ pendingPage: Readonly<Ref<number | undefined, number | undefined>>;
25
+ pageLoading: Readonly<Ref<boolean, boolean>>;
26
+ visiblePages: import("vue").ComputedRef<number[]>;
27
+ activePages: import("vue").ComputedRef<Set<number>>;
28
+ renderPages: import("vue").ComputedRef<Set<number>>;
29
+ thumbnailReadyPages: import("vue").ComputedRef<Set<number>>;
30
+ canPrevious: import("vue").ComputedRef<boolean>;
31
+ canNext: import("vue").ComputedRef<boolean>;
32
+ next: () => void;
33
+ previous: () => void;
34
+ goToPage: (page: number) => Promise<void>;
35
+ changeMode: (value: ReaderMode) => boolean;
36
+ initializePage: (page: number) => void;
37
+ reset: () => void;
38
+ cancelPreparation: (clearTarget?: boolean) => void;
39
+ canStartUserTurn: (forward: boolean, prepare?: boolean) => boolean;
40
+ onPageRendered: ({ page }: {
41
+ page: number;
42
+ }) => void;
43
+ onPageError: (page: number, error: unknown) => void;
44
+ syncCurrentPage: (pageIndex: number) => void;
45
+ onFlipStateChange: (state: string) => void;
46
+ onOrientationChange: (value: ReaderMode) => void;
47
+ };
48
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { PDFDocumentProxy } from 'pdfjs-dist';
2
+ import type { ResolvedFlipbookProps } from './types';
3
+ interface DocumentEvents {
4
+ onReset: () => void;
5
+ onRangeError: () => void;
6
+ onReady: (document: PDFDocumentProxy, isCurrent: () => boolean) => Promise<void>;
7
+ onProgress: (progress: number) => void;
8
+ onError: (error: unknown) => void;
9
+ }
10
+ /**
11
+ * 管理 PDF 文档会话、加载进度、错误与销毁。
12
+ * 调用逻辑:协调层创建后,在挂载、URL 变化和 reload 时调用 load。
13
+ * @param props 组件 URL、文件大小和 Worker 等配置。
14
+ * @param events 文档重置、就绪、进度与错误回调。
15
+ * @returns 只读文档状态及 load 方法。
16
+ */
17
+ export declare function usePdfDocument(props: ResolvedFlipbookProps, events: DocumentEvents): {
18
+ pdf: Readonly<import("vue").ShallowRef<import("pdfjs-dist/types/src/display/api").PDFDocumentProxy | undefined, import("pdfjs-dist/types/src/display/api").PDFDocumentProxy | undefined>>;
19
+ pageCount: Readonly<import("vue").Ref<number, number>>;
20
+ pageSize: Readonly<import("vue").Ref<{
21
+ readonly width: number;
22
+ readonly height: number;
23
+ }, {
24
+ readonly width: number;
25
+ readonly height: number;
26
+ }>>;
27
+ loading: Readonly<import("vue").Ref<boolean, boolean>>;
28
+ loadProgress: Readonly<import("vue").Ref<number, number>>;
29
+ errorMessage: Readonly<import("vue").Ref<string, string>>;
30
+ load: () => Promise<void>;
31
+ };
32
+ export {};
@@ -0,0 +1,38 @@
1
+ import type { PdfFlipbookExpose, ReaderMode } from '../types';
2
+ import type { FlipbookEmit, ResolvedFlipbookProps } from './types';
3
+ /**
4
+ * 作为外观层组合文档、导航、布局与翻页引擎。
5
+ * 调用逻辑:VuePdfFlipbook.vue 的 setup 调用,模板和 defineExpose 使用其结果。
6
+ * @param props 已填充默认值的组件属性。
7
+ * @param emit 类型化组件事件发送函数。
8
+ * @returns 模板所需 ref、事件处理方法和公开实例 API。
9
+ */
10
+ export declare function usePdfFlipbook(props: ResolvedFlipbookProps, emit: FlipbookEmit): {
11
+ viewport: import("vue").Ref<HTMLElement | undefined, HTMLElement | undefined>;
12
+ bookStage: import("vue").Ref<HTMLElement | undefined, HTMLElement | undefined>;
13
+ flipbookElement: import("vue").Ref<HTMLElement | undefined, HTMLElement | undefined>;
14
+ rootHeight: import("vue").ComputedRef<string>;
15
+ bookRevision: import("vue").Ref<number, number>;
16
+ api: PdfFlipbookExpose;
17
+ thumbnailsVisible: import("vue").Ref<boolean, boolean>;
18
+ pageAspectRatio: import("vue").ComputedRef<number>;
19
+ visiblePages: import("vue").ComputedRef<number[]>;
20
+ canPrevious: import("vue").ComputedRef<boolean>;
21
+ canNext: import("vue").ComputedRef<boolean>;
22
+ bookShellStyle: import("vue").ComputedRef<{
23
+ width: string;
24
+ height: string;
25
+ }>;
26
+ pdf: Readonly<import("vue").ShallowRef<import("pdfjs-dist/types/src/display/api").PDFDocumentProxy | undefined, import("pdfjs-dist/types/src/display/api").PDFDocumentProxy | undefined>>;
27
+ loading: Readonly<import("vue").Ref<boolean, boolean>>;
28
+ pageCount: Readonly<import("vue").Ref<number, number>>;
29
+ pageLoading: Readonly<import("vue").Ref<boolean, boolean>>;
30
+ mode: Readonly<import("vue").Ref<ReaderMode, ReaderMode>>;
31
+ activePages: import("vue").ComputedRef<Set<number>>;
32
+ renderPages: import("vue").ComputedRef<Set<number>>;
33
+ thumbnailReadyPages: import("vue").ComputedRef<Set<number>>;
34
+ onPageRendered: ({ page }: {
35
+ page: number;
36
+ }) => void;
37
+ onPageError: (page: number, error: unknown) => void;
38
+ };
@@ -0,0 +1,26 @@
1
+ import type { PDFDocumentProxy } from 'pdfjs-dist';
2
+ interface CanvasOptions {
3
+ pdf: PDFDocumentProxy;
4
+ pageNumber: number;
5
+ renderScale: number;
6
+ }
7
+ interface CanvasEvents {
8
+ onRendered: (payload: {
9
+ page: number;
10
+ width: number;
11
+ height: number;
12
+ }) => void;
13
+ onError: (error: unknown) => void;
14
+ }
15
+ /**
16
+ * 管理单页 Canvas 渲染、过期任务取消和共享资源引用。
17
+ * 调用逻辑:PdfCanvasPage.vue 在 setup 调用;属性变化自动触发 renderPage。
18
+ * @param props PDF 文档、页码和渲染倍率等响应式属性。
19
+ * @param events 渲染完成与失败回调。
20
+ * @returns canvas 模板 ref 和 rendering 状态。
21
+ */
22
+ export declare function usePdfPageCanvas(props: Readonly<CanvasOptions>, events: CanvasEvents): {
23
+ canvas: import("vue").Ref<HTMLCanvasElement | undefined, HTMLCanvasElement | undefined>;
24
+ rendering: import("vue").Ref<boolean, boolean>;
25
+ };
26
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Plugin } from 'vue';
2
+ import VuePdfFlipbook from './VuePdfFlipbook.vue';
3
+ import './style.css';
4
+ export type { PdfFlipbookExpose, PdfFlipbookProps, PdfFlipbookState, PdfThumbnailSlotProps, ReaderMode } from './types';
5
+ export { VuePdfFlipbook };
6
+ export { default as PdfCanvasPage } from './components/PdfCanvasPage.vue';
7
+ declare const plugin: Plugin;
8
+ export default plugin;
@@ -0,0 +1,8 @@
1
+ import type { PDFPageProxy } from 'pdfjs-dist';
2
+ /**
3
+ * 增加共享 PDF 页面引用,防止缩略图卸载时清理正文仍在使用的资源。
4
+ * 调用逻辑:Canvas 获取页面后调用,任务结束或卸载时调用返回的释放函数。
5
+ * @param page PDF.js 返回的共享页面代理对象。
6
+ * @returns 无参数、返回 void 的幂等释放函数;最后一个使用者释放时执行 cleanup。
7
+ */
8
+ export declare function retainPage(page: PDFPageProxy): () => void;
@@ -0,0 +1,29 @@
1
+ import type { ReaderMode } from './types';
2
+ /**
3
+ * 计算指定页码所在的可见页组并裁剪文档边界。
4
+ * 调用逻辑:导航状态计算和翻页必需页计算调用。
5
+ * @param page 一基页码。
6
+ * @param pages 总页数。
7
+ * @param mode 实际单页或双页模式。
8
+ * @returns 一基页码数组;空文档返回空数组。
9
+ */
10
+ export declare function getVisiblePages(page: number, pages: number, mode: ReaderMode): number[];
11
+ /**
12
+ * 合并起点、终点及翻页动画背面所需页码。
13
+ * 调用逻辑:跳页准备、渲染优先级和原生手势准入共用。
14
+ * @param from 起点一基页码。
15
+ * @param to 目标一基页码。
16
+ * @param pages 总页数。
17
+ * @param mode 实际阅读模式。
18
+ * @returns 去重的一基页码数组。
19
+ */
20
+ export declare function getTurnPages(from: number, to: number, pages: number, mode: ReaderMode): number[];
21
+ /**
22
+ * 获取可见页及前后各 5 页的预览窗口。
23
+ * 调用逻辑:正文和缩略图共用,限制 Canvas 挂载范围。
24
+ * @param page 中心一基页码。
25
+ * @param pages 总页数。
26
+ * @param mode 实际阅读模式。
27
+ * @returns 边界裁剪后的连续页码数组。
28
+ */
29
+ export declare function getPageWindow(page: number, pages: number, mode: ReaderMode): number[];
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 将可校验的分段数据源适配为 PDF.js 数据传输对象。
3
+ * 调用逻辑:usePdfDocument.load 建立文档前调用。
4
+ * @param url PDF 地址。
5
+ * @param controller 控制本轮所有网络请求的 AbortController。
6
+ * @param onError 未取消的分段失败回调。
7
+ * @param fileSize 可选原始文件大小。
8
+ * @returns Promise<PDFDataRangeTransport>,包含首段数据且关闭流式加载。
9
+ */
10
+ export declare function createPdfRangeTransport(url: string, controller: AbortController, onError: (error: unknown) => void, fileSize?: number): Promise<{
11
+ /**
12
+ * 按 PDF.js 请求读取字节段,完成后通知 onDataRange。
13
+ * 调用逻辑:由 PDF.js 在解析文档、页面和共享资源时调用。
14
+ * @param begin 包含的起始字节偏移。
15
+ * @param end 不包含的结束字节偏移。
16
+ * @returns void;网络任务异步执行,失败通过 onError 通知。
17
+ */
18
+ requestDataRange(begin: number, end: number): void;
19
+ /**
20
+ * 中止本轮文档的全部分段请求。
21
+ * 调用逻辑:PDF.js 销毁传输对象时调用,复用会话 AbortController。
22
+ * 参数:无。
23
+ * @returns void。
24
+ */
25
+ abort(): void;
26
+ length: number;
27
+ initialData: Uint8Array<ArrayBufferLike> | null;
28
+ progressiveDone: boolean;
29
+ contentDispositionFilename: string;
30
+ onDataRange(begin: number, chunk: Uint8Array | null): void;
31
+ onDataProgressiveRead(chunk: Uint8Array | null): void;
32
+ onDataProgressiveDone(): void;
33
+ transportReady(listener: any): void;
34
+ "__#private@#private": any;
35
+ }>;
@@ -0,0 +1,21 @@
1
+ export declare const rangeChunkSize: number;
2
+ /**
3
+ * 通过首段请求建立可校验的 PDF 字节数据源。
4
+ * 调用逻辑:由 createPdfRangeTransport 调用,不使用 HEAD 猜测长度,不回退全文下载。
5
+ * @param url PDF 地址。
6
+ * @param signal 会话取消信号,传递给所有请求。
7
+ * @param fileSize 可选原始文件字节数,用于响应头未暴露时。
8
+ * @returns Promise,解析为文件总长度、首段数据及 read(begin, end) 方法。
9
+ */
10
+ export declare function openRangeSource(url: string, signal: AbortSignal, fileSize?: number): Promise<{
11
+ length: number;
12
+ initialData: Uint8Array<ArrayBufferLike>;
13
+ /**
14
+ * 按需读取后续字节段,并验证响应范围与文档总长度。
15
+ * 调用逻辑:PDFDataRangeTransport 的 requestDataRange 调用。
16
+ * @param begin 包含的起始偏移。
17
+ * @param end 不包含的结束偏移。
18
+ * @returns Promise<Uint8Array>;参数或服务器响应不符时拒绝。
19
+ */
20
+ read(begin: number, end: number): Promise<Uint8Array<ArrayBufferLike>>;
21
+ }>;
@@ -0,0 +1,66 @@
1
+ import type { PDFDocumentProxy } from 'pdfjs-dist';
2
+ export type ReaderMode = 'single' | 'double';
3
+ export interface PdfThumbnailSlotProps {
4
+ page: number;
5
+ pdf: PDFDocumentProxy;
6
+ isActive: boolean;
7
+ /** 位于预览窗口且正文已渲染完成;外部插槽据此延迟创建缩略图 Canvas。 */
8
+ shouldRender: boolean;
9
+ }
10
+ export interface PdfFlipbookProps {
11
+ url: string;
12
+ /** PDF 原始字节数;CORS 未暴露 Content-Range 时用于确定分段边界。 */
13
+ fileSize?: number;
14
+ initialPage?: number;
15
+ initialMode?: ReaderMode;
16
+ /** 默认填满已设置高度的父容器;数值按像素处理。 */
17
+ height?: string | number;
18
+ background?: string;
19
+ workerSrc?: string;
20
+ }
21
+ export interface PdfFlipbookState {
22
+ page: number;
23
+ pages: number;
24
+ mode: ReaderMode;
25
+ visiblePages: number[];
26
+ loading: boolean;
27
+ /** 翻页前正在等待目标页下载或渲染,可供外部展示加载状态。 */
28
+ pageLoading: boolean;
29
+ /** 准备或动画期间的目标页码;没有待处理目标时为 null。 */
30
+ targetPage: number | null;
31
+ progress: number;
32
+ error: string;
33
+ canPrevious: boolean;
34
+ canNext: boolean;
35
+ thumbnailsVisible: boolean;
36
+ }
37
+ export interface PdfFlipbookExpose {
38
+ /** 外部通过组件 ref 调用以显示缩略图;无参数,返回 void,更新 thumbnailsVisible。 */
39
+ showThumbnails: () => void;
40
+ /** 外部通过组件 ref 调用以隐藏缩略图;无参数,返回 void,更新 thumbnailsVisible。 */
41
+ hideThumbnails: () => void;
42
+ /** 外部调用后交给导航层请求下一页组;无参数,返回 void,末页不执行。 */
43
+ next: () => void;
44
+ /** 外部调用后交给导航层请求上一页组;无参数,返回 void,首页不执行。 */
45
+ previous: () => void;
46
+ /**
47
+ * 请求跳页,内部依次执行防抖、必需页准备和翻页。
48
+ * 调用逻辑:外部页码输入、缩略图或其他导航控件通过组件 ref 调用。
49
+ * @param page 一基目标页码,自动取整并限制范围。
50
+ * @returns Promise<void>;动画启动或请求取消/忽略后完成,不等待动画结束。
51
+ */
52
+ goToPage: (page: number) => Promise<void>;
53
+ /**
54
+ * 切换阅读模式并重新适配布局和引擎。
55
+ * 调用逻辑:由外部模式控件通过组件 ref 调用。
56
+ * @param mode single 为单页,double 为双页;实际显示还受容器宽度限制。
57
+ * @returns Promise<void>;布局更新完成或模式未变化时结束。
58
+ */
59
+ setMode: (mode: ReaderMode) => Promise<void>;
60
+ /** 外部重试时调用文档加载流程;无参数,返回 Promise<void>,错误通过 error 事件报告。 */
61
+ reload: () => Promise<void>;
62
+ /** 外部主动查询状态时调用;无参数,返回 PdfFlipbookState 快照,不暴露内部 ref。 */
63
+ getState: () => PdfFlipbookState;
64
+ /** 外部自定义预览时调用;无参数,返回借用的 PDF 文档或 undefined;文档由组件销毁,外部勿调用 destroy。 */
65
+ getDocument: () => PDFDocumentProxy | undefined;
66
+ }
@@ -0,0 +1,2 @@
1
+ .thumbnail-container[data-v-025f840c]{width:100%;position:relative}.page-num[data-v-025f840c]{pointer-events:none;z-index:9;background:#b5b5b540;padding:2px 4px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.vpf-reader,.vpf-reader *{box-sizing:border-box}.vpf-reader{width:100%;height:var(--vpf-height,100%);background:var(--vpf-background,transparent);flex-direction:column;min-width:0;min-height:0;display:flex;overflow:hidden}.vpf-viewport{flex:1;width:100%;min-height:0;position:relative;overflow:hidden}.vpf-page-nav{z-index:10;color:#fff;cursor:pointer;opacity:0;pointer-events:none;background:#141c1bbf;border:1px solid #ffffff40;border-radius:8px;place-items:center;width:44px;height:56px;padding:10px;transition:opacity .15s,background .15s;display:grid;position:absolute;top:50%;transform:translateY(-50%)}.vpf-page-nav--previous{left:12px}.vpf-page-nav--next{right:12px}.vpf-page-nav svg{fill:none;stroke:currentColor;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;width:24px;height:24px}.vpf-viewport:hover .vpf-page-nav,.vpf-viewport:focus-within .vpf-page-nav{opacity:1;pointer-events:auto}.vpf-page-nav:hover:not(:disabled){background:#141c1bf2}.vpf-page-nav:focus-visible{outline-offset:2px;outline:2px solid #fff}.vpf-viewport:hover .vpf-page-nav:disabled,.vpf-viewport:focus-within .vpf-page-nav:disabled{opacity:.35;cursor:default}@media (hover:none){.vpf-page-nav{opacity:1;pointer-events:auto}.vpf-page-nav:disabled{opacity:.35}}@media (prefers-reduced-motion:reduce){.vpf-page-nav{transition:none}}.vpf-thumbnails{background:#edf0eb;flex:none;gap:12px;max-height:35%;padding:10px;display:flex;overflow:auto}.vpf-thumbnails,.vpf-default-thumbnails{scrollbar-width:thin;scrollbar-color:#a5aea8 transparent}.vpf-thumbnails:hover,.vpf-thumbnails:focus-within,.vpf-default-thumbnails:hover{scrollbar-color:#7d8b82 transparent}@supports selector(::-webkit-scrollbar){.vpf-thumbnails,.vpf-default-thumbnails,.vpf-thumbnails:hover,.vpf-thumbnails:focus-within,.vpf-default-thumbnails:hover{scrollbar-width:auto;scrollbar-color:auto}.vpf-thumbnails::-webkit-scrollbar{width:8px;height:8px}.vpf-default-thumbnails::-webkit-scrollbar{width:8px;height:8px}.vpf-thumbnails::-webkit-scrollbar-track{background:0 0}.vpf-default-thumbnails::-webkit-scrollbar-track{background:0 0}.vpf-thumbnails::-webkit-scrollbar-thumb{background:#a5aea8 padding-box padding-box;border:2px solid #0000;border-radius:999px;min-width:32px}.vpf-default-thumbnails::-webkit-scrollbar-thumb{background:#a5aea8 padding-box padding-box;border:2px solid #0000;border-radius:999px;min-width:32px}.vpf-thumbnails::-webkit-scrollbar-thumb:hover{background-color:#7d8b82}.vpf-default-thumbnails::-webkit-scrollbar-thumb:hover{background-color:#7d8b82}.vpf-thumbnails::-webkit-scrollbar-thumb:active{background-color:#5f7165}.vpf-default-thumbnails::-webkit-scrollbar-thumb:active{background-color:#5f7165}.vpf-thumbnails::-webkit-scrollbar-button{width:0;height:0;display:none}.vpf-default-thumbnails::-webkit-scrollbar-button{width:0;height:0;display:none}.vpf-thumbnails::-webkit-scrollbar-corner{background:0 0}.vpf-default-thumbnails::-webkit-scrollbar-corner{background:0 0}}.vpf-thumbnail{color:#333;cursor:pointer;font:inherit;background:#fff;border:2px solid #0000;flex:0 0 86px;padding:4px}.vpf-thumbnail[aria-current]{border-color:#987044}.vpf-thumbnail:focus-visible{outline-offset:-2px;outline:2px solid #987044}.vpf-thumbnail-preview{aspect-ratio:3/4;background:#fff;width:100%}.vpf-book-stage{flex-direction:column;justify-content:center;align-items:center;width:100%;height:100%;display:flex}.vpf-default-thumbnails{z-index:11;pointer-events:auto;background:#edf0ebd9;max-height:100%;position:absolute;bottom:0;left:0;right:0;overflow:auto}.vpf-thumbnails--compact{background:0 0;align-items:flex-start;gap:6px;max-height:none;padding:6px}.vpf-thumbnails--compact .vpf-thumbnail{border-width:1px;flex:0 0 30px;width:30px;min-width:0;padding:0;font-size:10px;line-height:16px}.vpf-book-shell{isolation:isolate;flex:none;position:relative}.vpf-flipbook.stf__parent{min-width:0!important;min-height:0!important}.vpf-flipbook{width:100%;height:100%;position:relative}.vpf-turn-page{color:#545454;transform-style:preserve-3d;backface-visibility:hidden;background:#fff;position:relative;box-shadow:inset 0 0 28px #2026250f;overflow:hidden!important}.vpf-turn-page:before{content:"";z-index:0;pointer-events:none;backface-visibility:hidden;background:#fff;position:absolute;inset:0}.vpf-turn-page.--left{border-radius:5px 0 0 5px}.vpf-turn-page.--right{border-radius:0 5px 5px 0}.vpf-book-stage.is-single .vpf-turn-page{border-radius:5px}.vpf-flipbook.stf__parent,.vpf-flipbook .stf__wrapper,.vpf-flipbook .stf__block{box-sizing:border-box}.vpf-flipbook .stf__wrapper{width:100%;height:100%;position:relative}.vpf-flipbook .stf__wrapper.--portrait{clip-path:inset(0)}.vpf-flipbook .stf__wrapper.--landscape:before{content:"";pointer-events:none;background:#fff;width:2px;position:absolute;top:0;bottom:0;left:calc(50% - 1px)}.vpf-flipbook .stf__block{perspective:2400px}.vpf-flipbook .stf__item{transform-style:preserve-3d;backface-visibility:hidden;will-change:transform, clip-path;position:absolute;background:#fff!important}.vpf-flipbook .stf__outerShadow,.vpf-flipbook .stf__innerShadow,.vpf-flipbook .stf__hardShadow,.vpf-flipbook .stf__hardInnerShadow{pointer-events:none;mix-blend-mode:normal}.vpf-page-canvas{z-index:1;background:#fff;width:100%;min-width:0;height:100%;max-height:100%;display:flex;position:relative}.vpf-page-canvas.is-rendering canvas{visibility:hidden}.vpf-reader .stf__parent .vpf-page-canvas canvas,.vpf-page-canvas canvas{object-fit:contain;background:#fff;width:100%;max-width:100%;height:100%;display:block;position:relative}
2
+ /*$vite$:1*/