From 215e212759bcb324d6abf6efc7a046f556e1db4a Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Sat, 24 Aug 2024 16:34:37 +0800 Subject: [PATCH] feat: implement reset style feature --- packages/board/src/index.ts | 9 +++ packages/core/src/index.ts | 4 ++ packages/core/src/middleware/info/index.ts | 16 +++-- .../src/middleware/layout-selector/index.ts | 11 ++- packages/core/src/middleware/ruler/index.ts | 30 +++++--- packages/core/src/middleware/ruler/util.ts | 24 +++++-- .../core/src/middleware/scroller/index.ts | 28 ++++---- .../core/src/middleware/selector/index.ts | 25 +++++-- .../src/middleware/selector/pattern/index.ts | 6 +- packages/idraw/dev/main.ts | 72 ++++++++++--------- packages/idraw/src/idraw.ts | 27 +++++-- packages/idraw/src/{ => setting}/config.ts | 45 +++++++++++- packages/idraw/src/{ => setting}/mode.ts | 2 +- packages/idraw/src/setting/style.ts | 29 ++++++++ packages/types/src/lib/board.ts | 6 +- packages/types/src/lib/idraw.ts | 2 +- 16 files changed, 244 insertions(+), 92 deletions(-) rename packages/idraw/src/{ => setting}/config.ts (75%) rename packages/idraw/src/{ => setting}/mode.ts (98%) create mode 100644 packages/idraw/src/setting/style.ts diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts index 7864d529..48efe2e2 100644 --- a/packages/board/src/index.ts +++ b/packages/board/src/index.ts @@ -397,6 +397,15 @@ export class Board { } } + resetMiddlewareConfig(middleware: BoardMiddleware, config?: Partial) { + if (this.#middlewareMap.has(middleware)) { + const item = this.#middlewareMap.get(middleware); + if (item) { + item.middlewareObject.resetConfig?.(config as any); + } + } + } + scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }) { const viewer = this.#viewer; const { ignoreUpdateVisibleStatus } = opts; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index cc248a5c..f3c16d44 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -73,6 +73,10 @@ export class Core { this.#board.disuse(middleware); } + resetMiddlewareConfig(middleware: BoardMiddleware, config?: Partial) { + this.#board.resetMiddlewareConfig(middleware, config); + } + setData( data: Data, opts?: { diff --git a/packages/core/src/middleware/info/index.ts b/packages/core/src/middleware/info/index.ts index 1459d626..14ccfc88 100644 --- a/packages/core/src/middleware/info/index.ts +++ b/packages/core/src/middleware/info/index.ts @@ -19,15 +19,10 @@ export const MiddlewareInfo: BoardMiddleware< > = (opts, config) => { const { boardContent, calculator, eventHub } = opts; const { overlayContext } = boardContent; - const innerConfig = { + let innerConfig = { ...defaltStyle, ...config }; - const { textBackground, textColor } = innerConfig; - const style = { - textBackground, - textColor - }; let showAngleInfo = true; @@ -46,7 +41,16 @@ export const MiddlewareInfo: BoardMiddleware< eventHub.off(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, showInfoAngleCallback); }, + resetConfig(config) { + innerConfig = { ...innerConfig, ...config }; + }, + beforeDrawFrame({ snapshot }) { + const { textBackground, textColor } = innerConfig; + const style = { + textBackground, + textColor + }; const { sharedStore } = snapshot; const selectedElementList = sharedStore[keySelectedElementList]; diff --git a/packages/core/src/middleware/layout-selector/index.ts b/packages/core/src/middleware/layout-selector/index.ts index 506bf67d..ea491066 100644 --- a/packages/core/src/middleware/layout-selector/index.ts +++ b/packages/core/src/middleware/layout-selector/index.ts @@ -24,12 +24,10 @@ export { keyLayoutIsSelected, keyLayoutIsBusyMoving }; export const MiddlewareLayoutSelector: BoardMiddleware = (opts, config) => { const { sharer, boardContent, calculator, viewer, eventHub } = opts; const { overlayContext } = boardContent; - const innerConfig = { + let innerConfig = { ...defaultStyle, ...config }; - const { activeColor } = innerConfig; - const style = { activeColor }; let prevPoint: Point | null = null; let prevIsHoverContent: boolean | null = null; @@ -158,6 +156,10 @@ export const MiddlewareLayoutSelector: BoardMiddleware { if (sharer.getSharedStorage(keyLayoutIsBusyMoving) === true) { return; @@ -362,6 +364,9 @@ export const MiddlewareLayoutSelector: BoardMiddleware = (opts, config) => { const { boardContent, viewer, eventHub, calculator } = opts; const { overlayContext, underlayContext } = boardContent; - const innerConfig = { + let innerConfig = { ...defaultStyle, ...config }; - const { background, borderColor, scaleColor, textColor, gridColor, gridPrimaryColor, selectedAreaColor } = innerConfig; - const style = { - background, - borderColor, - scaleColor, - textColor, - gridColor, - gridPrimaryColor, - selectedAreaColor - }; let show: boolean = true; let showGrid: boolean = true; @@ -41,13 +31,31 @@ export const MiddlewareRuler: BoardMiddleware { + const { background, borderColor, scaleColor, textColor, gridColor, gridPrimaryColor, selectedAreaColor } = innerConfig; + + const style = { + background, + borderColor, + scaleColor, + textColor, + gridColor, + gridPrimaryColor, + selectedAreaColor + }; if (show === true) { const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot); const viewSizeInfo = getViewSizeInfoFromSnapshot(snapshot); diff --git a/packages/core/src/middleware/ruler/util.ts b/packages/core/src/middleware/ruler/util.ts index ff7baf53..f5088611 100644 --- a/packages/core/src/middleware/ruler/util.ts +++ b/packages/core/src/middleware/ruler/util.ts @@ -1,6 +1,15 @@ -import type { Element, ViewScaleInfo, ViewSizeInfo, ViewContext2D, BoardViewerFrameSnapshot, ViewRectInfo, ViewCalculator } from '@idraw/types'; +import type { + Element, + ViewScaleInfo, + ViewSizeInfo, + ViewContext2D, + BoardViewerFrameSnapshot, + ViewRectInfo, + ViewCalculator, + MiddlewareRulerStyle +} from '@idraw/types'; import { formatNumber, rotateByCenter, getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from '@idraw/util'; -import type { DeepRulerSharedStorage, MiddlewareRulerStyle } from './types'; +import type { DeepRulerSharedStorage } from './types'; import { keySelectedElementList, keyActionType } from '../selector'; import { rulerSize, fontSize, fontWeight, lineSize, fontFamily } from './config'; @@ -201,14 +210,17 @@ export function drawRulerBackground( const { background, borderColor } = style; ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(width + 1, 0); + // const basePosition = 0; + const basePosition = -1; + ctx.moveTo(basePosition, basePosition); + ctx.lineTo(width + 1, basePosition); ctx.lineTo(width + 1, rulerSize); ctx.lineTo(rulerSize, rulerSize); ctx.lineTo(rulerSize, height + 1); - ctx.lineTo(0, height + 1); - ctx.lineTo(0, 0); + ctx.lineTo(basePosition, height + 1); + ctx.lineTo(basePosition, basePosition); ctx.closePath(); + ctx.fillStyle = background; ctx.fill(); ctx.lineWidth = lineSize; diff --git a/packages/core/src/middleware/scroller/index.ts b/packages/core/src/middleware/scroller/index.ts index b297df77..a4e32cea 100644 --- a/packages/core/src/middleware/scroller/index.ts +++ b/packages/core/src/middleware/scroller/index.ts @@ -12,22 +12,11 @@ export const MiddlewareScroller: BoardMiddleware { sharer.setSharedStorage(keyPrevPoint, null); // null | Point; @@ -77,6 +66,11 @@ export const MiddlewareScroller: BoardMiddleware { viewer.scroll({ moveX: 0 - e.deltaX, @@ -142,6 +136,16 @@ export const MiddlewareScroller: BoardMiddleware = (opts, config) => { - const innerConfig = { + let innerConfig = { ...defaultStyle, ...config }; - const { activeColor, activeAreaColor, lockedColor, referenceColor } = innerConfig; - const style = { activeColor, activeAreaColor, lockedColor, referenceColor }; const { viewer, sharer, boardContent, calculator, eventHub } = opts; const { overlayContext } = boardContent; let prevPoint: Point | null = null; @@ -114,8 +112,8 @@ export const MiddlewareSelector: BoardMiddleware< let inBusyMode: 'resize' | 'drag' | 'drag-list' | 'area' | null = null; let hasChangedData: boolean | null = null; - const rotateControllerPattern = createRotateControllerPattern({ - fill: style.activeColor, + let rotateControllerPattern = createRotateControllerPattern({ + fill: innerConfig.activeColor, devicePixelRatio: sharer.getActiveViewSizeInfo().devicePixelRatio }); @@ -280,6 +278,10 @@ export const MiddlewareSelector: BoardMiddleware< eventHub.off(coreEventKeys.SNAP_TO_GRID, setSnapToSnapCallback); }, + resetConfig(config) { + innerConfig = { ...innerConfig, ...config }; + }, + hover: (e: PointWatcherEvent) => { const layoutIsSelected = sharer.getSharedStorage(keyLayoutIsSelected); const layoutIsBusyMoving = sharer.getSharedStorage(keyLayoutIsBusyMoving); @@ -852,8 +854,17 @@ export const MiddlewareSelector: BoardMiddleware< }, beforeDrawFrame({ snapshot }) { + const { activeColor, activeAreaColor, lockedColor, referenceColor } = innerConfig; + const style = { activeColor, activeAreaColor, lockedColor, referenceColor }; + const { activeStore, sharedStore } = snapshot; const { scale, offsetLeft, offsetTop, offsetRight, offsetBottom, width, height, contextHeight, contextWidth, devicePixelRatio } = activeStore; + if (rotateControllerPattern.fill !== activeColor) { + rotateControllerPattern = createRotateControllerPattern({ + fill: innerConfig.activeColor, + devicePixelRatio + }); + } const sharer = opts.sharer; const viewScaleInfo = { scale, offsetLeft, offsetTop, offsetRight, offsetBottom }; @@ -908,7 +919,7 @@ export const MiddlewareSelector: BoardMiddleware< element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', - rotateControllerPattern, + rotateControllerPattern: rotateControllerPattern.context2d, style }); if (actionType === 'drag') { @@ -952,7 +963,7 @@ export const MiddlewareSelector: BoardMiddleware< element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', - rotateControllerPattern, + rotateControllerPattern: rotateControllerPattern.context2d, style }); if (actionType === 'drag') { diff --git a/packages/core/src/middleware/selector/pattern/index.ts b/packages/core/src/middleware/selector/pattern/index.ts index 96232715..739b1cbe 100644 --- a/packages/core/src/middleware/selector/pattern/index.ts +++ b/packages/core/src/middleware/selector/pattern/index.ts @@ -3,7 +3,7 @@ import { createOffscreenContext2D } from '@idraw/util'; import { drawElement } from '@idraw/renderer'; import { createIconRotate } from './icon-rotate'; -export function createRotateControllerPattern(opts: { fill: string; devicePixelRatio: number }): ViewContext2D { +export function createRotateControllerPattern(opts: { fill: string; devicePixelRatio: number }): { context2d: ViewContext2D; fill: string } { const { fill, devicePixelRatio } = opts; const iconRotate = createIconRotate({ fill }); const { w, h } = iconRotate; @@ -41,5 +41,7 @@ export function createRotateControllerPattern(opts: { fill: string; devicePixelR parentOpacity: 1 }); - return context2d; + // context2d.fill = fill; + + return { context2d, fill }; } diff --git a/packages/idraw/dev/main.ts b/packages/idraw/dev/main.ts index e7fbdda8..9bf4afff 100644 --- a/packages/idraw/dev/main.ts +++ b/packages/idraw/dev/main.ts @@ -2,42 +2,44 @@ import { iDraw } from '../src/index'; import { getData } from './data'; +const styles = { + selector: { + activeColor: 'red', + activeAreaColor: '#FF00001C', + lockedColor: 'black', + referenceColor: 'green' + }, + info: { + textBackground: 'yellow', + textColor: 'red' + }, + ruler: { + background: '#0000FF1A', + borderColor: '#0000FF', + scaleColor: '#FF0000', + textColor: '#000000', + gridColor: '#0000FF1C', + gridPrimaryColor: '#0000FFAC', + selectedAreaColor: '#FF0000CC' + }, + scroller: { + thumbBackground: '#FF00003A', + thumbBorderColor: '#FF00008A', + hoverThumbBackground: '#FF00006E', + hoverThumbBorderColor: '#FF0000EE', + activeThumbBackground: '#FF00005E', + activeThumbBorderColor: '#FF0000F0' + }, + layoutSelector: { + activeColor: '#00FF00' + } +}; + const opts = { width: 800, height: 500, - devicePixelRatio: 2, - styles: { - selector: { - activeColor: 'red', - activeAreaColor: '#FF00001C', - lockedColor: 'black', - referenceColor: 'green' - }, - info: { - textBackground: 'yellow', - textColor: 'red' - }, - ruler: { - background: '#0000FF1A', - borderColor: '#0000FF', - scaleColor: '#FF0000', - textColor: '#000000', - gridColor: '#0000FF1C', - gridPrimaryColor: '#0000FFAC', - selectedAreaColor: '#FF0000CC' - }, - scroller: { - thumbBackground: '#FF00003A', - thumbBorderColor: '#FF00008A', - hoverThumbBackground: '#FF00006E', - hoverThumbBorderColor: '#FF0000EE', - activeThumbBackground: '#FF00005E', - activeThumbBorderColor: '#FF0000F0' - }, - layoutSelector: { - activeColor: '#00FF00' - } - } + devicePixelRatio: 2 + // styles, }; const mount = document.querySelector('#mount') as HTMLDivElement; @@ -45,6 +47,10 @@ const data = getData(); const idraw = new iDraw(mount, opts); idraw.setData(data); idraw.centerContent(); + +setTimeout(() => { + idraw.reset({ styles }); +}, 2000); // idraw.scale(0.5); // idraw.scale(2); // idraw.scrollX(-80); diff --git a/packages/idraw/src/idraw.ts b/packages/idraw/src/idraw.ts index cc4cf4a8..957fcdc8 100644 --- a/packages/idraw/src/idraw.ts +++ b/packages/idraw/src/idraw.ts @@ -27,11 +27,12 @@ import { calcViewCenter, Store } from '@idraw/util'; -import { defaultSettings, getDefaultStorage, defaultMode, parseStyles } from './config'; +import { defaultSettings, getDefaultStorage, defaultMode, parseStyles, parseSettings } from './setting/config'; import { exportImageFileBlobURL } from './file'; import type { ExportImageFileBaseOptions, ExportImageFileResult } from './file'; import type { IDrawEvent } from './event'; -import { changeMode, runMiddlewares } from './mode'; +import { changeMode, runMiddlewares } from './setting/mode'; +import { changeStyles } from './setting/style'; export class iDraw { #core: Core; @@ -82,12 +83,28 @@ export class iDraw { reset(opts: IDrawSettings) { const core = this.#core; const store = this.#store; + const { mode, styles } = parseSettings(opts); + let needFresh = false; + let newOpts: IDrawSettings = {}; store.clear(); - changeMode(opts.mode || defaultMode, core, store); - core.refresh(); + if (mode) { + changeMode(mode, core, store); + newOpts.mode = mode; + needFresh = true; + } + if (styles) { + changeStyles(styles, core, store); + newOpts.styles = styles; + needFresh = true; + } + + if (needFresh === true) { + core.refresh(); + } + this.#opts = { ...this.#opts, - ...opts + ...newOpts }; } diff --git a/packages/idraw/src/config.ts b/packages/idraw/src/setting/config.ts similarity index 75% rename from packages/idraw/src/config.ts rename to packages/idraw/src/setting/config.ts index 21d48b95..ea60790a 100644 --- a/packages/idraw/src/config.ts +++ b/packages/idraw/src/setting/config.ts @@ -28,7 +28,45 @@ export function getDefaultStorage(): IDrawStorage { return storage; } -export function parseStyles(opts: IDrawSettings) { +export function parseSettings(opts: IDrawSettings) { + const { mode, styles } = opts; + const settings: IDrawSettings = {}; + if (istype.string(mode)) { + settings.mode = mode; + } + if (styles) { + settings.styles = parseStrictStyles(opts); + } + + return settings; +} + +export function parseStrictStyles(settings: IDrawSettings): IDrawSettings['styles'] { + const styles = parseStyles(settings); + const strictStyles: IDrawSettings['styles'] = {}; + + const { selector, info, ruler, scroller, layoutSelector } = styles; + if (Object.keys(selector).length > 0) { + strictStyles.selector = selector; + } + if (Object.keys(info).length > 0) { + strictStyles.info = info; + } + + if (Object.keys(ruler).length > 0) { + strictStyles.ruler = ruler; + } + if (Object.keys(scroller).length > 0) { + strictStyles.scroller = scroller; + } + if (Object.keys(layoutSelector).length > 0) { + strictStyles.layoutSelector = layoutSelector; + } + + return strictStyles; +} + +export function parseStyles(settings: IDrawSettings): Required['styles']> { const styles: Required = { selector: {}, ruler: {}, @@ -36,9 +74,9 @@ export function parseStyles(opts: IDrawSettings) { scroller: {}, layoutSelector: {} }; - if (opts.styles) { + if (settings.styles) { // selector - const { selector, info, ruler, scroller, layoutSelector } = opts.styles; + const { selector, info, ruler, scroller, layoutSelector } = settings.styles; if (istype.string(selector?.activeColor)) { styles.selector.activeColor = selector?.activeColor; } @@ -108,5 +146,6 @@ export function parseStyles(opts: IDrawSettings) { styles.layoutSelector.activeColor = layoutSelector?.activeColor; } } + return styles; } diff --git a/packages/idraw/src/mode.ts b/packages/idraw/src/setting/mode.ts similarity index 98% rename from packages/idraw/src/mode.ts rename to packages/idraw/src/setting/mode.ts index 3c94395c..19593067 100644 --- a/packages/idraw/src/mode.ts +++ b/packages/idraw/src/setting/mode.ts @@ -12,7 +12,7 @@ import { MiddlewareInfo, MiddlewarePointer } from '@idraw/core'; -import { IDrawEvent } from './event'; +import { IDrawEvent } from '../event'; function isValidMode(mode: string | IDrawMode) { return ['select', 'drag', 'readOnly'].includes(mode); diff --git a/packages/idraw/src/setting/style.ts b/packages/idraw/src/setting/style.ts new file mode 100644 index 00000000..696c42dd --- /dev/null +++ b/packages/idraw/src/setting/style.ts @@ -0,0 +1,29 @@ +import { Core, MiddlewareInfo, MiddlewareLayoutSelector, MiddlewareRuler, MiddlewareScroller, MiddlewareSelector } from '@idraw/core'; +import { Store } from '@idraw/util'; +import type { IDrawSettings, IDrawStorage } from '@idraw/types'; +import type { IDrawEvent } from '../event'; + +export function changeStyles(styles: Required['styles'], core: Core, store: Store) { + const { selector, info, ruler, scroller, layoutSelector } = styles; + const middlewareStyles = store.get('middlewareStyles'); + if (selector) { + core.resetMiddlewareConfig(MiddlewareSelector, selector); + middlewareStyles.selector = { ...middlewareStyles.selector, ...selector }; + } + if (info) { + core.resetMiddlewareConfig(MiddlewareInfo, info); + middlewareStyles.info = { ...middlewareStyles.info, ...info }; + } + if (ruler) { + core.resetMiddlewareConfig(MiddlewareRuler, ruler); + middlewareStyles.ruler = { ...middlewareStyles.ruler, ...ruler }; + } + if (scroller) { + core.resetMiddlewareConfig(MiddlewareScroller, scroller); + middlewareStyles.scroller = { ...middlewareStyles.scroller, ...scroller }; + } + if (layoutSelector) { + core.resetMiddlewareConfig(MiddlewareLayoutSelector, layoutSelector); + middlewareStyles.layoutSelector = { ...middlewareStyles.layoutSelector, ...layoutSelector }; + } +} diff --git a/packages/types/src/lib/board.ts b/packages/types/src/lib/board.ts index db66e4a7..4d794df1 100644 --- a/packages/types/src/lib/board.ts +++ b/packages/types/src/lib/board.ts @@ -60,10 +60,12 @@ export interface BoardWatcherEventMap = any> clear: void; } -export interface BoardMiddlewareObject = any> { +export interface BoardMiddlewareObject = any, C extends any = undefined> { name?: string; use?: () => void; disuse?: () => void; + resetConfig?: (config?: Partial) => void; + // action hover?: (e: BoardWatcherEventMap['hover']) => void | boolean; pointStart?: (e: BoardWatcherEventMap['pointStart']) => void | boolean; @@ -99,7 +101,7 @@ export interface BoardMiddlewareOptions = Re export type BoardMiddleware = any, E extends BoardExtendEventMap = BoardExtendEventMap, C extends any = undefined> = ( opts: BoardMiddlewareOptions, config?: C -) => BoardMiddlewareObject; +) => BoardMiddlewareObject; export interface BoardOptions { boardContent: BoardContent; diff --git a/packages/types/src/lib/idraw.ts b/packages/types/src/lib/idraw.ts index 18206bc5..85829d62 100644 --- a/packages/types/src/lib/idraw.ts +++ b/packages/types/src/lib/idraw.ts @@ -27,5 +27,5 @@ export interface IDrawStorage { enableTextEdit: boolean; enableDrag: boolean; enableInfo: boolean; - middlewareStyles: Required; + middlewareStyles: Required['styles']>; }