diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts index 5cea48d..872bf9e 100644 --- a/packages/board/src/index.ts +++ b/packages/board/src/index.ts @@ -1,6 +1,6 @@ import { Renderer } from '@idraw/renderer'; import { throttle } from '@idraw/util'; -import type { Data, BoardMode, BoardOptions, BoardMiddleware, BoardMiddlewareObject, BoardWatcherEventMap } from '@idraw/types'; +import type { Data, BoardMode, BoardOptions, BoardMiddleware, BoardMiddlewareObject, BoardWatcherEventMap, ViewSizeInfo } from '@idraw/types'; import { Calculator } from './lib/calculator'; import { BoardWatcher } from './lib/watcher'; import { Sharer } from './lib/sharer'; @@ -82,6 +82,10 @@ export class Board { this._handleWheelY(e); }, frameTime) ); + this._watcher.on('scale', this._handleScale.bind(this)); + this._watcher.on('scrollX', this._handleScrollX.bind(this)); + this._watcher.on('scrollY', this._handleScrollY.bind(this)); + this._watcher.on('resize', this._handleResize.bind(this)); } private _handlePointStart(e: BoardWatcherEventMap['pointStart']) { @@ -144,6 +148,47 @@ export class Board { } } + private _handleScale(e: BoardWatcherEventMap['scale']) { + for (let i = 0; i < this._activeMiddlewareObjs.length; i++) { + const obj = this._activeMiddlewareObjs[i]; + const result = obj?.scale?.(e); + if (result === false) { + return; + } + } + } + + private _handleScrollX(e: BoardWatcherEventMap['scrollX']) { + for (let i = 0; i < this._activeMiddlewareObjs.length; i++) { + const obj = this._activeMiddlewareObjs[i]; + const result = obj?.scrollX?.(e); + if (result === false) { + return; + } + } + } + + private _handleScrollY(e: BoardWatcherEventMap['scrollY']) { + for (let i = 0; i < this._activeMiddlewareObjs.length; i++) { + const obj = this._activeMiddlewareObjs[i]; + const result = obj?.scrollY?.(e); + if (result === false) { + return; + } + } + } + + private _handleResize(e: BoardWatcherEventMap['resize']) { + for (let i = 0; i < this._activeMiddlewareObjs.length; i++) { + const obj = this._activeMiddlewareObjs[i]; + const result = obj?.resize?.(e); + if (result === false) { + return; + } + } + } + + // draw event private _handleBeforeDrawFrame(e: BoardWatcherEventMap['beforeDrawFrame']) { for (let i = 0; i < this._activeMiddlewareObjs.length; i++) { const obj = this._activeMiddlewareObjs[i]; @@ -196,17 +241,26 @@ export class Board { } scale(num: number) { - this._viewer.scale(num); + const scaleInfo = this._viewer.scale(num); this._viewer.drawFrame(); + this._watcher.trigger('scale', scaleInfo); } scrollX(num: number) { - this._viewer.scrollX(num); + const scaleInfo = this._viewer.scrollX(num); this._viewer.drawFrame(); + this._watcher.trigger('scrollX', scaleInfo); } scrollY(num: number) { - this._viewer.scrollY(num); + const scaleInfo = this._viewer.scrollY(num); this._viewer.drawFrame(); + this._watcher.trigger('scrollY', scaleInfo); + } + + resize(newViewSize: Partial) { + const viewSize = this._viewer.resize(newViewSize); + this._viewer.drawFrame(); + this._watcher.trigger('resize', viewSize); } } diff --git a/packages/board/src/lib/viewer.ts b/packages/board/src/lib/viewer.ts index 8344f28..6cd308f 100644 --- a/packages/board/src/lib/viewer.ts +++ b/packages/board/src/lib/viewer.ts @@ -86,28 +86,53 @@ export class Viewer extends EventEmitter implements BoardVi this._drawAnimationFrame(); } - scale(num: number) { + scale(num: number): ViewScaleInfo { const { sharer, renderer, calculator } = this._opts; const prevScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); const scaleInfo = calculator.viewScale(num, prevScaleInfo, viewSizeInfo); sharer.setActiveScaleInfo(scaleInfo); renderer.scale(num); + return scaleInfo; } - scrollX(num: number) { + scrollX(num: number): ViewScaleInfo { const { sharer, calculator } = this._opts; const prevScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); const scaleInfo = calculator.viewScroll({ moveX: num - (prevScaleInfo.offsetLeft || 0) }, prevScaleInfo, viewSizeInfo); sharer.setActiveScaleInfo(scaleInfo); + return scaleInfo; } - scrollY(num: number) { + scrollY(num: number): ViewScaleInfo { const { sharer, calculator } = this._opts; const prevScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); const scaleInfo = calculator.viewScroll({ moveY: num - (prevScaleInfo.offsetTop || 0) }, prevScaleInfo, viewSizeInfo); sharer.setActiveScaleInfo(scaleInfo); + return scaleInfo; + } + + resize(viewSize: Partial = {}): ViewSizeInfo { + const { sharer } = this._opts; + const originViewSize = sharer.getActiveViewSizeInfo(); + const newViewSize = { ...originViewSize, ...viewSize }; + + const { width, height, devicePixelRatio } = newViewSize; + const { boardContext, helperContext, viewContext } = this._opts.viewContent; + boardContext.canvas.width = width * devicePixelRatio; + boardContext.canvas.height = height * devicePixelRatio; + boardContext.canvas.style.width = `${width}px`; + boardContext.canvas.style.height = `${height}px`; + + helperContext.canvas.width = width * devicePixelRatio; + helperContext.canvas.height = height * devicePixelRatio; + + viewContext.canvas.width = width * devicePixelRatio; + viewContext.canvas.height = height * devicePixelRatio; + + sharer.setActiveViewSizeInfo(newViewSize); + return newViewSize; } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index db975cf..98d8f9c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -4,6 +4,7 @@ import { createBoardContexts } from '@idraw/util'; export { MiddlewareSelector } from './middleware/select'; export { MiddlewareScroller } from './middleware/scroll'; +export { MiddlewareRuler } from './middleware/rule'; export class Core { private _board: Board; diff --git a/packages/core/src/middleware/rule/index.ts b/packages/core/src/middleware/rule/index.ts new file mode 100644 index 0000000..9dfe781 --- /dev/null +++ b/packages/core/src/middleware/rule/index.ts @@ -0,0 +1,22 @@ +import type { Point, BoardMiddleware, PointWatcherEvent, BoardWatherWheelXEvent, BoardWatherWheelYEvent } from '@idraw/types'; + +export const MiddlewareRuler: BoardMiddleware = (opts) => { + const key = 'RULE'; + + return { + mode: key, + isDefault: true, + scale(e) { + console.log('scale =====', e); + }, + scrollX(e) { + console.log('scrollX =====', e); + }, + scrollY(e) { + console.log('scrollY =====', e); + }, + resize(e) { + console.log('scale =====', e); + } + }; +}; diff --git a/packages/idraw/src/index.ts b/packages/idraw/src/index.ts index 4370375..ac39505 100644 --- a/packages/idraw/src/index.ts +++ b/packages/idraw/src/index.ts @@ -1,4 +1,4 @@ -import { Core, MiddlewareSelector, MiddlewareScroller } from '@idraw/core'; +import { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareRuler } from '@idraw/core'; import type { IDrawOptions, Data } from '@idraw/types'; export class iDraw { @@ -11,6 +11,7 @@ export class iDraw { this._opts = opts; core.use(MiddlewareScroller); core.use(MiddlewareSelector); + core.use(MiddlewareRuler); } setData(data: Data) { diff --git a/packages/types/src/lib/board.ts b/packages/types/src/lib/board.ts index 16e4767..471e984 100644 --- a/packages/types/src/lib/board.ts +++ b/packages/types/src/lib/board.ts @@ -1,5 +1,5 @@ import type { Point } from './point'; -import type { ViewContent, ViewCalculator } from './view'; +import type { ViewContent, ViewCalculator, ViewScaleInfo, ViewSizeInfo } from './view'; import type { UtilEventEmitter } from './util'; import type { ActiveStore, StoreSharer } from './store'; import type { RendererEventMap, RendererOptions, RendererDrawOptions } from './renderer'; @@ -20,6 +20,14 @@ export interface BoardWatherDrawFrameEvent { snapshot: BoardViewerFrameSnapshot; } +export type BoardWatherScaleEvent = ViewScaleInfo; + +export type BoardWatherScrollXEvent = ViewScaleInfo; + +export type BoardWatherScrollYEvent = ViewScaleInfo; + +export type BoardWatherResizeEvent = ViewSizeInfo; + export interface BoardWatcherEventMap { hover: BoardWatcherPointEvent; pointStart: BoardWatcherPointEvent; @@ -29,16 +37,21 @@ export interface BoardWatcherEventMap { doubleClick: BoardWatcherPointEvent; wheelX: BoardWatherWheelXEvent; wheelY: BoardWatherWheelYEvent; + scale: BoardWatherScaleEvent; + scrollX: BoardWatherScrollXEvent; + scrollY: BoardWatherScrollYEvent; + resize: BoardWatherResizeEvent; beforeDrawFrame: BoardWatherDrawFrameEvent; afterDrawFrame: BoardWatherDrawFrameEvent; } -export type BoardMode = 'SELECT' | 'SCROLL' | 'RULER' | 'CONNECT' | 'PENCIL' | 'PEN' | string; +export type BoardMode = 'SELECT' | 'SCROLL' | 'RULE' | 'CONNECT' | 'PENCIL' | 'PEN' | string; export interface BoardMiddlewareObject { mode: BoardMode; isDefault?: boolean; created?: () => void; + // action hover?: (e: BoardWatcherEventMap['hover']) => void | boolean; pointStart?: (e: BoardWatcherEventMap['pointStart']) => void | boolean; pointMove?: (e: BoardWatcherEventMap['pointMove']) => void | boolean; @@ -47,6 +60,13 @@ export interface BoardMiddlewareObject { doubleClick?: (e: BoardWatcherEventMap['doubleClick']) => void | boolean; wheelX?: (e: BoardWatcherEventMap['wheelX']) => void | boolean; wheelY?: (e: BoardWatcherEventMap['wheelY']) => void | boolean; + + scale?: (e: BoardWatcherEventMap['scale']) => void | boolean; + scrollX?: (e: BoardWatcherEventMap['scrollX']) => void | boolean; + scrollY?: (e: BoardWatcherEventMap['scrollY']) => void | boolean; + resize?: (e: BoardWatcherEventMap['resize']) => void | boolean; + + // draw beforeDrawFrame?(e: BoardWatcherEventMap['beforeDrawFrame']): void | boolean; afterDrawFrame?(e: BoardWatcherEventMap['afterDrawFrame']): void | boolean; } @@ -85,9 +105,10 @@ export interface BoardViewerOptions { export interface BoardViewer extends UtilEventEmitter { drawFrame(): void; - scale(num: number): void; - scrollX(num: number): void; - scrollY(num: number): void; + scale(num: number): ViewScaleInfo; + scrollX(num: number): ViewScaleInfo; + scrollY(num: number): ViewScaleInfo; + resize(viewSize: Partial): ViewSizeInfo; } export interface BoardRenderer extends UtilEventEmitter {