From f4ebe720a486bf0b9af76200d457ecadf5c3f8f7 Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Sun, 11 Jun 2023 15:38:07 +0800 Subject: [PATCH] refactor: refactor calculator --- packages/board/src/lib/calculator.ts | 151 ++++----------------------- packages/board/src/lib/viewer.ts | 12 +-- packages/types/src/lib/view.ts | 2 - packages/util/src/lib/view-calc.ts | 16 ++- 4 files changed, 32 insertions(+), 149 deletions(-) diff --git a/packages/board/src/lib/calculator.ts b/packages/board/src/lib/calculator.ts index 1f81616..9fbe6d4 100644 --- a/packages/board/src/lib/calculator.ts +++ b/packages/board/src/lib/calculator.ts @@ -1,14 +1,5 @@ import type { Data, Point, Element, ElementType, ViewCalculator, ViewCalculatorOptions, ViewScaleInfo, ElementSize, ViewSizeInfo } from '@idraw/types'; -import { - rotateElementVertexes, - checkRectIntersect, - viewScale, - viewScroll, - calcElementSize, - isViewPointInElement, - getViewPointAtElement, - isElementInView -} from '@idraw/util'; +import { calcElementSize, isViewPointInElement, getViewPointAtElement, isElementInView } from '@idraw/util'; export class Calculator implements ViewCalculator { private _opts: ViewCalculatorOptions; @@ -17,135 +8,31 @@ export class Calculator implements ViewCalculator { this._opts = opts; } - viewScroll(opts: { moveX?: number; moveY?: number }, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ViewScaleInfo { - const scale = viewScaleInfo.scale; - const { moveX, moveY } = opts; - const { width, height, contextWidth, contextHeight } = viewSizeInfo; - let offsetLeft = viewScaleInfo.offsetLeft; - let offsetRight = viewScaleInfo.offsetRight; - let offsetTop = viewScaleInfo.offsetTop; - let offsetBottom = viewScaleInfo.offsetBottom; - if (moveX !== undefined && (moveX > 0 || moveX <= 0)) { - if (contextWidth * scale < width) { - offsetLeft = offsetRight = (width - contextWidth * scale) / 2; - } else if (contextWidth * scale > width) { - if (offsetLeft + moveX >= 0) { - offsetLeft = 0; - offsetRight = width - contextWidth * scale; - } else if (offsetLeft + moveX < width - contextWidth * scale) { - offsetLeft = width - contextWidth * scale; - offsetRight = 0; - } else { - offsetLeft += moveX; - offsetRight = width - contextWidth * scale - offsetLeft; - } - } else { - offsetLeft = offsetRight = 0; - } - } - - if (moveY !== undefined && (moveY > 0 || moveY <= 0)) { - if (contextHeight * scale < height) { - offsetTop = offsetBottom = (height - contextHeight * scale) / 2; - } else if (contextHeight * scale > height) { - if (offsetTop + moveY >= 0) { - offsetTop = 0; - offsetBottom = height - contextHeight * scale; - } else if (offsetTop + moveY < height - contextHeight * scale) { - offsetTop = height - contextHeight * scale; - offsetBottom = 0; - } else { - offsetTop += moveY; - offsetBottom = height - contextHeight * scale - offsetTop; - } - } else { - offsetTop = offsetBottom = 0; - } - } - - return { - scale, - offsetTop, - offsetLeft, - offsetRight, - offsetBottom - }; - } - elementSize(size: ElementSize, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ElementSize { - const { x, y, w, h, angle } = size; - const { contextX = 0, contextY = 0 } = viewSizeInfo; - const { scale, offsetTop, offsetLeft } = viewScaleInfo; - - const newSize = { - x: x * scale + offsetLeft - contextX, - y: y * scale + offsetTop - contextY, - w: w * scale, - h: h * scale, - angle - }; - - return newSize; + return calcElementSize(size, { viewScaleInfo, viewSizeInfo }); } isElementInView(elem: ElementSize, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): boolean { - const { width, height } = viewSizeInfo; - const { angle } = elem; - const { x, y, w, h } = this.elementSize(elem, viewScaleInfo, viewSizeInfo); - const ves = rotateElementVertexes({ x, y, w, h, angle }); - const viewSize = { x: 0, y: 0, w: width, h: height }; - - const elemStartX = Math.min(ves[0].x, ves[1].x, ves[2].x, ves[3].x); - const elemStartY = Math.min(ves[0].y, ves[1].y, ves[2].y, ves[3].y); - const elemEndX = Math.max(ves[0].x, ves[1].x, ves[2].x, ves[3].x); - const elemEndY = Math.max(ves[0].y, ves[1].y, ves[2].y, ves[3].y); - const elemSize = { x: elemStartX, y: elemStartY, w: elemEndX - elemStartX, h: elemEndY - elemStartY }; - return checkRectIntersect(viewSize, elemSize); + return isElementInView(elem, { viewScaleInfo, viewSizeInfo }); } - isPointInElement(p: Point, elem: Element, viewScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): boolean { - const ctx = this._opts.viewContent.boardContext; - const { angle = 0 } = elem; - const { x, y, w, h } = this.elementSize(elem, viewScaleInfo, viewSize); - const vertexes = rotateElementVertexes({ x, y, w, h, angle }); - if (vertexes.length >= 2) { - ctx.beginPath(); - ctx.moveTo(vertexes[0].x, vertexes[0].y); - for (let i = 1; i < vertexes.length; i++) { - ctx.lineTo(vertexes[i].x, vertexes[i].y); - } - ctx.closePath(); - } - if (ctx.isPointInPath(p.x, p.y)) { - return true; - } - return false; + isPointInElement(p: Point, elem: Element, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): boolean { + const context2d = this._opts.viewContent.boardContext; + return isViewPointInElement(p, { + context2d, + element: elem, + viewScaleInfo, + viewSizeInfo + }); } - getPointElement(p: Point, data: Data, viewScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): { index: number; element: null | Element } { - const result: { index: number; element: null | Element } = { - index: -1, - element: null - }; - for (let i = data.elements.length - 1; i >= 0; i--) { - const elem = data.elements[i]; - if (this.isPointInElement(p, elem, viewScaleInfo, viewSize)) { - result.index = i; - result.element = elem; - break; - } - } - return result; + getPointElement(p: Point, data: Data, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): { index: number; element: null | Element } { + const context2d = this._opts.viewContent.boardContext; + return getViewPointAtElement(p, { + data, + context2d, + viewScaleInfo, + viewSizeInfo + }); } - - // rotateElementSize(elemSize: ElementSize): PointSize[] { - // // const { x, y, w, h, angle = 0 } = elemSize; - // // const pointSizes: PointSize[] = []; - // return []; - // } - - // pointToViewPoint(p: Point): Point { - // // TODO - // return {}; - // } } diff --git a/packages/board/src/lib/viewer.ts b/packages/board/src/lib/viewer.ts index ee4d558..5f8be6b 100644 --- a/packages/board/src/lib/viewer.ts +++ b/packages/board/src/lib/viewer.ts @@ -1,4 +1,4 @@ -import { EventEmitter, viewScale } from '@idraw/util'; +import { EventEmitter, viewScale, viewScroll } from '@idraw/util'; import type { BoardViewer, BoardViewerEventMap, BoardViewerOptions, ActiveStore, BoardViewerFrameSnapshot, ViewScaleInfo, ViewSizeInfo } from '@idraw/types'; const { requestAnimationFrame } = window; @@ -93,26 +93,26 @@ export class Viewer extends EventEmitter implements BoardVi const { sharer, renderer } = this._opts; const prevViewScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); - const viewScaleInfo = viewScale(num, { prevViewScaleInfo, viewSizeInfo }); + const viewScaleInfo = viewScale({ num, prevViewScaleInfo, viewSizeInfo }); sharer.setActiveScaleInfo(viewScaleInfo); renderer.scale(num); return viewScaleInfo; } scrollX(num: number): ViewScaleInfo { - const { sharer, calculator } = this._opts; + const { sharer } = this._opts; const prevViewScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); - const viewScaleInfo = calculator.viewScroll({ moveX: num - (prevViewScaleInfo.offsetLeft || 0) }, prevViewScaleInfo, viewSizeInfo); + const viewScaleInfo = viewScroll({ moveX: num - (prevViewScaleInfo.offsetLeft || 0), viewScaleInfo: prevViewScaleInfo, viewSizeInfo }); sharer.setActiveScaleInfo(viewScaleInfo); return viewScaleInfo; } scrollY(num: number): ViewScaleInfo { - const { sharer, calculator } = this._opts; + const { sharer } = this._opts; const prevViewScaleInfo: ViewScaleInfo = sharer.getActiveScaleInfo(); const viewSizeInfo: ViewSizeInfo = sharer.getActiveViewSizeInfo(); - const viewScaleInfo = calculator.viewScroll({ moveY: num - (prevViewScaleInfo.offsetTop || 0) }, prevViewScaleInfo, viewSizeInfo); + const viewScaleInfo = viewScroll({ moveY: num - (prevViewScaleInfo.offsetTop || 0), viewScaleInfo: prevViewScaleInfo, viewSizeInfo }); sharer.setActiveScaleInfo(viewScaleInfo); return viewScaleInfo; } diff --git a/packages/types/src/lib/view.ts b/packages/types/src/lib/view.ts index 133437a..85afc8e 100644 --- a/packages/types/src/lib/view.ts +++ b/packages/types/src/lib/view.ts @@ -35,10 +35,8 @@ export interface ViewCalculatorOptions { } export interface ViewCalculator { - // viewScale(num: number, prevScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): ViewScaleInfo; isElementInView(elem: Element, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): boolean; isPointInElement(p: Point, elem: Element, viewScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): boolean; elementSize(size: ElementSize, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ElementSize; - viewScroll(opts: { moveX?: number; moveY?: number }, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ViewScaleInfo; getPointElement(p: Point, data: Data, viewScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): { index: number; element: null | Element }; } diff --git a/packages/util/src/lib/view-calc.ts b/packages/util/src/lib/view-calc.ts index 802f4d0..1d6d3c1 100644 --- a/packages/util/src/lib/view-calc.ts +++ b/packages/util/src/lib/view-calc.ts @@ -1,11 +1,9 @@ -import { Point, Data, ViewScaleInfo, ViewSizeInfo, Element, ElementType, ElementSize } from '@idraw/types'; +import { Point, Data, ViewScaleInfo, ViewSizeInfo, Element, ElementType, ElementSize, ViewContext2D } from '@idraw/types'; import { rotateElementVertexes } from './rotate'; -import { Context2D } from './context2d'; import { checkRectIntersect } from './rect'; -export function viewScale(num: number, opts: { prevViewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewScaleInfo { - const scale = num; - const { prevViewScaleInfo, viewSizeInfo } = opts; +export function viewScale(opts: { num: number; prevViewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewScaleInfo { + const { num: scale, prevViewScaleInfo, viewSizeInfo } = opts; const { width, height, contextWidth, contextHeight } = viewSizeInfo; let offsetLeft = 0; let offsetRight = 0; @@ -39,9 +37,9 @@ export function viewScale(num: number, opts: { prevViewScaleInfo: ViewScaleInfo; }; } -export function viewScroll(opts: { moveX?: number; moveY?: number }, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ViewScaleInfo { +export function viewScroll(opts: { moveX?: number; moveY?: number; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewScaleInfo { + const { moveX, moveY, viewScaleInfo, viewSizeInfo } = opts; const scale = viewScaleInfo.scale; - const { moveX, moveY } = opts; const { width, height, contextWidth, contextHeight } = viewSizeInfo; let offsetLeft = viewScaleInfo.offsetLeft; let offsetRight = viewScaleInfo.offsetRight; @@ -113,7 +111,7 @@ export function calcElementSize(size: ElementSize, opts: { viewScaleInfo: ViewSc export function isViewPointInElement( p: Point, - opts: { context2d: Context2D; element: Element; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo } + opts: { context2d: ViewContext2D; element: Element; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo } ): boolean { const { context2d: ctx, element: elem, viewScaleInfo, viewSizeInfo } = opts; @@ -137,7 +135,7 @@ export function isViewPointInElement( export function getViewPointAtElement( p: Point, opts: { - context2d: Context2D; + context2d: ViewContext2D; data: Data; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo;