refactor: refactor types for v0.4

This commit is contained in:
chenshenhai 2023-04-15 10:41:15 +08:00
parent d5b79fa8c3
commit 5b5aa90743
19 changed files with 275 additions and 496 deletions

View file

@ -1,12 +1,9 @@
export * from './lib/util';
export * from './lib/point';
export * from './lib/data';
export * from './lib/context';
export * from './lib/board';
export * from './lib/paint';
export * from './lib/element';
export * from './lib/helper';
export * from './lib/config';
export * from './lib/core';
export * from './lib/screen';
export * from './lib/device';
export * from './lib/plugin';
export * from './lib/common';
export * from './lib/view';
export * from './lib/board';
export * from './lib/renderer';
export * from './lib/loader';
export * from './lib/store';

View file

@ -1,48 +1,80 @@
type Point = {
x: number;
y: number;
};
import type { Point } from './point';
import type { ViewContent, ViewCalculator } from './view';
import type { UtilEventEmitter } from './util';
import type { Renderer } from '../renderer';
import type { ActiveStore, StoreSharer } from './store';
type BoardScrollConfig = {
color: string;
width: number;
showBackground?: boolean;
};
interface BoardWatcherPointEvent {
point: Point;
}
type BoardSizeOptions = {
width?: number;
height?: number;
contextWidth?: number;
contextHeight?: number;
devicePixelRatio?: number;
};
interface BoardWatherWheelEvent {
deltaX: number;
deltaY: number;
}
type BoardOptions = BoardSizeOptions & {
width: number;
height: number;
contextWidth: number;
contextHeight: number;
canScroll?: boolean;
scrollConfig?: BoardScrollConfig;
};
interface BoardWatherDrawFrameEvent {
snapshot: BoardViewerFrameSnapshot;
}
type PointCursor =
| 'auto'
| 'move'
| 'n-resize'
| 'e-resize'
| 's-resize'
| 'w-resize'
| 'ne-resize'
| 'nw-resize'
| 'se-resize'
| 'sw-resize'
| 'grab';
export interface BoardWatcherEventMap {
hover: BoardWatcherPointEvent;
pointStart: BoardWatcherPointEvent;
pointMove: BoardWatcherPointEvent;
pointEnd: BoardWatcherPointEvent;
pointLeave: BoardWatcherPointEvent;
doubleClick: BoardWatcherPointEvent;
wheel: BoardWatherWheelEvent;
beforeDrawFrame: BoardWatherDrawFrameEvent;
afterDrawFrame: BoardWatherDrawFrameEvent;
}
export {
Point,
PointCursor,
BoardSizeOptions,
BoardOptions,
BoardScrollConfig
};
export type BoardMode = 'SELECT' | 'RULER' | 'CONNECT' | 'PENCIL' | 'PEN';
export interface BoardMiddlewareObject {
mode: BoardMode;
created?: () => void;
hover?: (e: BoardWatcherEventMap['hover']) => void;
pointStart?: (e: BoardWatcherEventMap['pointStart']) => void;
pointMove?: (e: BoardWatcherEventMap['pointMove']) => void;
pointEnd?: (e: BoardWatcherEventMap['pointEnd']) => void;
pointLeave?: (e: BoardWatcherEventMap['pointLeave']) => void;
doubleClick?: (e: BoardWatcherEventMap['doubleClick']) => void;
wheel?: (e: BoardWatcherEventMap['wheel']) => void;
beforeDrawFrame?(e: BoardWatcherEventMap['beforeDrawFrame']): void;
afterDrawFrame?(e: BoardWatcherEventMap['afterDrawFrame']): void;
}
export interface BoardMiddlewareOptions {
viewContent: ViewContent;
sharer: StoreSharer;
viewer: BoardViewer;
calculator: ViewCalculator;
}
export type BoardMiddleware = (opts: BoardMiddlewareOptions) => BoardMiddlewareObject;
export interface BoardOptions {
viewContent: ViewContent;
}
export interface BoardViewerFrameSnapshot {
activeStore: ActiveStore;
sharedStore: Record<string, any>;
}
export interface BoardViewerEventMap {
drawFrame: {};
}
export interface BoardViewerOptions {
sharer: StoreSharer;
renderer: Renderer;
viewContent: ViewContent;
beforeDrawFrame: (e: { snapshot: BoardViewerFrameSnapshot }) => void;
afterDrawFrame: (e: { snapshot: BoardViewerFrameSnapshot }) => void;
}
export interface BoardViewer extends UtilEventEmitter<BoardViewerEventMap> {
drawFrame(): void;
}

