import * as pdfjs_dist_types_src_display_api from 'pdfjs-dist/types/src/display/api'; import * as pdfjs_dist_types_src_display_display_utils from 'pdfjs-dist/types/src/display/display_utils'; import { EventEmitter } from '@dingrtc/shared'; type ImageScalingMode = 'auto' | 'fillWidth' | 'fillHeight'; declare enum ResizeType { width = 0, height = 1, widthAndHeight = 2, none = 3 } /** * 图形被选中时,在外部提示框上可以被按住拖动的点 * * @export * @class OutlineResizeHandle */ declare class OutlineResizeHandle { getX: () => number; getY: () => number; cursorStyle: string; resizeType: ResizeType; renderSelf: boolean; static ResizeType: typeof ResizeType; constructor(getX: () => number, getY: () => number, cursorStyle: string, resizeType: ResizeType, renderSelf?: boolean); /** * transparent 为 true 会绘制透明样式, 用于测算点位 * @param renderContext * @param transparent 是否应用透明样式 */ render(renderContext: CanvasRenderingContext2D, transparent: boolean, scale: number): void; isPointInShape(x: number, y: number): boolean; } /** * 基础图形点位描述 */ declare class Model { points: Point[]; /** * 图形点位模型 * @param points */ constructor(points: Point[]); setPoints(points: Point[]): void; setPointAtIndex(index: number, point: Point): void; get minx(): number; get miny(): number; get maxx(): number; get maxy(): number; get width(): number; get height(): number; /** * 中心点位置 */ get center(): { x: number; y: number; }; /** * 以当前图形中心点为圆心旋转 * @param angle */ rotate(angle: number): Point[]; } declare enum ShapeType { Click = "click", Select = "select", Pen = "pen", Line = "line", Rect = "rect", Square = "square", Ellipse = "ellipse", Circle = "circle", Text = "text", Triangle = "triangle",// 三角形 Rhombic = "rhombic",// 菱形 Arrow = "arrow", Delete = "delete", Image = "image", Stamp = "stamp", Video = "video", Audio = "audio", Eraser = "eraser", Brush = "eraser", EraserIndicator = "eraserIndicator", LaserPointer = "laserPointer", Cursor = "cursor", Drag = "drag" } declare enum ShapeOrderType { back = "back", front = "front", normal = "normal", bg = "bg" } declare enum ShapeVisibleType { invisible = "0", visible = "1" } declare enum InteractionStatusType { default = 0, focused = 1, selected = 2, resizing = 3, rotating = 4, willBeDeleted = 5 } /** * 图形消息 */ interface IShapeData { name: string; pageId: string; shape: ShapeType; order: ShapeOrderType; orderTime: string; text?: string; data: string; visible: ShapeVisibleType; style?: string; font?: string; image?: string; video?: string; audio?: string; } /** * 图形消息 */ interface IShapeRgnData { name: string; pageId: string; shape: ShapeType; rgn: string; } /** * 所有图形的基础类型 * * shape 通过 shapeId + creator 唯一确定 */ declare abstract class BaseShape extends EventEmitter<{ requestRender: (shape: BaseShape) => void; }> { shapeId: string; readonly creator: string; readonly pageId: string; static GIF_RENDER_RATE: number; hash: number; get shouldRenderOutline(): boolean; protected emitRenderRequest(): void; private _order; get order(): ShapeOrderType; set order(order: ShapeOrderType); private _orderTime; get orderTime(): number; set orderTime(orderTime: number); rngReverse: { xReversed: boolean; yReversed: boolean; }; transformOriginalInfo?: BaseShape; resizeStartHandle?: Point & { resizeType: ResizeType; index: number; }; resizeOriginPosition?: Point; protected _visible: boolean; get visible(): boolean; set visible(visible: boolean); abstract get shapeType(): ShapeType; abstract clone(userId: string, shapeId: string): BaseShape; protected _interactionStatus: InteractionStatusType; get interactionStatus(): InteractionStatusType; set interactionStatus(interactionStatus: InteractionStatusType); get points(): Point[]; set points(points: Point[]); protected model: Model; /** * 用于消息通信时传输的 shape 序列号 */ get shapeSeq(): string; /** * @param points 图形点位信息 * @param shapeId 图形序列 * @param creator 创建者 uid * @param pageId 所属页面 id,不设置表示图形不属于任何页面 */ constructor(points: Point[], shapeId: string, creator: string, pageId?: string); /** * 是否可以被选中 */ abstract shouldSelectAfterAdd(): boolean; render(ctx: CanvasRenderingContext2D, options: { viewport: { minx: number; miny: number; maxx: number; maxy: number; }; scale: number; translate: number[]; wrapperDom: HTMLElement; lineWidth: number; insertType: ShapeType; forceRenderText: boolean; }): void; /** * 渲染图形(不包括边框和形变抓手按钮) * @param renderContext * @param options */ protected abstract renderShape(renderContext: CanvasRenderingContext2D, options: { viewport: { minx: number; miny: number; maxx: number; maxy: number; }; scale: number; translate: number[]; wrapperDom: HTMLElement; lineWidth: number; insertType: ShapeType; forceRenderText: boolean; }): void; /** * 当图形被选中或者被聚焦时,渲染图形外部边框;当图形被单选时显示图形的变形把手 */ renderOutline(ctx: CanvasRenderingContext2D, scale: number): void; /** * 图形是否在选的的rect范围内(任意一点出现在选的范围内即认为可见) * @param x * @param y * @param width * @param height * @returns */ private isShapeInRect; /** * 测试点位是否在图形边线上 * @param x 点位在 canvas 上的 x 坐标 * @param y 点位在 canvas 上的 y 坐标 * @param renderContext */ abstract isPointInShape(x: number, y: number): boolean; /** * 测试点位是否在图形边框矩形内 * @param x 点位在 canvas 上的 x 坐标 * @param y 点位在 canvas 上的 y 坐标 */ isPointInShapeRect(x: number, y: number): boolean; export(): ShapeReservedState; /** * 获取 rgn 信息,用来在设备之间传输,实现 shape 的移动和缩放 */ getRgnData(): string; get minx(): number; get miny(): number; get maxx(): number; get maxy(): number; get width(): number; get height(): number; /** * 中心点位置 */ get center(): { x: number; y: number; }; /** * deepcopy 存储变化开始时候的 points 位置 */ storeTransformStartPoints(): void; onMoveStart(): void; onMove(deltaX: number, deltaY: number): void; onMoveEnd(deltaX: number, deltaY: number): void; onResizeStart(x: number, y: number): void; onResize(deltaX: number, deltaY: number, shiftPressing: boolean): void; /** * 对所有的点位根据 resizeOriginPosition 进行缩放 * @param xRatio * @param yRatio * @param resizeOriginPosition */ resizeByRatio(xRatio: number, yRatio: number, resizeOriginPosition?: Point): void; private updateRgnReverse; onResizeEnd(deltaX: number, deltaY: number, shiftPressing: boolean): void; /** * 以中心点为基准旋转 * @param angle */ onRotate(angle: number): void; /** * outline 上的 resize 把手 */ get outlineResizeHandles(): OutlineResizeHandle[]; destructor(): void; genDrawMsg(name: string): IShapeData; genRgnMsg(name: string): IShapeRgnData; } /** * 图片图形,普通普通会缓存img对象,背景图(order='bg')的图片不缓存img */ declare class Image extends BaseShape { imgUrl: string; clone(userId: string, shapeId: string): Image; private loadedUrl; private _img?; get img(): HTMLImageElement | undefined; set img(value: HTMLImageElement | undefined); private gifData?; private gifRenderInterval; get shapeType(): ShapeType; export(): ShapeReservedState; constructor(baseConfig: { points: Point[]; shapeId: string; creator: string; pageId: string; }, imgUrl: string); shouldSelectAfterAdd(): boolean; genDrawMsg(userName: string): IShapeData; loadImage(): Promise; isPointInShape(x: number, y: number): boolean; isGif(): any; renderShape(renderContext: CanvasRenderingContext2D): void; genRgnMsg(name: string): { pageId: string; name: string; shape: ShapeType; rgn: string; }; destructor(): void; } declare class ShapeHistory { actionType: HistoryActionType; shapeId: string; currentState: ShapeReservedState; lastState?: ShapeReservedState; shapeCreator: string; constructor(actionType: HistoryActionType, shapeId: string, currentState: ShapeReservedState, lastState?: ShapeReservedState); } declare class BatchHistory { actionType: HistoryActionType; shapeStates: { shapeId: string; currentState: ShapeReservedState; lastState?: ShapeReservedState; }[]; constructor(actionType: HistoryActionType, shapeStates: { shapeId: string; currentState: ShapeReservedState; lastState?: ShapeReservedState; }[]); } declare enum HistoryActionType { reveiveShape = 0, newShape = 1, hideShape = 2, rgnShape = 3, updateStyle = 4, updateText = 5, deleteShape = 6 } declare class History extends EventEmitter<{ 'history-changed': (state: { undo: boolean; redo: boolean; }) => void; }> { private undoList; private redoList; private emitHistoryEvent; saveHistory(shapeHistory: ShapeHistory): void; batchSave(batchHistory: BatchHistory): void; undo(): ShapeHistory | BatchHistory; redo(): ShapeHistory | BatchHistory; clearAll(): void; clearUserHistory(userId: string): void; clearShapeHistory(shapeId: string): void; canUndo(): boolean; canRedo(): boolean; } declare class Page extends EventEmitter<{ 'background-image-updated': () => void; 'page-content-updated': (page: Page) => void; }> { pageId: string; private shapes; private _backgroundColor; private _backgroundImage?; private _scale; private _translate; history: History; get scale(): number; set scale(value: number); get translate(): [number, number]; set translate(value: [number, number]); get miny(): number; get minx(): number; get visibleShapes(): BaseShape[]; get backgroundImage(): Image | undefined; set backgroundImage(value: Image | undefined); get backgroundColor(): string; set backgroundColor(value: string); addShape(shape: BaseShape): void; getShapeBySeq(shapeSeq: string, userId: string): BaseShape; /** * 根据 page 中shapes 的 order 分类以及时间重新排序 */ updateShapesOrder(): void; /** * 返回当前页面内所有图形,包括背景图 * @returns */ getShapes(): BaseShape[]; /** * 清除所有图形 */ clearShapes(): void; /** * 清除所有图形和背景图 */ clearPage(): void; /** * 清除背景图 */ clearBackgroundImage(): void; /** * 清除某个用户的背景图 */ clearUserBackgroundImage(userId: string): void; /** * 清除某个用户的图形 * @param userId */ clearUserShapes(userId: string): void; removeShape(shapeId: string): void; constructor(pageId: string); reset(): void; export(): { pageId: string; scale: number; translate: [number, number]; backgroundColor: string; backgroundImage: ShapeReservedState; shapes: ShapeReservedState[]; }; static restore(data: any): Page; private static restoreShapes; restoreShapes(shapeStates: ShapeReservedState[]): BaseShape[]; } interface IDomRect { x: number; y: number; width: number; height: number; top: number; right: number; bottom: number; left: number; } declare enum DocBrowserMode { flip = "flip", scroll = "scroll" } declare enum DocType { 'normal' = "normal", 'externalDoc' = "externalDoc", 'h5' = "h5", 'pdf' = "pdf" } declare abstract class BaseDoc extends EventEmitter<{ requestRender: (docId: string) => void; 'viewport-updated': (docId: string) => void; 'page-index-changed': (docId: string) => void; }> { /** * 文档类型 */ abstract get type(): DocType; /** * 文档内所有页面是否共享缩放和平移属性 * * @type {boolean} */ abstract get sharePageSize(): boolean; /** * 是否可以增加、删除页面 */ abstract get canModifyPage(): boolean; createdEventNotEmited: boolean; docId: string; name: string; creator: string; pageVersion: number; fileKey?: string; private pages; private previousPageIndex; curPageId: string; maxSeq: number; protected _browseMode: DocBrowserMode; disableScale: boolean; get browseMode(): DocBrowserMode; set browseMode(mode: DocBrowserMode); pageSize: { width: number; height: number; }; private _scrollPages; get scrollPages(): number; set scrollPages(pages: number); get width(): number; get scrollPageHeight(): number; get scrollHeight(): number; get y(): number; get currentPageIndex(): number; set currentPageIndex(index: number); get currentPage(): Page; get totalPages(): number; get scale(): number; get translate(): number[]; sizeConfig: { width: number; height: number; limited: boolean; }; setSizeConfig(sizeConfig: { width: number; height: number; limited: boolean; }): void; get isSizeLimited(): boolean; getPageByPageId(pageId: string): any; getPageIndexByPageId(pageId: string): any; getPages(): Page[]; getPageAtIndex(index: number): Page; generateNewPageId(): string; addPage(page: Page, index?: number): void; removePage(index: number): void; /** * 监听 page 更新事件,向外部发送渲染请求 * @param page */ private setUpPageListeners; protected requestRender(): void; /** * 通知外部文档更新,需要重新渲染 */ private onPageUpdated; /** * 根据pageId列表更新page,本地多的删掉,少的新建page补齐 * @param pageIds */ regenerate(pageIds: string[]): void; constructor(pageInfo: { docId: string; name: string; creator: string; curPageId: string; pageVersion: number; sizeConfig?: { width: number; height: number; limited: boolean; }; fileKey?: string; browseMode: DocBrowserMode; }); setScrollY(y: number, wrapperRect: IDomRect): void; /** * 设置画板偏移 * @param x 水平方向偏移 * @param y 竖直方向偏移 (如果是pdf view,只能垂直方向移动) * @param smooth 是否平滑移动 * @param duration 平滑移动时间,默认 400 ms */ setTranslate(x: number, y: number, wrapperRect: IDomRect, smooth?: boolean, duration?: number): void; /** * 设置当前白板视图的缩放比例,可以选择是否已白板中心作为缩放原点 * @param nextScale 缩放比例 * @param scaleByPosition 是否以某个位置为中心缩放,默认开启,且以当前画板中心为中心缩放 * @param scalePosition 指定缩放中心位置,如果不指定,则以当前画板中心为中心缩放 */ setScale(nextScale: number, scaleByPosition: boolean, wrapperRect: IDomRect, scalePosition?: { x: number; y: number; }): void; setScaleAndTranslate(nextScale: number, translate: number[], limited: boolean, wrapperRect: IDomRect): void; /** * 设置本地视角信息 * @param visionInfo 视角信息 */ setDocViewport(visionInfo: { width: number; height: number; minx: number; miny: number; }, wrapperRect: IDomRect, page?: Page): void; /** * 获取 sizeConfig 下或 白板在"scroll"模式下的被限定,在当前画布大小下缩放居中之后真实的画布大小 * */ private getSizeConfigLimitSize; /** * 以 传入的点位更新当前白板页面 scale 比例,如果白板被限制大小,会自动计算出合适的 scale 和 translate * @param nextScale 要更新的 scale * @param originalX 缩放点的 x 坐标,点位是在白板 canvas 元素上的位置 * @param originalY 缩放点的 y 坐标,点位是在白板 canvas 元素上的位置 */ updateBoardWithNewScale: (nextScale: number, originalX: number, originalY: number, rect: IDomRect) => void; /** * 根据传入的translate 和 scale计算出视窗位置 */ private getPotentialViewportPosition; /** * 计算在被限定大小的情况下,在某个缩放值下,translate能取的极限值 * @param scale * @param viewport 限定的视窗位置 */ private getLimitedTranslate; scaleBoardFitBackgroundImage(page: Page, wrapperRect: IDomRect, bgScaleMode: ImageScalingMode): void; /** * 返回文档可见区域的坐标 */ getDocViewportPosition(wrapperRect: IDomRect): { minx: number; miny: number; maxx: number; maxy: number; }; export(): { docId: string; name: string; creator: string; pageIndex: number; pageVersion: number; pages: { pageId: string; scale: number; translate: [number, number]; backgroundColor: string; backgroundImage: ShapeReservedState; shapes: ShapeReservedState[]; }[]; fileKey: string; }; toJson(): { docId: string; name: string; creator: string; pageIndex: number; pageLength: number; fileKey: string; }; /** * 清除所有页面数据 */ clear(): void; clearPageById(pageId: string): void; /** * 清除某个用户所有图形 * @param userId */ clearUserShapes(userId: string): void; /** * 清除某个用户背景图 * @param userId */ clearUserBackgroundImage(userId: string): void; reset(): void; } interface PDFViewer { pageIndex: number; width: number; totalHeight: number; domRef: HTMLDivElement; state: 'notloaded' | 'loading' | 'loaded'; url: string; y: number; pdfPages: Map; /** * pdf 页面加载完之后按顺序保存每页的高度(累计高度),用于计算当前页面的高度 */ pageHightList: number[]; } /** * pdf 文档 */ declare class PdfDoc extends BaseDoc { pdfViewer: PDFViewer; static DOC_TYPE: DocType; get browseMode(): DocBrowserMode; set browseMode(mode: DocBrowserMode); get type(): DocType; get sharePageSize(): boolean; get canModifyPage(): boolean; get width(): number; get scrollHeight(): number; url: string; lastSyncY: number; /** * 缓存当前页面高度范围,减少计算页码运算 */ private currentPageMem; /** * 判断当前滚动位置是否在当前缓存的页面范围内 */ private isInCurrentMemPage; get currentPageIndex(): number; constructor(docInfo: { docId: string; name: string; creator: string; curPageId: string; pageVersion: number; fileKey?: string; browseMode: DocBrowserMode; }, pdfViewer: PDFViewer); load(): Promise; setScrollY(y: number, wrapperRect: IDomRect): void; setScaleAndTranslate(nextScale: number, translate: number[], limited: boolean, wrapperRect: IDomRect): void; createPdfLoadingPage(): void; centerPdfDoc(): void; protected getPdfVisiblePage(wrapperRect: IDomRect): { pagesNum: number; start: number; end: number; firstVisibleIndex: number; lastVisibleIndex: number; }; /** * 检测当前滚动位置,显示周围几张PDF图片 */ lazyLoadPdfPage: any; /** * 检测当前展示位置,如果当前位置的pfd未渲染,则开始渲染当前页面 */ lazyRenderPdfPage: any; } declare class PdfPlugin { static getDevicePixelRatio(): number; static loadPdf(url: string, doc: PdfDoc): Promise; private static preparePdfPage; static updatePdfWidth(doc: PdfDoc, newWidth: number): void; } export { PdfPlugin, PdfPlugin as default };