chore: improve build script

This commit is contained in:
chenshenhai 2023-02-12 11:39:24 +08:00
parent d26f4686a0
commit 4360131bbd
20 changed files with 666 additions and 305 deletions

View file

@ -3,7 +3,7 @@
"private": false,
"type": "module",
"scripts": {
"postinstall": "npm run build",
"_postinstall": "npm run build",
"dev": "vite-node ./scripts/dev.ts",
"dev:mod": "vite-node ./scripts/dev-mod.ts",
"build": "npm run build:mod && npm run build:bundle && npm run build:min",
@ -32,8 +32,11 @@
"@babel/core": "^7.20.7",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@types/glob": "^8.0.1",
"@types/jest": "^29.2.5",
"@types/koa-compose": "^3.2.5",
"@types/node": "^18.11.18",
"@types/serve-handler": "^6.1.1",
"@typescript-eslint/eslint-plugin": "^5.47.1",
"@typescript-eslint/parser": "^5.47.1",
"babel-jest": "^29.3.1",

View file

@ -1,9 +1,13 @@
import {
TypePoint, TypeHelperWrapperControllerDirection,InterfaceHelperPlugin,
TypeConfigStrict, TypeData, TypeHelperConfig,
TypePoint,
TypeHelperWrapperControllerDirection,
InterfaceHelperPlugin,
TypeConfigStrict,
TypeData,
TypeHelperConfig
} from '@idraw/types';
import { deepClone, throttle } from '@idraw/util';
import { Board } from '@idraw/board';
import Board from '@idraw/board';
import { Mode, CursorStatus } from './../constant/static';
import { TempData } from './engine-temp';
import { Helper } from './helper';
@ -12,26 +16,25 @@ import { Element } from './element';
import { CoreEvent } from './core-event';
type Options = {
coreEvent: CoreEvent,
board: Board,
element: Element,
config: TypeConfigStrict,
drawFeekback: () => void,
coreEvent: CoreEvent;
board: Board;
element: Element;
config: TypeConfigStrict;
drawFeekback: () => void;
getDataFeekback: () => TypeData;
selectElementByIndex: (index: number, opts?: { useMode?: boolean }) => void,
emitChangeScreen: () => void,
emitChangeData: () => void,
}
selectElementByIndex: (index: number, opts?: { useMode?: boolean }) => void;
emitChangeScreen: () => void;
emitChangeData: () => void;
};
export class Engine {
private _plugins: InterfaceHelperPlugin[] = [];
private _opts: Options;
private _mapper: Mapper;
public temp: TempData;
public helper: Helper;
constructor(opts: Options) {
const { board, config, element } = opts;
const helper = new Helper(board, config);
@ -50,12 +53,14 @@ export class Engine {
}
updateHelperConfig(opts: {
width: number, height: number, devicePixelRatio: number
width: number;
height: number;
devicePixelRatio: number;
}) {
const { board, getDataFeekback, config } = this._opts;
const data = getDataFeekback();
const transform = board.getTransform();
this.helper.updateConfig(data,{
this.helper.updateConfig(data, {
width: opts.width,
height: opts.height,
devicePixelRatio: opts.devicePixelRatio,
@ -64,8 +69,8 @@ export class Engine {
selectedUUIDList: this.temp.get('selectedUUIDList'),
scale: transform.scale,
scrollX: transform.scrollX,
scrollY: transform.scrollY,
})
scrollY: transform.scrollY
});
}
init() {
@ -77,7 +82,7 @@ export class Engine {
return;
}
const { board } = this._opts;
board.on('hover', throttle(this._handleHover.bind(this), 32));
board.on('leave', throttle(this._handleLeave.bind(this), 32));
board.on('point', throttle(this._handleClick.bind(this), 16));
@ -88,17 +93,18 @@ export class Engine {
board.on('moveEnd', this._handleMoveEnd.bind(this));
}
private _handleDoubleClick (point: TypePoint) {
private _handleDoubleClick(point: TypePoint) {
const { element, getDataFeekback, drawFeekback, coreEvent } = this._opts;
const data = getDataFeekback();
const [index, uuid] = element.isPointInElement(point, data);
if (index >= 0 && uuid) {
const elem = deepClone(data.elements?.[index]);
if (elem?.operation?.invisible !== true) {
coreEvent.trigger(
'screenDoubleClickElement',
{ index, uuid, element: deepClone(data.elements?.[index])}
);
coreEvent.trigger('screenDoubleClickElement', {
index,
uuid,
element: deepClone(data.elements?.[index])
});
}
}
drawFeekback();
@ -109,8 +115,12 @@ export class Engine {
return;
}
const {
element, getDataFeekback, selectElementByIndex, coreEvent,
emitChangeScreen, drawFeekback
element,
getDataFeekback,
selectElementByIndex,
coreEvent,
emitChangeScreen,
drawFeekback
} = this._opts;
const helper = this.helper;
const data = getDataFeekback();
@ -118,24 +128,30 @@ export class Engine {
// Coontroll Element-List
this.temp.set('mode', Mode.SELECT_ELEMENT_LIST);
} else {
const {
uuid, selectedControllerDirection
} = helper.isPointInElementWrapperController(point, data);
const { uuid, selectedControllerDirection } =
helper.isPointInElementWrapperController(point, data);
if (uuid && selectedControllerDirection) {
// Controll Element-Wrapper
this.temp.set('mode', Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER);
this.temp.set('selectedControllerDirection', selectedControllerDirection);
this.temp.set(
'selectedControllerDirection',
selectedControllerDirection
);
this.temp.set('selectedUUID', uuid);
} else {
const [index, uuid] = element.isPointInElement(point, data);
if (index >= 0 && data.elements[index]?.operation?.invisible !== true) {
// Controll Element
selectElementByIndex(index, { useMode: true });
if (typeof uuid === 'string' && coreEvent.has('screenSelectElement')) {
coreEvent.trigger(
'screenSelectElement',
{ index, uuid, element: deepClone(data.elements?.[index])}
);
if (
typeof uuid === 'string' &&
coreEvent.has('screenSelectElement')
) {
coreEvent.trigger('screenSelectElement', {
index,
uuid,
element: deepClone(data.elements?.[index])
});
emitChangeScreen();
}
this.temp.set('mode', Mode.SELECT_ELEMENT);
@ -151,30 +167,27 @@ export class Engine {
}
private _handleClick(point: TypePoint): void {
const {
element, getDataFeekback, coreEvent, drawFeekback
} = this._opts;
const { element, getDataFeekback, coreEvent, drawFeekback } = this._opts;
const data = getDataFeekback();
const [index, uuid] = element.isPointInElement(point, data);
if (index >= 0 && uuid) {
coreEvent.trigger(
'screenClickElement',
{ index, uuid, element: deepClone(data.elements?.[index])}
);
coreEvent.trigger('screenClickElement', {
index,
uuid,
element: deepClone(data.elements?.[index])
});
}
drawFeekback();
}
private _handleMoveStart(point: TypePoint): void {
const {
element, getDataFeekback, coreEvent
} = this._opts;
const { element, getDataFeekback, coreEvent } = this._opts;
const data = getDataFeekback();
const helper = this.helper;
this.temp.set('prevPoint', point);
const uuid = this.temp.get('selectedUUID');
if (this.temp.get('mode') === Mode.SELECT_ELEMENT_LIST) {
// TODO
} else if (this.temp.get('mode') === Mode.SELECT_ELEMENT) {
@ -185,7 +198,7 @@ export class Engine {
x: point.x,
y: point.y
});
}
}
} else if (this.temp.get('mode') === Mode.SELECT_AREA) {
helper.startSelectArea(point);
}
@ -195,68 +208,104 @@ export class Engine {
const { drawFeekback } = this._opts;
const helper = this.helper;
if (this.temp.get('mode') === Mode.SELECT_ELEMENT_LIST) {
this._dragElements(this.temp.get('selectedUUIDList'), point, this.temp.get('prevPoint'));
this._dragElements(
this.temp.get('selectedUUIDList'),
point,
this.temp.get('prevPoint')
);
drawFeekback();
this.temp.set('cursorStatus', CursorStatus.DRAGGING);
} else if (typeof this.temp.get('selectedUUID') === 'string') {
if (this.temp.get('mode') === Mode.SELECT_ELEMENT) {
this._dragElements([this.temp.get('selectedUUID') as string], point, this.temp.get('prevPoint'));
this._dragElements(
[this.temp.get('selectedUUID') as string],
point,
this.temp.get('prevPoint')
);
drawFeekback();
this.temp.set('cursorStatus', CursorStatus.DRAGGING);
} else if (this.temp.get('mode') === Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER && this.temp.get('selectedControllerDirection')) {
} else if (
this.temp.get('mode') === Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER &&
this.temp.get('selectedControllerDirection')
) {
this._transfromElement(
this.temp.get('selectedUUID') as string,
point,
this.temp.get('prevPoint'),
this.temp.get('selectedControllerDirection') as TypeHelperWrapperControllerDirection
this.temp.get(
'selectedControllerDirection'
) as TypeHelperWrapperControllerDirection
);
this.temp.set('cursorStatus', CursorStatus.DRAGGING)
this.temp.set('cursorStatus', CursorStatus.DRAGGING);
}
} else if (this.temp.get('mode') === Mode.SELECT_AREA) {
helper.changeSelectArea(point);
drawFeekback();
}
this.temp.set('prevPoint', point)
this.temp.set('prevPoint', point);
}
private _dragElements(uuids: string[], point: TypePoint, prevPoint: TypePoint|null): void {
private _dragElements(
uuids: string[],
point: TypePoint,
prevPoint: TypePoint | null
): void {
if (!prevPoint) {
return;
}
const {
board, element, getDataFeekback, drawFeekback
} = this._opts;
const { board, element, getDataFeekback, drawFeekback } = this._opts;
const data = getDataFeekback();
const helper = this.helper;
uuids.forEach((uuid) => {
const idx = helper.getElementIndexByUUID(uuid);
if (idx === null) return;
const elem = data.elements[idx];
if (elem?.operation?.lock !== true && elem?.operation?.invisible !== true) {
element.dragElement(data, uuid, point, prevPoint, board.getContext().getTransform().scale);
if (
elem?.operation?.lock !== true &&
elem?.operation?.invisible !== true
) {
element.dragElement(
data,
uuid,
point,
prevPoint,
board.getContext().getTransform().scale
);
}
});
drawFeekback();
}
private _transfromElement(
uuid: string, point: TypePoint, prevPoint: TypePoint|null, direction: TypeHelperWrapperControllerDirection
): null | { width: number, height: number, angle: number, } {
uuid: string,
point: TypePoint,
prevPoint: TypePoint | null,
direction: TypeHelperWrapperControllerDirection
): null | { width: number; height: number; angle: number } {
if (!prevPoint) {
return null;
}
const {
board, element, getDataFeekback, drawFeekback
} = this._opts;
const { board, element, getDataFeekback, drawFeekback } = this._opts;
const data = getDataFeekback();
const result = element.transformElement(data, uuid, point, prevPoint, board.getContext().getTransform().scale, direction);
const result = element.transformElement(
data,
uuid,
point,
prevPoint,
board.getContext().getTransform().scale,
direction
);
drawFeekback();
return result;
}
private _handleMoveEnd(point: TypePoint): void {
const {
element, getDataFeekback, coreEvent, drawFeekback, emitChangeData
element,
getDataFeekback,
coreEvent,
drawFeekback,
emitChangeData
} = this._opts;
const data = getDataFeekback();
const helper = this.helper;
@ -296,7 +345,7 @@ export class Engine {
helper.clearSelectedArea();
drawFeekback();
}
if (this.temp.get('mode') !== Mode.SELECT_ELEMENT) {
this.temp.set('selectedUUID', null);
}
@ -306,11 +355,11 @@ export class Engine {
private _handleHover(point: TypePoint): void {
let isMouseOverElement: boolean = false;
const { board, getDataFeekback, coreEvent, } = this._opts;
const { board, getDataFeekback, coreEvent } = this._opts;
const data = getDataFeekback();
const helper = this.helper;
const mapper = this._mapper;
if (this.temp.get('mode') === Mode.SELECT_AREA) {
board.resetCursor();
} else if (this.temp.get('cursorStatus') === CursorStatus.NULL) {
@ -320,12 +369,17 @@ export class Engine {
const index: number | null = helper.getElementIndexByUUID(elementUUID);
if (index !== null && index >= 0) {
const elem = data.elements[index];
if (elem?.operation?.lock === true || elem?.operation?.invisible === true) {
if (
elem?.operation?.lock === true ||
elem?.operation?.invisible === true
) {
board.resetCursor();
return;
}
if (this.temp.get('hoverUUID') !== elem.uuid) {
const preIndex = helper.getElementIndexByUUID(this.temp.get('hoverUUID') || '');
const preIndex = helper.getElementIndexByUUID(
this.temp.get('hoverUUID') || ''
);
if (preIndex !== null && data.elements[preIndex]) {
coreEvent.trigger('mouseLeaveElement', {
uuid: this.temp.get('hoverUUID'),
@ -335,7 +389,11 @@ export class Engine {
}
}
if (elem) {
coreEvent.trigger('mouseOverElement', { uuid: elem.uuid, index, element: elem, });
coreEvent.trigger('mouseOverElement', {
uuid: elem.uuid,
index,
element: elem
});
this.temp.set('hoverUUID', elem.uuid);
isMouseOverElement = true;
}
@ -345,10 +403,16 @@ export class Engine {
if (isMouseOverElement !== true && this.temp.get('hoverUUID') !== null) {
const uuid = this.temp.get('hoverUUID');
const index: number | null = helper.getElementIndexByUUID(uuid || '');
if (index !== null) coreEvent.trigger('mouseLeaveElement', { uuid, index, element: data.elements[index] })
this.temp.set('hoverUUID', null);
if (index !== null)
coreEvent.trigger('mouseLeaveElement', {
uuid,
index,
element: data.elements[index]
});
this.temp.set('hoverUUID', null);
}
if (coreEvent.has('mouseOverScreen')) coreEvent.trigger('mouseOverScreen', point);
if (coreEvent.has('mouseOverScreen'))
coreEvent.trigger('mouseOverScreen', point);
}
private _handleLeave(): void {
@ -357,8 +421,4 @@ export class Engine {
coreEvent.trigger('mouseLeaveScreen', undefined);
}
}
}
}

View file

@ -1,10 +1,17 @@
import {
TypeData, TypeHelper, TypeHelperConfig, TypeHelperUpdateOpts,
TypeHelperWrapperControllerDirection, TypeElement,
TypeElemDesc, TypeContext, TypePoint, TypeConfigStrict,
TypeData,
TypeHelper,
TypeHelperConfig,
TypeHelperUpdateOpts,
TypeHelperWrapperControllerDirection,
TypeElement,
TypeElemDesc,
TypeContext,
TypePoint,
TypeConfigStrict,
TypeHeplerSelectedElementWrapper
} from '@idraw/types';
import { Board } from '@idraw/board';
import Board from '@idraw/board';
import { deepClone } from '@idraw/util';
import { parseAngleToRadian, calcElementCenter } from './calculate';
import { rotateContext, rotateElement } from './transform';
@ -12,9 +19,7 @@ import { LIMIT_QBLIQUE_ANGLE } from './../constant/element';
const limitQbliqueAngle = LIMIT_QBLIQUE_ANGLE;
export class Helper implements TypeHelper {
private _helperConfig: TypeHelperConfig;
private _coreConfig: TypeConfigStrict;
private _ctx: TypeContext;
@ -31,10 +36,7 @@ export class Helper implements TypeHelper {
};
}
updateConfig (
data: TypeData,
opts: TypeHelperUpdateOpts
): void {
updateConfig(data: TypeData, opts: TypeHelperUpdateOpts): void {
this._updateElementIndex(data);
this._updateSelectedElementWrapper(data, opts);
this._updateSelectedElementListWrapper(data, opts);
@ -52,20 +54,29 @@ export class Helper implements TypeHelper {
return null;
}
isPointInElementWrapperController(p: TypePoint, data?: TypeData):
{
uuid: string | null | undefined,
selectedControllerDirection: TypeHelperWrapperControllerDirection | null,
hoverControllerDirection: TypeHelperWrapperControllerDirection | null,
directIndex: number | null,
isPointInElementWrapperController(
p: TypePoint,
data?: TypeData
): {
uuid: string | null | undefined;
selectedControllerDirection: TypeHelperWrapperControllerDirection | null;
hoverControllerDirection: TypeHelperWrapperControllerDirection | null;
directIndex: number | null;
} {
const ctx = this._ctx;
const uuid = this._helperConfig?.selectedElementWrapper?.uuid || null;
let directIndex = null;
let selectedControllerDirection: TypeHelperWrapperControllerDirection | null = null;
let hoverControllerDirection: TypeHelperWrapperControllerDirection | null = null;
let selectedControllerDirection: TypeHelperWrapperControllerDirection | null =
null;
let hoverControllerDirection: TypeHelperWrapperControllerDirection | null =
null;
if (!this._helperConfig.selectedElementWrapper) {
return {uuid, selectedControllerDirection, directIndex, hoverControllerDirection};
return {
uuid,
selectedControllerDirection,
directIndex,
hoverControllerDirection
};
}
const wrapper = this._helperConfig.selectedElementWrapper;
const controllers = [
@ -76,17 +87,17 @@ export class Helper implements TypeHelper {
wrapper.controllers.left,
wrapper.controllers.bottomLeft,
wrapper.controllers.bottom,
wrapper.controllers.bottomRight,
wrapper.controllers.bottomRight
];
let directionNames: TypeHelperWrapperControllerDirection[] = [
'right',
'top-right',
'top',
'top-left',
'left',
'left',
'bottom-left',
'bottom',
'bottom-right',
'bottom-right'
];
let hoverDirectionNames = deepClone(directionNames);
@ -100,35 +111,43 @@ export class Helper implements TypeHelper {
angle += 360;
}
if (angle < 45) {
angleMoveNum = 0
angleMoveNum = 0;
} else if (angle < 90) {
angleMoveNum = 1
angleMoveNum = 1;
} else if (angle < 135) {
angleMoveNum = 2
angleMoveNum = 2;
} else if (angle < 180) {
angleMoveNum = 3
angleMoveNum = 3;
} else if (angle < 225) {
angleMoveNum = 4
angleMoveNum = 4;
} else if (angle < 270) {
angleMoveNum = 5
angleMoveNum = 5;
} else if (angle < 315) {
angleMoveNum = 6
angleMoveNum = 6;
}
}
}
if (angleMoveNum > 0) {
hoverDirectionNames = hoverDirectionNames.slice(-angleMoveNum).concat(hoverDirectionNames.slice(0, -angleMoveNum))
hoverDirectionNames = hoverDirectionNames
.slice(-angleMoveNum)
.concat(hoverDirectionNames.slice(0, -angleMoveNum));
}
rotateContext(ctx, wrapper.translate, wrapper.radian || 0, () => {
for (let i = 0; i < controllers.length; i ++) {
for (let i = 0; i < controllers.length; i++) {
const controller = controllers[i];
if (controller.invisible === true) {
continue;
}
ctx.beginPath();
ctx.arc(controller.x, controller.y, wrapper.controllerSize, 0, Math.PI * 2);
ctx.arc(
controller.x,
controller.y,
wrapper.controllerSize,
0,
Math.PI * 2
);
ctx.closePath();
if (ctx.isPointInPath(p.x, p.y)) {
selectedControllerDirection = directionNames[i];
@ -146,17 +165,28 @@ export class Helper implements TypeHelper {
if (controller.invisible !== true) {
rotateContext(ctx, wrapper.translate, wrapper.radian || 0, () => {
ctx.beginPath();
ctx.arc(controller.x, controller.y, wrapper.controllerSize, 0, Math.PI * 2);
ctx.arc(
controller.x,
controller.y,
wrapper.controllerSize,
0,
Math.PI * 2
);
ctx.closePath();
if (ctx.isPointInPath(p.x, p.y)) {
selectedControllerDirection = 'rotate';
hoverControllerDirection = 'rotate';
hoverControllerDirection = 'rotate';
}
});
}
}
return {uuid, selectedControllerDirection, hoverControllerDirection, directIndex};
return {
uuid,
selectedControllerDirection,
hoverControllerDirection,
directIndex
};
}
isPointInElementList(p: TypePoint, data: TypeData): boolean {
@ -211,8 +241,8 @@ export class Helper implements TypeHelper {
}
clearSelectedArea() {
this._areaStart = {x: 0, y: 0};
this._areaEnd = {x: 0, y: 0};
this._areaStart = { x: 0, y: 0 };
this._areaEnd = { x: 0, y: 0 };
this._calcSelectedArea();
}
@ -256,19 +286,18 @@ export class Helper implements TypeHelper {
const { scale = 1, scrollX = 0, scrollY = 0 } = transform;
const elemWrapper = this._coreConfig.elementWrapper;
const lineWidth = elemWrapper.lineWidth / scale;
const lineDash = elemWrapper.lineDash.map(n => (n / scale));
const lineDash = elemWrapper.lineDash.map((n) => n / scale);
this._helperConfig.selectedAreaWrapper = {
x: (Math.min(start.x, end.x) - scrollX) / scale,
y: (Math.min(start.y, end.y) - scrollY) / scale,
w: Math.abs(end.x - start.x) / scale,
h: Math.abs(end.y - start.y) / scale,
startPoint: {x: start.x, y: start.y},
endPoint: {x: end.x, y: end.y},
startPoint: { x: start.x, y: start.y },
endPoint: { x: end.x, y: end.y },
lineWidth: lineWidth,
lineDash: lineDash,
color: elemWrapper.color,
color: elemWrapper.color
};
}
@ -279,9 +308,17 @@ export class Helper implements TypeHelper {
});
}
private _updateSelectedElementWrapper(data: TypeData, opts: TypeHelperUpdateOpts) {
private _updateSelectedElementWrapper(
data: TypeData,
opts: TypeHelperUpdateOpts
) {
const { selectedUUID: uuid } = opts;
if (!(typeof uuid === 'string' && this._helperConfig.elementIndexMap[uuid] >= 0)) {
if (
!(
typeof uuid === 'string' &&
this._helperConfig.elementIndexMap[uuid] >= 0
)
) {
delete this._helperConfig.selectedElementWrapper;
return;
}
@ -294,7 +331,10 @@ export class Helper implements TypeHelper {
this._helperConfig.selectedElementWrapper = wrapper;
}
private _updateSelectedElementListWrapper(data: TypeData, opts: TypeHelperUpdateOpts) {
private _updateSelectedElementListWrapper(
data: TypeData,
opts: TypeHelperUpdateOpts
) {
const { selectedUUIDList } = opts;
const wrapperList: TypeHeplerSelectedElementWrapper[] = [];
data.elements.forEach((elem, i) => {
@ -314,19 +354,22 @@ export class Helper implements TypeHelper {
const elemWrapper = this._coreConfig.elementWrapper;
const controllerSize = elemWrapper.controllerSize / scale;
const lineWidth = elemWrapper.lineWidth / scale;
const lineDash = elemWrapper.lineDash.map(n => (n / scale));
const lineDash = elemWrapper.lineDash.map((n) => n / scale);
const rotateLimit = 12;
// @ts-ignore
const bw = elem.desc?.borderWidth || 0;
const bw = elem.desc?.borderWidth || 0;
let hideObliqueDirection = false;
if (typeof elem.angle === 'number' && Math.abs(elem.angle) > limitQbliqueAngle) {
if (
typeof elem.angle === 'number' &&
Math.abs(elem.angle) > limitQbliqueAngle
) {
hideObliqueDirection = true;
}
// TODO
// const controllerOffset = controllerSize;
const controllerOffset = lineWidth;
const wrapper: TypeHeplerSelectedElementWrapper = {
uuid: elem.uuid,
controllerSize: controllerSize,
@ -336,17 +379,19 @@ export class Helper implements TypeHelper {
topLeft: {
x: elem.x - controllerOffset - bw,
y: elem.y - controllerOffset - bw,
invisible: hideObliqueDirection || elem?.operation?.disableScale === true,
invisible:
hideObliqueDirection || elem?.operation?.disableScale === true
},
top: {
x: elem.x + elem.w / 2,
y: elem.y - controllerOffset - bw,
invisible: elem?.operation?.disableScale === true,
invisible: elem?.operation?.disableScale === true
},
topRight: {
x: elem.x + elem.w + controllerOffset + bw,
y: elem.y - controllerOffset - bw,
invisible: hideObliqueDirection || elem?.operation?.disableScale === true,
invisible:
hideObliqueDirection || elem?.operation?.disableScale === true
},
right: {
x: elem.x + elem.w + controllerOffset + bw,
@ -356,17 +401,19 @@ export class Helper implements TypeHelper {
bottomRight: {
x: elem.x + elem.w + controllerOffset + bw,
y: elem.y + elem.h + controllerOffset + bw,
invisible: hideObliqueDirection || elem?.operation?.disableScale === true,
invisible:
hideObliqueDirection || elem?.operation?.disableScale === true
},
bottom: {
x: elem.x + elem.w / 2,
y: elem.y + elem.h + controllerOffset + bw,
invisible: elem?.operation?.disableScale === true,
invisible: elem?.operation?.disableScale === true
},
bottomLeft: {
x: elem.x - controllerOffset - bw,
y: elem.y + elem.h + controllerOffset + bw,
invisible: hideObliqueDirection || elem?.operation?.disableScale === true,
invisible:
hideObliqueDirection || elem?.operation?.disableScale === true
},
left: {
x: elem.x - controllerOffset - bw,
@ -381,7 +428,10 @@ export class Helper implements TypeHelper {
},
lineWidth: lineWidth,
lineDash: lineDash,
color: elem?.operation?.lock === true ? elemWrapper.lockColor : elemWrapper.color,
color:
elem?.operation?.lock === true
? elemWrapper.lockColor
: elemWrapper.color
};
if (typeof elem.angle === 'number' && (elem.angle > 0 || elem.angle < 0)) {
@ -391,5 +441,4 @@ export class Helper implements TypeHelper {
return wrapper;
}
}
}

View file

@ -1,5 +1,5 @@
import { TypeData, TypePoint, TypePointCursor } from '@idraw/types';
import { Board } from '@idraw/board';
import Board from '@idraw/board';
import { Helper } from './helper';
import { Element } from './element';
@ -11,11 +11,10 @@ const _opts = Symbol('_opts');
type Options = {
board: Board;
element: Element;
helper: Helper
}
helper: Helper;
};
export class Mapper {
private [_opts]: Options;
private [_board]: Board;
private [_helper]: Helper;
@ -31,60 +30,68 @@ export class Mapper {
isEffectivePoint(p: TypePoint): boolean {
const scrollLineWidth = this[_board].getScrollLineWidth();
const screenInfo = this[_board].getScreenInfo();
if (p.x <= (screenInfo.width - scrollLineWidth) && p.y <= (screenInfo.height - scrollLineWidth)) {
if (
p.x <= screenInfo.width - scrollLineWidth &&
p.y <= screenInfo.height - scrollLineWidth
) {
return true;
}
return false;
}
judgePointCursor(p: TypePoint, data: TypeData): {
cursor: TypePointCursor,
elementUUID: string | null,
judgePointCursor(
p: TypePoint,
data: TypeData
): {
cursor: TypePointCursor;
elementUUID: string | null;
} {
let cursor: TypePointCursor = 'auto';
let elementUUID: string | null = null;
if (!this.isEffectivePoint(p)) {
return { cursor, elementUUID};
return { cursor, elementUUID };
}
const { uuid, hoverControllerDirection } = this[_helper].isPointInElementWrapperController(p, data);
const { uuid, hoverControllerDirection } = this[
_helper
].isPointInElementWrapperController(p, data);
const direction = hoverControllerDirection;
if (uuid && direction) {
switch (direction) {
case 'top-right' : {
case 'top-right': {
cursor = 'ne-resize';
break;
}
case 'top-left' : {
case 'top-left': {
cursor = 'nw-resize';
break;
}
case 'top' : {
case 'top': {
cursor = 'n-resize';
break;
}
case 'right' : {
case 'right': {
cursor = 'e-resize';
break;
}
case 'bottom-right' : {
case 'bottom-right': {
cursor = 'se-resize';
break;
}
case 'bottom' : {
case 'bottom': {
cursor = 's-resize';
break;
}
case 'bottom-left' : {
case 'bottom-left': {
cursor = 'sw-resize';
break;
}
case 'left' : {
case 'left': {
cursor = 'w-resize';
break;
}
case 'rotate' : {
case 'rotate': {
cursor = 'grab';
break;
}
@ -106,8 +113,7 @@ export class Mapper {
}
return {
cursor,
elementUUID,
elementUUID
};
}
}

View file

@ -1,18 +1,26 @@
import {
TypeElement, TypeElemDesc, TypeElementBase,
} from '@idraw/types';
import { TypeElement, TypeElemDesc, TypeElementBase } from '@idraw/types';
import { deepClone, createUUID } from '@idraw/util';
import {
_board, _data, _opts, _config, _renderer, _element, _engine,
_tempData, _draw, _coreEvent, _emitChangeScreen, _emitChangeData,
_board,
_data,
_opts,
_config,
_renderer,
_element,
_engine,
_tempData,
_draw,
_coreEvent,
_emitChangeScreen,
_emitChangeData
} from './../names';
import { diffElementResourceChange } from './../lib/diff';
import { Core } from './../index';
import Core from './../index';
import { Mode } from './../constant/static';
export function getSelectedElements(core: Core): TypeElement<keyof TypeElemDesc>[] {
export function getSelectedElements(
core: Core
): TypeElement<keyof TypeElemDesc>[] {
const elems: TypeElement<keyof TypeElemDesc>[] = [];
let list: string[] = [];
const uuid = core[_engine].temp.get('selectedUUID');
@ -31,8 +39,11 @@ export function getSelectedElements(core: Core): TypeElement<keyof TypeElemDesc>
return deepClone(elems);
}
export function getElement(core: Core, uuid: string): TypeElement<keyof TypeElemDesc>|null {
let elem: TypeElement<keyof TypeElemDesc>|null = null;
export function getElement(
core: Core,
uuid: string
): TypeElement<keyof TypeElemDesc> | null {
let elem: TypeElement<keyof TypeElemDesc> | null = null;
const index = core[_engine].helper.getElementIndexByUUID(uuid);
if (index !== null && core[_data].elements[index]) {
elem = deepClone(core[_data].elements[index]);
@ -40,16 +51,22 @@ export function getElement(core: Core, uuid: string): TypeElement<keyof TypeElem
return elem;
}
export function getElementByIndex(core: Core, index: number): TypeElement<keyof TypeElemDesc>|null {
let elem: TypeElement<keyof TypeElemDesc>|null = null;
if (index >=0 && core[_data].elements[index]) {
export function getElementByIndex(
core: Core,
index: number
): TypeElement<keyof TypeElemDesc> | null {
let elem: TypeElement<keyof TypeElemDesc> | null = null;
if (index >= 0 && core[_data].elements[index]) {
elem = deepClone(core[_data].elements[index]);
}
return elem;
}
export function updateElement(core: Core, elem: TypeElement<keyof TypeElemDesc>) {
const _elem = deepClone(elem) as TypeElement<keyof TypeElemDesc>;
export function updateElement(
core: Core,
elem: TypeElement<keyof TypeElemDesc>
) {
const _elem = deepClone(elem) as TypeElement<keyof TypeElemDesc>;
const data = core[_data];
const resourceChangeUUIDs: string[] = [];
for (let i = 0; i < data.elements.length; i++) {
@ -66,7 +83,11 @@ export function updateElement(core: Core, elem: TypeElement<keyof TypeElemDesc>)
core[_draw]({ resourceChangeUUIDs });
}
export function selectElementByIndex(core: Core, index: number, opts?: { useMode?: boolean }): void {
export function selectElementByIndex(
core: Core,
index: number,
opts?: { useMode?: boolean }
): void {
if (core[_data].elements[index]) {
const uuid = core[_data].elements[index].uuid;
if (opts?.useMode === true) {
@ -82,8 +103,11 @@ export function selectElementByIndex(core: Core, index: number, opts?: { useMode
}
}
export function selectElement(core: Core, uuid: string, opts?: { useMode?: boolean }): void {
export function selectElement(
core: Core,
uuid: string,
opts?: { useMode?: boolean }
): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
if (typeof index === 'number' && index >= 0) {
core.selectElementByIndex(index, opts);
@ -92,7 +116,11 @@ export function selectElement(core: Core, uuid: string, opts?: { useMode?: boole
export function moveUpElement(core: Core, uuid: string): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
if (typeof index === 'number' && index >= 0 && index < core[_data].elements.length - 1) {
if (
typeof index === 'number' &&
index >= 0 &&
index < core[_data].elements.length - 1
) {
const temp = core[_data].elements[index];
core[_data].elements[index] = core[_data].elements[index + 1];
core[_data].elements[index + 1] = temp;
@ -103,7 +131,11 @@ export function moveUpElement(core: Core, uuid: string): void {
export function moveDownElement(core: Core, uuid: string): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
if (typeof index === 'number' && index > 0 && index < core[_data].elements.length) {
if (
typeof index === 'number' &&
index > 0 &&
index < core[_data].elements.length
) {
const temp = core[_data].elements[index];
core[_data].elements[index] = core[_data].elements[index - 1];
core[_data].elements[index - 1] = temp;
@ -112,8 +144,10 @@ export function moveDownElement(core: Core, uuid: string): void {
core[_draw]();
}
export function addElement(core: Core, elem: TypeElementBase<keyof TypeElemDesc>): string | null {
export function addElement(
core: Core,
elem: TypeElementBase<keyof TypeElemDesc>
): string | null {
const _elem = deepClone(elem);
_elem.uuid = createUUID();
core[_data].elements.push(_elem);
@ -131,7 +165,11 @@ export function deleteElement(core: Core, uuid: string) {
}
}
export function insertElementBefore(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, beforeUUID: string) {
export function insertElementBefore(
core: Core,
elem: TypeElementBase<keyof TypeElemDesc>,
beforeUUID: string
) {
const index = core[_engine].helper.getElementIndexByUUID(beforeUUID);
if (index !== null) {
return core.insertElementBeforeIndex(elem, index);
@ -139,8 +177,11 @@ export function insertElementBefore(core: Core, elem: TypeElementBase<keyof Type
return null;
}
export function insertElementBeforeIndex(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, index: number) {
export function insertElementBeforeIndex(
core: Core,
elem: TypeElementBase<keyof TypeElemDesc>,
index: number
) {
const _elem = deepClone(elem);
_elem.uuid = createUUID();
if (index >= 0) {
@ -152,8 +193,11 @@ export function insertElementBeforeIndex(core: Core, elem: TypeElementBase<keyof
return null;
}
export function insertElementAfter(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, beforeUUID: string) {
export function insertElementAfter(
core: Core,
elem: TypeElementBase<keyof TypeElemDesc>,
beforeUUID: string
) {
const index = core[_engine].helper.getElementIndexByUUID(beforeUUID);
if (index !== null) {
return core.insertElementAfterIndex(elem, index);
@ -161,7 +205,11 @@ export function insertElementAfter(core: Core, elem: TypeElementBase<keyof TypeE
return null;
}
export function insertElementAfterIndex(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, index: number) {
export function insertElementAfterIndex(
core: Core,
elem: TypeElementBase<keyof TypeElemDesc>,
index: number
) {
const _elem = deepClone(elem);
_elem.uuid = createUUID();
if (index >= 0) {
@ -171,4 +219,4 @@ export function insertElementAfterIndex(core: Core, elem: TypeElementBase<keyof
return _elem.uuid;
}
return null;
}
}

View file

@ -32,6 +32,6 @@
</div>
<div id="preview"></div>
<script type="module" src="./main.js"></script>
<script type="module" src="./main.ts"></script>
</body>
</html>

View file

@ -1,45 +0,0 @@
import iDraw from './../src/index';
import { getData } from './data.js';
var opts = {
width: 300,
height: 200,
contextWidth: 300,
contextHeight: 200,
devicePixelRatio: 4,
};
// var config = {
// elementWrapper: {
// controllerSize: 4,
// }
// }
const mount = document.querySelector('#mount');
const data = getData();
const idraw = new iDraw(
mount,
Object.assign({}, opts, {
contextWidth: 500,
contextHeight: 400,
}),
{
scrollWrapper: {
use: true,
},
}
);
idraw.setData(data);
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
idraw.exportDataURL({type: "image/png"}).then((dataURL) => {
const preview = document.querySelector('#preview');
preview.innerHTML = `<img width="300" src="${dataURL}">`;
}).catch((err) => {
console.log(err);
});
});

View file

@ -0,0 +1,45 @@
import iDraw from '../src/index';
import { getData } from './data';
var opts = {
width: 600,
height: 400,
contextWidth: 600,
contextHeight: 400,
devicePixelRatio: 4
};
// var config = {
// elementWrapper: {
// controllerSize: 4,
// }
// }
const mount = document.querySelector('#mount') as HTMLDivElement;
const data = getData();
const idraw = new iDraw(
mount,
Object.assign({}, opts, {
contextWidth: 500,
contextHeight: 400
}),
{
scrollWrapper: {
use: true
}
}
);
idraw.setData(data);
const btn = document.querySelector('#btn') as HTMLButtonElement;
btn.addEventListener('click', () => {
idraw
.exportDataURL({ type: 'image/png' })
.then((dataURL) => {
const preview = document.querySelector('#preview');
preview.innerHTML = `<img width="300" src="${dataURL}">`;
})
.catch((err) => {
console.log(err);
});
});

View file

@ -0,0 +1,15 @@
const elementTypes = {
'text': {}, // TODO
'rect': {}, // TODO
'image': {}, // TODO
'svg': {}, // TODO
'circle': {}, // TODO
'html': {}, // TODO
};
export const elementNames = Object.keys(elementTypes);
// limitQbliqueAngle
export const LIMIT_QBLIQUE_ANGLE = 15;

View file

@ -0,0 +1,12 @@
export enum Mode {
NULL = 'null',
SELECT_ELEMENT = 'select-element',
SELECT_ELEMENT_LIST = 'select-element-list',
SELECT_ELEMENT_WRAPPER_CONTROLLER = 'select-element-wrapper-controller',
SELECT_AREA = 'select-area',
}
export enum CursorStatus {
DRAGGING = 'dragging',
NULL = 'null',
}

View file

@ -3,7 +3,7 @@ import { elementNames } from './../constant/element';
export function parseData(data: any): TypeData {
const result: TypeData = {
elements: [],
elements: []
};
if (Array.isArray(data?.elements)) {
data?.elements.forEach((elem: any = {}) => {
@ -13,24 +13,28 @@ export function parseData(data: any): TypeData {
});
}
if (typeof data.bgColor === 'string') {
result.bgColor = data.bgColor;
result.bgColor = data.bgColor;
}
return result;
}
function isElement(
elem: TypeElement<keyof TypeElemDesc>
): boolean{
if (!(isNumber(elem.x) && isNumber(elem.y) && isNumber(elem.w) && isNumber(elem.h))) {
function isElement(elem: TypeElement<keyof TypeElemDesc>): boolean {
if (
!(
isNumber(elem.x) &&
isNumber(elem.y) &&
isNumber(elem.w) &&
isNumber(elem.h)
)
) {
return false;
}
if (!(typeof elem.type === 'string' && elementNames.includes(elem.type))) {
return false;
}
return true;
}
}
function isNumber(num: any) {
return (num >= 0 || num < 0);
}
return num >= 0 || num < 0;
}

View file

@ -7,8 +7,11 @@ importers:
'@babel/core': ^7.20.7
'@babel/preset-env': ^7.20.2
'@babel/preset-typescript': ^7.18.6
'@types/glob': ^8.0.1
'@types/jest': ^29.2.5
'@types/koa-compose': ^3.2.5
'@types/node': ^18.11.18
'@types/serve-handler': ^6.1.1
'@typescript-eslint/eslint-plugin': ^5.47.1
'@typescript-eslint/parser': ^5.47.1
babel-jest: ^29.3.1
@ -41,8 +44,11 @@ importers:
'@babel/core': 7.20.7
'@babel/preset-env': 7.20.2_@babel+core@7.20.7
'@babel/preset-typescript': 7.18.6_@babel+core@7.20.7
'@types/glob': 8.0.1
'@types/jest': 29.2.5
'@types/koa-compose': 3.2.5
'@types/node': 18.11.18
'@types/serve-handler': 6.1.1
'@typescript-eslint/eslint-plugin': 5.47.1_axni7f4fgvh6tlufnh6hwgsifq
'@typescript-eslint/parser': 5.47.1_iukboom6ndih5an6iafl45j2fe
babel-jest: 29.3.1_@babel+core@7.20.7
@ -3371,6 +3377,12 @@ packages:
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
dev: true
/@types/accepts/1.3.5:
resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==}
dependencies:
'@types/node': 18.11.18
dev: true
/@types/babel__core/7.1.20:
resolution: {integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==}
dependencies:
@ -3400,12 +3412,70 @@ packages:
'@babel/types': 7.20.7
dev: true
/@types/body-parser/1.19.2:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies:
'@types/connect': 3.4.35
'@types/node': 18.11.18
dev: true
/@types/connect/3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies:
'@types/node': 18.11.18
dev: true
/@types/content-disposition/0.5.5:
resolution: {integrity: sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==}
dev: true
/@types/cookies/0.7.7:
resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==}
dependencies:
'@types/connect': 3.4.35
'@types/express': 4.17.17
'@types/keygrip': 1.0.2
'@types/node': 18.11.18
dev: true
/@types/express-serve-static-core/4.17.33:
resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==}
dependencies:
'@types/node': 18.11.18
'@types/qs': 6.9.7
'@types/range-parser': 1.2.4
dev: true
/@types/express/4.17.17:
resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==}
dependencies:
'@types/body-parser': 1.19.2
'@types/express-serve-static-core': 4.17.33
'@types/qs': 6.9.7
'@types/serve-static': 1.15.0
dev: true
/@types/glob/8.0.1:
resolution: {integrity: sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==}
dependencies:
'@types/minimatch': 5.1.2
'@types/node': 18.11.18
dev: true
/@types/graceful-fs/4.1.5:
resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
dependencies:
'@types/node': 18.11.18
dev: true
/@types/http-assert/1.5.3:
resolution: {integrity: sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==}
dev: true
/@types/http-errors/2.0.1:
resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==}
dev: true
/@types/istanbul-lib-coverage/2.0.4:
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
dev: true
@ -3437,10 +3507,41 @@ packages:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: true
/@types/keygrip/1.0.2:
resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==}
dev: true
/@types/koa-compose/3.2.5:
resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==}
dependencies:
'@types/koa': 2.13.5
dev: true
/@types/koa/2.13.5:
resolution: {integrity: sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==}
dependencies:
'@types/accepts': 1.3.5
'@types/content-disposition': 0.5.5
'@types/cookies': 0.7.7
'@types/http-assert': 1.5.3
'@types/http-errors': 2.0.1
'@types/keygrip': 1.0.2
'@types/koa-compose': 3.2.5
'@types/node': 18.11.18
dev: true
/@types/mime/3.0.1:
resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}
dev: true
/@types/minimatch/3.0.5:
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
dev: true
/@types/minimatch/5.1.2:
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
dev: true
/@types/minimist/1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
dev: true
@ -3465,10 +3566,31 @@ packages:
resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==}
dev: true
/@types/qs/6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
dev: true
/@types/range-parser/1.2.4:
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
dev: true
/@types/semver/7.3.13:
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
dev: true
/@types/serve-handler/6.1.1:
resolution: {integrity: sha512-bIwSmD+OV8w0t2e7EWsuQYlGoS1o5aEdVktgkXaa43Zm0qVWi21xaSRb3DQA1UXD+DJ5bRq1Rgu14ZczB+CjIQ==}
dependencies:
'@types/node': 18.11.18
dev: true
/@types/serve-static/1.15.0:
resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==}
dependencies:
'@types/mime': 3.0.1
'@types/node': 18.11.18
dev: true
/@types/stack-utils/2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: true

View file

@ -1,9 +1,10 @@
import ts from 'typescript';
import path from 'path';
import fs from 'fs-extra';
import glob from 'glob';
import { packages } from './config';
import { joinPackagePath, getTsConfig } from './util/project';
import { removeFullDir } from './util/file';
import type { CompilerOptions } from 'typescript';
build();
@ -14,13 +15,13 @@ async function build() {
const pkgDir = path.resolve(`packages/${dirName}`);
console.log(`Start to build ESM for ${dirName}`);
console.log(`Remove packages/${dirName}/dist/`);
await fs.remove(`${pkgDir}/dist`);
removeFullDir(`${pkgDir}/dist`);
buildPackage(dirName);
console.log(`Build ESM of ${dirName} successfully!`);
}
}
function buildPackage(dirName) {
function buildPackage(dirName: string) {
const pattern = '**/*.ts';
const cwd = joinPackagePath(dirName, 'src');
const files = glob.sync(pattern, { cwd });
@ -31,14 +32,37 @@ function buildPackage(dirName) {
// build ts -> esm
{
const tsConfig = getTsConfig();
const compilerOptions = tsConfig.compilerOptions;
compilerOptions.target = ts.ScriptTarget.ES2015;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.NodeJs;
compilerOptions.declaration = true;
compilerOptions.outDir = joinPackagePath(dirName, 'dist', 'esm');
compilerOptions.rootDir = joinPackagePath(dirName, 'src');
// const tsConfig = getTsConfig();
// const compilerOptions = tsConfig.compilerOptions;
const compilerOptions: CompilerOptions = {
noUnusedLocals: true,
declaration: true,
sourceMap: false,
target: ts.ScriptTarget.ES2015,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
allowJs: false,
strict: true,
experimentalDecorators: true,
resolveJsonModule: true,
esModuleInterop: true,
removeComments: true,
// lib: ['ES2016', 'dom'],
outDir: joinPackagePath(dirName, 'dist', 'esm'),
rootDir: joinPackagePath(dirName, 'src'),
skipLibCheck: true
};
const program = ts.createProgram(targetFiles, compilerOptions);
const diagnostics = ts.getPreEmitDiagnostics(program);
if (diagnostics.length) {
// console.error(diagnostics);
for (const diagnostic of diagnostics) {
console.log(JSON.stringify(diagnostic.messageText, null, 2));
}
throw Error('TS build error!');
}
program.emit();
}
}

View file

@ -1,26 +1,10 @@
import fs from 'fs';
import path from 'path';
// import path from 'path';
function removeFullDir(dirPath) {
let files: string[] = [];
if (fs.existsSync(dirPath)) {
files = fs.readdirSync(dirPath);
files.forEach((filename) => {
const curPath: string = path.join(dirPath, filename);
const stat = fs.statSync(curPath);
if (stat.isDirectory()) {
removeFullDir(curPath);
} else if (stat.isFile()) {
// fs.unlinkSync(curPath);
fs.rmSync(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(dirPath);
function removeFullDir(dirPath: string) {
if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
fs.rmSync(dirPath, { recursive: true });
}
}
module.exports = {
removeFullDir
};
export { removeFullDir };

View file

@ -14,7 +14,7 @@ export function joinProjectPath(...args: string[]) {
}
export function getTsConfig() {
const configPath = joinProjectPath('tsconfig.json');
const configPath = joinProjectPath('tsconfig.web.json');
const configStr = fs.readFileSync(configPath, { encoding: 'utf8' });
const config = JSON.parse(configStr);
return config;

View file

@ -16,7 +16,7 @@ module.exports = {
height
};
async function createScreenshotBuffer(pagePath) {
async function createScreenshotBuffer(pagePath: string) {
const middlewares = [];
let buf;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@ -35,7 +35,10 @@ async function createScreenshotBuffer(pagePath) {
return buf;
}
async function createScreenshot(middlewares, opts: any = {}): Promise<void> {
async function createScreenshot(
middlewares: any[],
opts: any = {}
): Promise<void> {
return new Promise((resolve) => {
const server = http.createServer((req, res) =>
serveHandler(req, res, {

View file

@ -1,26 +1,11 @@
{
"compilerOptions": {
"declaration": true,
"sourceMap": false,
"target": "es5",
"module": "ES2015",
"moduleResolution": "node",
"allowJs": false,
"strict": true,
"noUnusedLocals": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"removeComments": true,
"lib": ["ESNext", "dom"]
},
"include": [
"packages/global.d.ts",
"packages/*/src",
"packages/*/__tests__",
"packages/*/dev"
],
"exclude": [
"packages/*/examples"
"files": [],
"references": [
{
"path": "./tsconfig.web.json"
},
{
"path": "./tsconfig.node.json"
}
]
}

22
tsconfig.node.json Normal file
View file

@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "ES6",
"lib": ["ES6", "DOM"],
"moduleResolution": "Node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"importHelpers": true,
"allowJs": true,
"composite": true
},
"include": [
"scripts/",
],
"exclude": [
"node_modules"
]
}

24
tsconfig.web.json Normal file
View file

@ -0,0 +1,24 @@
{
"compilerOptions": {
"declaration": true,
"sourceMap": false,
"target": "ES6",
"module": "ES2015",
"moduleResolution": "node",
"allowJs": false,
"strict": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"removeComments": true,
"lib": ["ES2016", "DOM"]
},
"include": [
"packages/*/src",
"packages/*/__tests__",
"packages/*/dev"
],
"exclude": [
"packages/*/examples"
]
}