View file

@ -1,35 +0,0 @@
type IsTypeUtil = {
x: (value: any) => boolean;
y: (value: any) => boolean;
w: (value: any) => boolean;
h: (value: any) => boolean;
angle: (value: any) => boolean;
number: (value: any) => boolean;
borderWidth: (value: any) => boolean;
borderRadius: (value: any) => boolean;
color: (value: any) => boolean;
imageSrc: (value: any) => boolean;
imageURL: (value: any) => boolean;
imageBase64: (value: any) => boolean;
svg: (value: any) => boolean;
html: (value: any) => boolean;
text: (value: any) => boolean;
fontSize: (value: any) => boolean;
fontWeight: (value: any) => boolean;
lineHeight: (value: any) => boolean;
textAlign: (value: any) => boolean;
fontFamily: (value: any) => boolean;
strokeWidth: (value: any) => boolean;
};
type CheckTypeUtil = {
attrs: (value: any) => boolean;
rectDesc: (value: any) => boolean;
circleDesc: (value: any) => boolean;
imageDesc: (value: any) => boolean;
svgDesc: (value: any) => boolean;
htmlDesc: (value: any) => boolean;
textDesc: (value: any) => boolean;
};
export { IsTypeUtil, CheckTypeUtil };

View file

@ -1,26 +0,0 @@
type IDrawConfig = {
elementWrapper?: {
color?: string;
controllerSize?: number;
lineWidth?: number;
lineDash?: number[];
};
scrollWrapper?: {
use?: boolean;
color?: string;
width?: number;
showBackground?: boolean;
};
};
type IDrawConfigStrict = IDrawConfig & {
elementWrapper: {
color: string;
lockColor: string;
controllerSize: number;
lineWidth: number;
lineDash: number[];
};
};
export { IDrawConfig, IDrawConfigStrict };

View file

@ -1,71 +0,0 @@
interface IDrawContext {
getContext(): CanvasRenderingContext2D;
setTransform(config: {
scale?: number;
scrollX?: number;
scrollY?: number;
}): void;
getTransform(): {
scale: number;
scrollX: number;
scrollY: number;
}
getSize(): {
width: number;
height: number;
contextWidth: number;
contextHeight: number;
devicePixelRatio: number;
};
resetSize(opts: {
width?: number;
height?: number;
contextWidth?: number;
contextHeight?: number;
devicePixelRatio?: number;
}): void;
calcDeviceNum(num: number): number;
calcScreenNum(num: number): number;
setFillStyle(color: string | CanvasPattern): void;
fill(fillRule?: CanvasFillRule | undefined): void;
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean | undefined): void;
fillRect(x: number, y: number, w: number, h: number): void;
clearRect(x: number, y: number, w: number, h: number): void;
rect(x: number, y: number, w: number, h: number): void;
beginPath(): void;
closePath(): void;
moveTo(x: number, y: number): void;
lineTo(x: number, y: number): void;
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
setLineWidth(w: number): void;
setLineDash(nums: number[]): void;
isPointInPath(x: number, y: number): boolean;
isPointInPathWithoutScroll(x: number, y: number): boolean;
setStrokeStyle(color: string): void;
stroke(): void;
translate(x: number, y: number): void;
rotate(angle: number): void;
measureText(text: string): TextMetrics;
setTextAlign(align: CanvasTextAlign): void;
fillText(text: string, x: number, y: number, maxWidth?: number | undefined): void;
strokeText(text: string, x: number, y: number, maxWidth?: number | undefined): void;
setFont(opts: { fontSize: number, fontFamily?: string, fontWeight?: string }): void
setTextBaseline(baseline: CanvasTextBaseline): void;
save(): void;
restore(): void;
scale(ratioX: number, ratioY: number): void;
drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null;
setGlobalAlpha(alpha: number): void;
setShadowColor(color: string): void;
setShadowOffsetX(offsetX: number): void;
setShadowOffsetY(offsetY: number): void;
setShadowBlur(blur: number): void;
ellipse(x: number,y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean | undefined): void
}
export {
IDrawContext
};

View file

@ -1,10 +0,0 @@
type CoreOptions = {
width: number;
height: number;
devicePixelRatio: number;
contextWidth: number;
contextHeight: number;
onlyRender?: boolean;
};
export { CoreOptions };

View file

@ -1,13 +1,5 @@
import { DataElemDesc, DataElement, DataElementBase } from './element';
import type { Element, ElementType } from './element';
type IDrawDataBase = {
elements: DataElementBase<keyof DataElemDesc>[];
bgColor?: string;
};
type IDrawData = {
elements: DataElement<keyof DataElemDesc>[];
bgColor?: string;
};
export { IDrawData, IDrawDataBase };
export interface Data {
elements: Element<ElementType>[];
}

View file

@ -1,8 +0,0 @@
type DeviceSize = {
x: number;
y: number;
w: number;
h: number;
};
export { DeviceSize };

View file

@ -1,120 +1,70 @@
// import { PaintData } from './paint';
type DataElementAttrs = {
export interface ElementSize {
x: number;
y: number;
w: number;
h: number;
angle?: number;
operation?: {
lock?: boolean;
invisible?: boolean;
disableScale?: boolean;
disableRotate?: boolean;
limitRatio?: boolean;
};
extension?: { [key: string]: any } | any;
};
}
type DataElementBase<T extends keyof DataElemDesc | DataElemType> =
DataElementAttrs & {
name?: string;
uuid?: string;
type: T | DataElemType;
desc: DataElemDesc[T];
};
type DataElement<T extends keyof DataElemDesc | DataElemType> =
DataElementBase<T> & {
uuid: string;
};
type DataElemDescBase = {
shadowColor?: string;
shadowOffsetX?: number;
shadowOffsetY?: number;
shadowBlur?: number;
};
type DataElemBoxDesc = {
interface ElementRectDesc {
color?: string;
bgColor?: string;
borderRadius?: number;
}
interface ElementEllipseDesc {
radius: number;
bgColor?: string;
borderWidth?: number;
borderColor?: string;
} & DataElemDescBase;
}
type DataElemDesc = {
text: DataElemDescText;
rect: DataElemDescRect;
circle: DataElemDescCircle;
image: DataElemDescImage;
svg: DataElemDescSVG;
html: DataElemDescHTML;
// paint: DataElemDescPaint,
};
interface ElementBaseDesc {
// TODO
}
// enum DataElemType {
// text = 'text',
// rect = 'rect',
// circle = 'circle',
// image = 'image',
// svg = 'svg',
// html = 'html',
// }
type DataElemType = 'text' | 'rect' | 'circle' | 'image' | 'svg' | 'html';
type DataElemDescRect = {
bgColor?: string;
} & DataElemBoxDesc;
type DataElemDescText = {
text: string;
color: string;
fontSize: number;
lineHeight?: number;
fontWeight?: 'bold' | '';
fontFamily?: string;
textAlign?: 'center' | 'left' | 'right';
verticalAlign?: 'middle' | 'top' | 'bottom';
bgColor?: string;
strokeColor?: string;
strokeWidth?: number;
textShadowColor?: string;
textShadowOffsetX?: number;
textShadowOffsetY?: number;
textShadowBlur?: number;
} & DataElemBoxDesc;
type DataElemDescCircle = {
bgColor: string;
} & DataElemBoxDesc;
type DataElemDescImage = {
src: string;
} & DataElemDescBase;
type DataElemDescSVG = {
svg: string;
};
type DataElemDescHTML = {
interface ElementHTMLDesc extends ElementBaseDesc {
html: string;
width: number;
height: number;
};
}
// type DataElemDescPaint = PaintData
interface ElementImageDesc extends ElementBaseDesc {
src: string;
}
export {
DataElementAttrs,
DataElemDescText,
DataElemDescRect,
DataElemDescCircle,
DataElemDescImage,
DataElemDescSVG,
DataElemDescHTML,
DataElemDesc,
DataElemType,
DataElement,
DataElementBase
};
interface ElementSVGDesc extends ElementBaseDesc {
svg: string;
}
interface ElementDescMap {
rect: ElementRectDesc;
ellipse: ElementEllipseDesc;
polygon: ElementBaseDesc; // TODO
paint: ElementBaseDesc; // TODO
pen: ElementBaseDesc; // TODO
image: ElementImageDesc;
html: ElementHTMLDesc;
svg: ElementSVGDesc;
}
export type ElementType = 'rect' | 'ellipse' | 'polygon' | 'paint' | 'pen' | 'image' | 'html' | 'svg'; // TODO
export interface ElementOperation {
lock?: boolean;
invisible?: boolean;
disableScale?: boolean;
disableRotate?: boolean;
limitRatio?: boolean;
lastModified?: number;
}
export interface Element<T extends ElementType> {
uuid: string;
x: number;
y: number;
w: number;
h: number;
type: T;
desc: ElementDescMap[T];
operation?: ElementOperation;
}

View file

@ -1,87 +0,0 @@
import { IDrawData } from './data';
import { Point } from './board';
// type test = {[uuid string]: DataElement}
type HelperController = Point & {
invisible?: boolean;
};
type HeplerSelectedElementWrapper = {
uuid: string;
controllerSize: number;
controllerOffset: number;
lock: boolean;
controllers: {
topLeft: HelperController;
top: HelperController;
topRight: HelperController;
right: HelperController;
bottomRight: HelperController;
bottom: HelperController;
bottomLeft: HelperController;
left: HelperController;
rotate: HelperController;
};
lineDash: number[];
lineWidth: number;
color: string;
radian?: number;
translate?: Point;
};
type HeplerSelectedAreaWrapper = {
x: number;
y: number;
w: number;
h: number;
startPoint: Point;
endPoint: Point;
lineWidth: number;
lineDash: number[];
color: string;
};
type HelperConfig = {
elementIndexMap: { [key: string]: number };
selectedAreaWrapper?: HeplerSelectedAreaWrapper;
selectedElementWrapper?: HeplerSelectedElementWrapper;
selectedElementListWrappers?: Array<HeplerSelectedElementWrapper>;
};
type HelperUpdateOpts = {
width: number;
height: number;
selectedUUID?: string | null;
selectedUUIDList?: string[];
devicePixelRatio: number;
scale: number;
canScroll: boolean;
scrollX: number;
scrollY: number;
};
// interface Helper {
// updateConfig(data: IDrawData, opts: HelperUpdateOpts): void;
// getConfig(): HelperConfig;
// }
type HelperWrapperControllerDirection =
| 'top-left'
| 'top'
| 'top-right'
| 'right'
| 'bottom-right'
| 'bottom'
| 'bottom-left'
| 'left'
| 'rotate';
export {
// Helper,
HelperConfig,
HelperUpdateOpts,
HelperWrapperControllerDirection,
HeplerSelectedElementWrapper,
HeplerSelectedAreaWrapper
};

View file

@ -0,0 +1,31 @@
import type { ElementType, Element } from './element';
export type LoadElementType = 'image' | 'svg' | 'html';
export interface LoadItem {
element: Element<LoadElementType>;
status: 'null' | 'load' | 'error';
content: LoadContent | null;
startTime: number;
endTime: number;
error?: any;
}
export interface LoaderEvent extends LoadItem {
countTime: number;
}
export interface LoaderEventMap {
load: LoaderEvent;
error: LoaderEvent;
}
export interface LoadResult<C> {
uuid: string;
lastModified: number;
content: C;
}
export type LoadContent = HTMLImageElement | HTMLCanvasElement;
export type LoadFunc<T extends ElementType, C extends LoadContent> = (element: Element<T>) => Promise<LoadResult<C>>;

View file

@ -1,23 +0,0 @@
export type PaintData = {
brushMap: { [name: string]: PaintBrush };
paths: PaintPath[];
};
export type PaintBrush = {
name: string;
src: string;
};
export type PaintPath = {
brush: string;
size: number;
positions: PaintPosition[];
color: string;
pressure: number;
};
export type PaintPosition = {
x: number;
y: number;
t: number;
};

View file

@ -1,39 +0,0 @@
import { IDrawData } from './data';
import { DataElemDesc, DataElement } from './element';
import { IDrawContext } from './context';
import { Point, PointCursor } from './board';
export type HelperPluginEventDetail = {
controller: string | null;
point: Point;
selectedElement: DataElement<keyof DataElemDesc> | null;
data: IDrawData;
helperCtx: IDrawContext;
};
export type HelperPluginEventResult = {
cursor?: PointCursor;
beController?: boolean;
};
export interface InterfaceHelperPlugin {
readonly name?: string;
readonly uuid?: string;
onHover?: (detail: HelperPluginEventDetail) => void | HelperPluginEventResult;
onPoint?: (detail: HelperPluginEventDetail) => void | HelperPluginEventResult;
onClick?: (detail: HelperPluginEventDetail) => void | HelperPluginEventResult;
onMoveStart?: (
detail: HelperPluginEventDetail
) => void | HelperPluginEventResult;
onMove?: (detail: HelperPluginEventDetail) => void | HelperPluginEventResult;
onMoveEnd?: (
detail: HelperPluginEventDetail
) => void | HelperPluginEventResult;
}

View file

@ -0,0 +1,11 @@
export interface PointSize {
x: number;
y: number;
}
export interface Point extends PointSize {
t: number;
}
export interface TouchPoint extends Point {
f: number; // force, pressure
}

View file

@ -0,0 +1,31 @@
import type { ViewContent, ViewScaleInfo, ViewCalculator } from './view';
import type { Element } from './element';
import type { LoaderEventMap, LoadElementType, LoadContent } from './loader';
import type { UtilEventEmitter } from './util';
import type { StoreSharer } from './store';
export interface RendererOptions {
viewContent: ViewContent;
sharer: StoreSharer;
calculator: ViewCalculator;
}
export interface RendererEvent {
viewContext: ViewContent['viewContext'];
}
export interface RendererEventMap {
load: LoaderEventMap['load'];
}
export interface RendererLoader extends UtilEventEmitter<LoaderEventMap> {
load(element: Element<LoadElementType>): void;
getContent(uuid: string): LoadContent | null;
}
export interface RendererDrawOptions extends ViewScaleInfo {}
export interface RendererDrawElementOptions extends RendererDrawOptions {
loader: RendererLoader;
calculator: ViewCalculator;
}

View file

@ -1,27 +0,0 @@
type ScreenData = {
scale: number;
scrollLeft: number;
scrollTop: number;
// selectedElementUUID: string | null;
};
type ScreenPosition = {
top: number;
bottom: number;
left: number;
right: number;
};
type ScreenSize = {
x: number;
y: number;
w: number;
h: number;
};
type ScreenContext = {
size: ScreenSize;
position: ScreenPosition;
};
export { ScreenData, ScreenPosition, ScreenSize, ScreenContext };

View file

@ -0,0 +1,24 @@
import { Data } from './data';
import { ViewScaleInfo } from './view';
export type ActiveStore = ViewScaleInfo & {
contextWidth: number;
contextHeight: number;
data: Data | null;
selectedIndexs: number[];
selectedUUIDs: string[];
// scale: number;
// offsetLeft: number;
// offsetRight: number;
// offsetTop: number;
// offsetBottom: number;
};
export interface StoreSharer {
getActiveStorage<T extends keyof ActiveStore>(key: T): ActiveStore[T];
setActiveStorage<T extends keyof ActiveStore>(key: T, storage: ActiveStore[T]): void;
getActiveStoreSnapshot(): ActiveStore;
getSharedStorage(key: string): any;
setSharedStorage(key: string, storage: any): void;
getSharedStoreSnapshot(): Record<string, any>;
}

View file

@ -0,0 +1,6 @@
export interface UtilEventEmitter<T extends Record<string, any>> {
on<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
off<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
trigger<K extends keyof T>(eventKey: K, e: T[K]): void;
has<K extends keyof T>(name: K | string): boolean;
}

View file

@ -0,0 +1,31 @@
import type { Element, ElementType, ElementSize } from './element';
import type { Point } from './point';
import type { Data } from './data';
export interface ViewScaleInfo {
scale: number;
offsetTop: number;
offsetBottom: number;
offsetLeft: number;
offsetRight: number;
}
export interface ViewContent {
viewContext: CanvasRenderingContext2D;
helperContext: CanvasRenderingContext2D;
boardContext: CanvasRenderingContext2D;
}
export interface ViewCalculatorOptions {
viewContent: ViewContent;
}
export interface ViewCalculator {
viewScale(num: number, prevScaleInfo?: ViewScaleInfo): ViewScaleInfo;
isElementInView(elem: Element<ElementType>, scaleInfo: ViewScaleInfo): boolean;
isPointInElement(p: Point, elem: Element<ElementType>, scaleInfo: ViewScaleInfo): boolean;
pointToViewPoint(p: Point): Point;
elementSize(size: ElementSize, scaleInfo: ViewScaleInfo): ElementSize;
getPointElement(p: Point, data: Data, scaleInfo: ViewScaleInfo): { index: number; element: null | Element<ElementType> };
// TODO
}