refactor: cleanup Symbol private props

This commit is contained in:
chenshenhai 2023-04-01 18:43:45 +08:00
parent 4e38ec8661
commit e00e614b99
15 changed files with 398 additions and 514 deletions

View file

@ -18,119 +18,98 @@ import { Screen } from './lib/screen';
const { throttle, Context } = util;
import {
_canvas,
_displayCanvas,
_mount,
_opts,
_hasRendered,
_ctx,
_watcher,
_render,
_parsePrivateOptions,
_scroller,
_helperCanvas,
_helperCtx,
_initEvent,
_doScrollX,
_doScrollY,
_doMoveScroll,
_resetContext,
_screen
} from './names';
type PrivateOptions = BoardOptions & {
devicePixelRatio: number;
};
export default class Board {
private [_hasRendered] = false;
private _hasRendered = false;
private [_canvas]: HTMLCanvasElement;
private [_helperCanvas]: HTMLCanvasElement;
private [_displayCanvas]: HTMLCanvasElement;
private [_mount]: HTMLDivElement;
private [_opts]: PrivateOptions;
private [_ctx]: IDrawContext;
private [_helperCtx]: IDrawContext;
// private [_watcher]: Watcher;
private [_watcher]: ScreenWatcher;
private [_scroller]: Scroller;
private [_screen]: Screen;
// private [_tempData]: TempData;
private _canvas: HTMLCanvasElement;
private _helperCanvas: HTMLCanvasElement;
private _displayCanvas: HTMLCanvasElement;
private _mount: HTMLDivElement;
private _opts: PrivateOptions;
private _ctx: IDrawContext;
private _helperCtx: IDrawContext;
// private _watcher: Watcher;
private _watcher: ScreenWatcher;
private _scroller: Scroller;
private _screen: Screen;
// private _tempData: TempData;
constructor(mount: HTMLDivElement, opts: BoardOptions) {
// this[_tempData] = new TempData(opts);
// this._tempData = new TempData(opts);
this[_mount] = mount;
this[_canvas] = document.createElement('canvas');
this[_helperCanvas] = document.createElement('canvas');
this[_displayCanvas] = document.createElement('canvas');
this[_mount].appendChild(this[_displayCanvas]);
this[_opts] = this[_parsePrivateOptions](opts);
this._mount = mount;
this._canvas = document.createElement('canvas');
this._helperCanvas = document.createElement('canvas');
this._displayCanvas = document.createElement('canvas');
this._mount.appendChild(this._displayCanvas);
this._opts = this._parsePrivateOptions(opts);
const originCtx2d = this[_canvas].getContext(
const originCtx2d = this._canvas.getContext(
'2d'
) as CanvasRenderingContext2D;
const displayCtx2d = this[_displayCanvas].getContext(
const displayCtx2d = this._displayCanvas.getContext(
'2d'
) as CanvasRenderingContext2D;
const helperCtx2d = this[_helperCanvas].getContext(
const helperCtx2d = this._helperCanvas.getContext(
'2d'
) as CanvasRenderingContext2D;
this[_ctx] = new Context(originCtx2d, this[_opts]);
this[_helperCtx] = new Context(helperCtx2d, this[_opts]);
this[_screen] = new Screen(this[_ctx], this[_opts]);
// this[_watcher] = new Watcher(this[_displayCanvas]);
this[_watcher] = new ScreenWatcher(this[_displayCanvas], this[_ctx]);
this[_scroller] = new Scroller(displayCtx2d, {
this._ctx = new Context(originCtx2d, this._opts);
this._helperCtx = new Context(helperCtx2d, this._opts);
this._screen = new Screen(this._ctx, this._opts);
// this._watcher = new Watcher(this._displayCanvas);
this._watcher = new ScreenWatcher(this._displayCanvas, this._ctx);
this._scroller = new Scroller(displayCtx2d, {
width: opts.width,
height: opts.height,
devicePixelRatio: opts.devicePixelRatio || 1,
scrollConfig: opts.scrollConfig
});
this[_render]();
this._render();
}
getDisplayContext2D(): CanvasRenderingContext2D {
return this[_displayCanvas].getContext('2d') as CanvasRenderingContext2D;
return this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
}
getOriginContext2D(): CanvasRenderingContext2D {
return this[_ctx].getContext();
return this._ctx.getContext();
}
getHelperContext2D(): CanvasRenderingContext2D {
return this[_helperCtx].getContext();
return this._helperCtx.getContext();
}
getContext(): IDrawContext {
return this[_ctx];
return this._ctx;
}
getHelperContext(): IDrawContext {
return this[_helperCtx];
return this._helperCtx;
}
scale(scaleRatio: number): ScreenContext {
if (scaleRatio > 0) {
this[_ctx].setTransform({ scale: scaleRatio });
this[_helperCtx].setTransform({ scale: scaleRatio });
this._ctx.setTransform({ scale: scaleRatio });
this._helperCtx.setTransform({ scale: scaleRatio });
}
const { position, size } = this[_screen].calcScreen();
const { position, size } = this._screen.calcScreen();
return { position, size };
}
scrollX(x: number) {
this[_watcher].setStatusMap({
this._watcher.setStatusMap({
canScrollYPrev: true,
canScrollYNext: true,
canScrollXPrev: true,
canScrollXNext: true
});
if (x >= 0 || x < 0) {
this[_ctx].setTransform({ scrollX: x });
this[_helperCtx].setTransform({ scrollX: x });
this._ctx.setTransform({ scrollX: x });
this._helperCtx.setTransform({ scrollX: x });
}
const {
position,
@ -139,8 +118,8 @@ export default class Board {
canScrollYNext,
canScrollXPrev,
canScrollYPrev
} = this[_screen].calcScreen();
this[_watcher].setStatusMap({
} = this._screen.calcScreen();
this._watcher.setStatusMap({
canScrollYPrev,
canScrollYNext,
canScrollXPrev,
@ -150,15 +129,15 @@ export default class Board {
}
scrollY(y: number): ScreenContext {
this[_watcher].setStatusMap({
this._watcher.setStatusMap({
canScrollYPrev: true,
canScrollYNext: true,
canScrollXPrev: true,
canScrollXNext: true
});
if (y >= 0 || y < 0) {
this[_ctx].setTransform({ scrollY: y });
this[_helperCtx].setTransform({ scrollY: y });
this._ctx.setTransform({ scrollY: y });
this._helperCtx.setTransform({ scrollY: y });
}
const {
position,
@ -167,8 +146,8 @@ export default class Board {
canScrollYNext,
canScrollXPrev,
canScrollYPrev
} = this[_screen].calcScreen();
this[_watcher].setStatusMap({
} = this._screen.calcScreen();
this._watcher.setStatusMap({
canScrollYPrev,
canScrollYNext,
canScrollXPrev,
@ -178,40 +157,40 @@ export default class Board {
}
getTransform() {
return this[_ctx].getTransform();
return this._ctx.getTransform();
}
draw(): ScreenContext {
this.clear();
const { position, deviceSize, size } = this[_screen].calcScreen();
const displayCtx = this[_displayCanvas].getContext('2d');
const { position, deviceSize, size } = this._screen.calcScreen();
const displayCtx = this._displayCanvas.getContext('2d');
displayCtx?.drawImage(
this[_canvas],
this._canvas,
deviceSize.x,
deviceSize.y,
deviceSize.w,
deviceSize.h
);
displayCtx?.drawImage(
this[_helperCanvas],
this._helperCanvas,
deviceSize.x,
deviceSize.y,
deviceSize.w,
deviceSize.h
);
if (this[_opts].canScroll === true) {
this[_scroller].draw(position);
if (this._opts.canScroll === true) {
this._scroller.draw(position);
}
return { position, size };
}
clear() {
const displayCtx = this[_displayCanvas].getContext('2d');
const displayCtx = this._displayCanvas.getContext('2d');
displayCtx?.clearRect(
0,
0,
this[_displayCanvas].width,
this[_displayCanvas].height
this._displayCanvas.width,
this._displayCanvas.height
);
}
@ -219,14 +198,14 @@ export default class Board {
name: T,
callback: (p: TypeBoardEventArgMap[T]) => void
) {
this[_watcher].on(name, callback);
this._watcher.on(name, callback);
}
off<T extends keyof TypeBoardEventArgMap>(
name: T,
callback: (p: TypeBoardEventArgMap[T]) => void
) {
this[_watcher].off(name, callback);
this._watcher.off(name, callback);
}
getScreenInfo(): {
@ -238,35 +217,35 @@ export default class Board {
devicePixelRatio: number;
// eslint-disable-next-line indent
} {
return this[_screen].calcScreen();
return this._screen.calcScreen();
}
setCursor(cursor: PointCursor) {
this[_displayCanvas].style.cursor = cursor;
this._displayCanvas.style.cursor = cursor;
}
resetCursor() {
this[_displayCanvas].style.cursor = 'auto';
this._displayCanvas.style.cursor = 'auto';
}
resetSize(opts: BoardSizeOptions) {
this[_opts] = { ...this[_opts], ...opts };
this[_resetContext]();
this[_ctx].resetSize(opts);
this[_helperCtx].resetSize(opts);
this[_screen].resetSize(opts);
this[_scroller].resetSize({
width: this[_opts].width,
height: this[_opts].height,
devicePixelRatio: this[_opts].devicePixelRatio
this._opts = { ...this._opts, ...opts };
this._resetContext();
this._ctx.resetSize(opts);
this._helperCtx.resetSize(opts);
this._screen.resetSize(opts);
this._scroller.resetSize({
width: this._opts.width,
height: this._opts.height,
devicePixelRatio: this._opts.devicePixelRatio
});
this.draw();
}
getScrollLineWidth(): number {
let lineWidth = 0;
if (this[_opts].canScroll === true) {
lineWidth = this[_scroller].getLineWidth();
if (this._opts.canScroll === true) {
lineWidth = this._scroller.getLineWidth();
}
return lineWidth;
}
@ -289,55 +268,55 @@ export default class Board {
return screenPoint;
}
private [_render]() {
if (this[_hasRendered] === true) {
private _render() {
if (this._hasRendered === true) {
return;
}
this[_resetContext]();
this[_initEvent]();
this[_hasRendered] = true;
this._resetContext();
this._initEvent();
this._hasRendered = true;
}
private [_resetContext]() {
private _resetContext() {
const { width, height, contextWidth, contextHeight, devicePixelRatio } =
this[_opts];
this[_canvas].width = contextWidth * devicePixelRatio;
this[_canvas].height = contextHeight * devicePixelRatio;
this._opts;
this._canvas.width = contextWidth * devicePixelRatio;
this._canvas.height = contextHeight * devicePixelRatio;
this[_helperCanvas].width = contextWidth * devicePixelRatio;
this[_helperCanvas].height = contextHeight * devicePixelRatio;
this._helperCanvas.width = contextWidth * devicePixelRatio;
this._helperCanvas.height = contextHeight * devicePixelRatio;
this[_displayCanvas].width = width * devicePixelRatio;
this[_displayCanvas].height = height * devicePixelRatio;
this._displayCanvas.width = width * devicePixelRatio;
this._displayCanvas.height = height * devicePixelRatio;
setStyle(this[_displayCanvas], {
setStyle(this._displayCanvas, {
width: `${width}px`,
height: `${height}px`
});
}
private [_parsePrivateOptions](opts: BoardOptions): PrivateOptions {
private _parsePrivateOptions(opts: BoardOptions): PrivateOptions {
const defaultOpts = {
devicePixelRatio: 1
};
return { ...defaultOpts, ...opts };
}
private [_initEvent]() {
if (this[_hasRendered] === true) {
private _initEvent() {
if (this._hasRendered === true) {
return;
}
if (this[_opts].canScroll === true) {
if (this._opts.canScroll === true) {
this.on(
'wheelX',
throttle((deltaX) => {
this[_doScrollX](deltaX);
this._doScrollX(deltaX);
}, 16)
);
this.on(
'wheelY',
throttle((deltaY: number) => {
this[_doScrollY](deltaY);
this._doScrollY(deltaY);
}, 16)
);
@ -345,9 +324,9 @@ export default class Board {
this.on(
'moveStart',
throttle((p: Point) => {
if (this[_scroller].isPointAtScrollX(p)) {
if (this._scroller.isPointAtScrollX(p)) {
scrollType = 'x';
} else if (this[_scroller].isPointAtScrollY(p)) {
} else if (this._scroller.isPointAtScrollY(p)) {
scrollType = 'y';
}
}, 16)
@ -357,7 +336,7 @@ export default class Board {
'move',
throttle((p: Point) => {
if (scrollType) {
this[_doMoveScroll](scrollType, p);
this._doMoveScroll(scrollType, p);
}
}, 16)
);
@ -366,7 +345,7 @@ export default class Board {
'moveEnd',
throttle((p: Point) => {
if (scrollType) {
this[_doMoveScroll](scrollType, p);
this._doMoveScroll(scrollType, p);
}
scrollType = null;
}, 16)
@ -376,15 +355,15 @@ export default class Board {
}
}
private [_doScrollX](dx: number, prevScrollX?: number) {
const { width } = this[_opts];
private _doScrollX(dx: number, prevScrollX?: number) {
const { width } = this._opts;
let scrollX = prevScrollX;
if (!(typeof scrollX === 'number' && (scrollX > 0 || scrollX <= 0))) {
scrollX = this[_ctx].getTransform().scrollX;
scrollX = this._ctx.getTransform().scrollX;
}
const { position } = this[_screen].calcScreen();
const { xSize } = this[_scroller].calc(position);
const moveX = this[_screen].calcScreenScroll(
const { position } = this._screen.calcScreen();
const { xSize } = this._scroller.calc(position);
const moveX = this._screen.calcScreenScroll(
position.left,
position.right,
xSize,
@ -395,15 +374,15 @@ export default class Board {
this.draw();
}
private [_doScrollY](dy: number, prevScrollY?: number) {
const { height } = this[_opts];
private _doScrollY(dy: number, prevScrollY?: number) {
const { height } = this._opts;
let scrollY = prevScrollY;
if (!(typeof scrollY === 'number' && (scrollY > 0 || scrollY <= 0))) {
scrollY = this[_ctx].getTransform().scrollY;
scrollY = this._ctx.getTransform().scrollY;
}
const { position } = this[_screen].calcScreen();
const { ySize } = this[_scroller].calc(position);
const moveY = this[_screen].calcScreenScroll(
const { position } = this._screen.calcScreen();
const { ySize } = this._scroller.calc(position);
const moveY = this._screen.calcScreenScroll(
position.top,
position.bottom,
ySize,
@ -414,16 +393,16 @@ export default class Board {
this.draw();
}
private [_doMoveScroll](scrollType: 'x' | 'y', point: Point) {
private _doMoveScroll(scrollType: 'x' | 'y', point: Point) {
if (!scrollType) {
return;
}
const { position } = this[_screen].calcScreen();
const { xSize, ySize } = this[_scroller].calc(position);
const { position } = this._screen.calcScreen();
const { xSize, ySize } = this._scroller.calc(position);
if (scrollType === 'x') {
this[_doScrollX](point.x - xSize / 2, 0);
this._doScrollX(point.x - xSize / 2, 0);
} else if (scrollType === 'y') {
this[_doScrollY](point.y - ySize / 2, 0);
this._doScrollY(point.y - ySize / 2, 0);
}
}
}

View file

@ -1,28 +0,0 @@
const _canvas = Symbol('_canvas');
const _displayCanvas = Symbol('_displayCanvas');
const _helperCanvas = Symbol('_helperCanvas');
const _mount = Symbol('_mount');
const _opts = Symbol('_opts');
const _hasRendered = Symbol('_hasRendered');
const _ctx = Symbol('_ctx');
const _helperCtx = Symbol('_helperCtx');
const _watcher = Symbol('_watcher');
const _render = Symbol('_render');
const _parsePrivateOptions = Symbol('_parsePrivateOptions');
const _scroller = Symbol('_scroller');
const _initEvent = Symbol('_initEvent');
const _doScrollX = Symbol('_doScrollX');
const _doScrollY = Symbol('_doScrollY');
const _doMoveScroll = Symbol('_doMoveScroll');
// const _doDoubleClick = Symbol('_doDoubleClick');
const _resetContext = Symbol('_resetContext');
const _screen = Symbol('_screen');
const _tempData = Symbol('_tempData');
export {
_canvas, _displayCanvas, _mount, _opts, _hasRendered, _ctx,
_watcher, _render, _parsePrivateOptions, _scroller,
_initEvent, _doScrollX, _doScrollY, _doMoveScroll, _resetContext,
_screen, _tempData, _helperCtx, _helperCanvas,
};

View file

@ -26,21 +26,6 @@ import {
TempData,
diffElementResourceChangeList
} from './lib';
import {
_board,
_data,
_opts,
_config,
_renderer,
_element,
_tempData,
_draw,
_coreEvent,
// _mapper,
_emitChangeScreen,
_emitChangeData,
_engine
} from './names';
import {
getSelectedElements,
updateElement,
@ -68,25 +53,25 @@ import {
} from './lib/draw/wrapper';
export default class Core {
private [_board]: Board;
private [_data]: IDrawData;
private [_opts]: CoreOptions;
private [_config]: IDrawConfigStrict;
private [_renderer]: Renderer;
private [_element]: Element;
private [_coreEvent]: CoreEvent = new CoreEvent();
private [_tempData]: TempData = new TempData();
private [_engine]: Engine;
private _board: Board;
private _data: IDrawData;
private _opts: CoreOptions;
private _config: IDrawConfigStrict;
private _renderer: Renderer;
private _elementHandler: Element;
private _coreEvent: CoreEvent = new CoreEvent();
private _tempData: TempData = new TempData();
private _engine: Engine;
static is: IsTypeUtil = is;
static check: CheckTypeUtil = check;
constructor(mount: HTMLDivElement, opts: CoreOptions, config?: IDrawConfig) {
this[_data] = { elements: [] };
this[_opts] = opts;
this[_config] = mergeConfig(config || {});
this[_board] = new Board(mount, {
...this[_opts],
this._data = { elements: [] };
this._opts = opts;
this._config = mergeConfig(config || {});
this._board = new Board(mount, {
...this._opts,
canScroll: config?.scrollWrapper?.use,
scrollConfig: {
color: config?.scrollWrapper?.color || '#000000',
@ -94,12 +79,12 @@ export default class Core {
...(config?.scrollWrapper || {})
}
});
this[_renderer] = new Renderer();
this._renderer = new Renderer();
const drawFrame = () => {
const helperCtx = this[_board].getHelperContext();
const helperConfig = this[_engine].getHelperConfig();
this[_board].clear();
const { contextWidth, contextHeight, devicePixelRatio } = this[_opts];
const helperCtx = this._board.getHelperContext();
const helperConfig = this._engine.getHelperConfig();
this._board.clear();
const { contextWidth, contextHeight, devicePixelRatio } = this._opts;
helperCtx.clearRect(
0,
0,
@ -109,47 +94,55 @@ export default class Core {
drawElementWrapper(helperCtx, helperConfig);
drawAreaWrapper(helperCtx, helperConfig);
drawElementListWrappers(helperCtx, helperConfig);
this[_board].draw();
this._board.draw();
};
this[_renderer].on('drawFrame', () => {
this._renderer.on('drawFrame', () => {
drawFrame();
});
this[_renderer].on('drawFrameComplete', () => {
this._renderer.on('drawFrameComplete', () => {
drawFrame();
});
this[_element] = new Element(this[_board].getContext());
this[_engine] = new Engine({
coreEvent: this[_coreEvent],
board: this[_board],
element: this[_element],
config: this[_config],
drawFeekback: this[_draw].bind(this),
getDataFeekback: () => this[_data],
this._elementHandler = new Element(this._board.getContext());
this._engine = new Engine({
coreEvent: this._coreEvent,
board: this._board,
element: this._elementHandler,
config: this._config,
drawFeekback: this.__draw.bind(this),
getDataFeekback: () => this._data,
selectElementByIndex: this.selectElementByIndex.bind(this),
emitChangeScreen: this[_emitChangeScreen].bind(this),
emitChangeData: this[_emitChangeData].bind(this)
emitChangeScreen: this._emitChangeScreen.bind(this),
emitChangeData: this.__emitChangeData.bind(this)
});
this[_engine].init();
this._engine.init();
this[_renderer].on('drawFrame', () => {
this[_coreEvent].trigger('drawFrame', undefined);
this._renderer.on('drawFrame', () => {
this._coreEvent.trigger('drawFrame', undefined);
});
this[_renderer].on('drawFrameComplete', () => {
this[_coreEvent].trigger('drawFrameComplete', undefined);
this._renderer.on('drawFrameComplete', () => {
this._coreEvent.trigger('drawFrameComplete', undefined);
});
this[_tempData].set('hasInited', true);
this._tempData.set('hasInited', true);
}
[_draw](opts?: { resourceChangeUUIDs?: string[] }): void {
this[_engine].updateHelperConfig({
width: this[_opts].width,
height: this[_opts].height,
devicePixelRatio: this[_opts].devicePixelRatio
private _emitChangeScreen() {
if (this._coreEvent.has('changeScreen')) {
this._coreEvent.trigger('changeScreen', {
...this.getScreenTransform()
});
}
}
__draw(opts?: { resourceChangeUUIDs?: string[] }): void {
this._engine.updateHelperConfig({
width: this._opts.width,
height: this._opts.height,
devicePixelRatio: this._opts.devicePixelRatio
});
this[_renderer].thaw();
this[_renderer].render(this[_board].getContext(), this[_data], {
this._renderer.thaw();
this._renderer.render(this._board.getContext(), this._data, {
changeResourceUUIDs: opts?.resourceChangeUUIDs || []
});
}
@ -174,8 +167,8 @@ export default class Core {
return cancelElementByIndex(this, index);
}
cancelElement(uuid: string, opts?: { useMode?: boolean }): void {
return cancelElement(this, uuid, opts);
cancelElement(uuid: string): void {
return cancelElement(this, uuid);
}
moveUpElement(uuid: string): void {
@ -231,34 +224,34 @@ export default class Core {
}
resetSize(opts: BoardSizeOptions) {
this[_opts] = { ...this[_opts], ...opts };
this[_board].resetSize(opts);
this[_draw]();
this._opts = { ...this._opts, ...opts };
this._board.resetSize(opts);
this.__draw();
}
scale(ratio: number): ScreenContext {
const screen = this[_board].scale(ratio);
this[_draw]();
this[_emitChangeScreen]();
const screen = this._board.scale(ratio);
this.__draw();
this._emitChangeScreen();
return screen;
}
scrollLeft(left: number): ScreenContext {
const screen = this[_board].scrollX(0 - left);
this[_draw]();
this[_emitChangeScreen]();
const screen = this._board.scrollX(0 - left);
this.__draw();
this._emitChangeScreen();
return screen;
}
scrollTop(top: number): ScreenContext {
const screen = this[_board].scrollY(0 - top);
this[_draw]();
this[_emitChangeScreen]();
const screen = this._board.scrollY(0 - top);
this.__draw();
this._emitChangeScreen();
return screen;
}
getScreenTransform(): ScreenData {
const transform = this[_board].getTransform();
const transform = this._board.getTransform();
return {
scale: transform.scale,
scrollTop: Math.max(0, 0 - transform.scrollY),
@ -267,71 +260,68 @@ export default class Core {
}
getData(): IDrawData {
return deepClone(this[_data]);
return this._data;
}
setData(data: any | IDrawData, opts?: { triggerChangeEvent: boolean }): void {
const resourceChangeUUIDs = diffElementResourceChangeList(
this[_data],
data
);
this[_data] = this[_element].initData(deepClone(parseData(data)));
const resourceChangeUUIDs = diffElementResourceChangeList(this._data, data);
this._data = this._elementHandler.initData(deepClone(parseData(data)));
if (opts && opts.triggerChangeEvent === true) {
this[_emitChangeData]();
this.__emitChangeData();
}
this[_draw]({ resourceChangeUUIDs });
this.__draw({ resourceChangeUUIDs });
}
clearOperation() {
this[_tempData].clear();
this[_draw]();
this._tempData.clear();
this.__draw();
}
on<T extends keyof TypeCoreEventArgMap>(
key: T,
callback: (p: TypeCoreEventArgMap[T]) => void
) {
this[_coreEvent].on(key, callback);
this._coreEvent.on(key, callback);
}
off<T extends keyof TypeCoreEventArgMap>(
key: T,
callback: (p: TypeCoreEventArgMap[T]) => void
) {
this[_coreEvent].off(key, callback);
this._coreEvent.off(key, callback);
}
getEngine() {
return this._engine;
}
pointScreenToContext(p: Point) {
return this[_board].pointScreenToContext(p);
return this._board.pointScreenToContext(p);
}
pointContextToScreen(p: Point) {
return this[_board].pointContextToScreen(p);
return this._board.pointContextToScreen(p);
}
__getBoardContext(): IDrawContext {
return this[_board].getContext();
return this._board.getContext();
}
__getDisplayContext2D(): CanvasRenderingContext2D {
return this[_board].getDisplayContext2D();
return this._board.getDisplayContext2D();
}
__getOriginContext2D(): CanvasRenderingContext2D {
return this[_board].getOriginContext2D();
return this._board.getOriginContext2D();
}
private [_emitChangeScreen]() {
if (this[_coreEvent].has('changeScreen')) {
this[_coreEvent].trigger('changeScreen', {
...this.getScreenTransform()
});
__emitChangeData() {
if (this._coreEvent.has('changeData')) {
this._coreEvent.trigger('changeData', deepClone(this._data));
}
}
private [_emitChangeData]() {
if (this[_coreEvent].has('changeData')) {
this[_coreEvent].trigger('changeData', deepClone(this[_data]));
}
__getElementHandler() {
return this._elementHandler;
}
}

View file

@ -124,7 +124,7 @@ export class Element {
'left'
].includes(direction)
) {
const p = calcuScaleElemPosition(elem, moveX, moveY, direction, scale);
const p = calcuScaleElemPosition(elem, moveX, moveY, direction);
elem.x = p.x;
elem.y = p.y;
elem.w = p.w;
@ -168,11 +168,11 @@ function calcuScaleElemPosition(
elem: DataElement<keyof DataElemDesc>,
moveX: number,
moveY: number,
direction: HelperWrapperControllerDirection,
scale: number
direction: HelperWrapperControllerDirection
// scale: number
): Point & { w: number; h: number } {
const p = { x: elem.x, y: elem.y, w: elem.w, h: elem.h };
let angle = elem.angle;
let angle = elem.angle || 0;
if (angle < 0) {
angle = Math.max(0, 360 + angle);
}
@ -219,7 +219,7 @@ function calcuScaleElemPosition(
break;
}
case 'top': {
if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) {
if (elem.angle === 0 || Math.abs(elem.angle || 0) < limitQbliqueAngle) {
if (p.h - moveY > 0) {
p.y += moveY;
p.h -= moveY;
@ -228,7 +228,10 @@ function calcuScaleElemPosition(
p.w -= (moveY / elem.h) * elem.w;
}
}
} else if (elem.angle > 0 || elem.angle < 0) {
} else if (
elem.angle !== undefined &&
(elem.angle > 0 || elem.angle < 0)
) {
const angle =
elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360);
let moveDist = calcMoveDist(moveX, moveY);
@ -364,7 +367,7 @@ function calcuScaleElemPosition(
break;
}
case 'right': {
if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) {
if (elem.angle === 0 || Math.abs(elem.angle || 0) < limitQbliqueAngle) {
if (elem.w + moveX > 0) {
p.w += moveX;
if (elem.operation?.limitRatio === true) {
@ -372,7 +375,10 @@ function calcuScaleElemPosition(
p.h += (moveX * elem.h) / elem.w;
}
}
} else if (elem.angle > 0 || elem.angle < 0) {
} else if (
elem.angle !== undefined &&
(elem.angle > 0 || elem.angle < 0)
) {
const angle =
elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360);
let moveDist = calcMoveDist(moveX, moveY);
@ -447,7 +453,7 @@ function calcuScaleElemPosition(
break;
}
case 'bottom': {
if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) {
if (elem.angle === 0 || Math.abs(elem.angle || 0) < limitQbliqueAngle) {
if (elem.h + moveY > 0) {
p.h += moveY;
if (elem.operation?.limitRatio === true) {
@ -455,7 +461,10 @@ function calcuScaleElemPosition(
p.w += (moveY / elem.h) * elem.w;
}
}
} else if (elem.angle > 0 || elem.angle < 0) {
} else if (
elem.angle !== undefined &&
(elem.angle > 0 || elem.angle < 0)
) {
const angle =
elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360);
let moveDist = calcMoveDist(moveX, moveY);
@ -530,7 +539,7 @@ function calcuScaleElemPosition(
break;
}
case 'left': {
if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) {
if (elem.angle === 0 || Math.abs(elem.angle || 0) < limitQbliqueAngle) {
if (elem.w - moveX > 0) {
p.x += moveX;
p.w -= moveX;
@ -539,7 +548,10 @@ function calcuScaleElemPosition(
p.y += ((moveX / elem.w) * elem.h) / 2;
}
}
} else if (elem.angle > 0 || elem.angle < 0) {
} else if (
elem.angle !== undefined &&
(elem.angle > 0 || elem.angle < 0)
) {
const angle =
elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360);
let moveDist = calcMoveDist(moveX, moveY);

View file

@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import {
IDrawData,
Helper,
HelperConfig,
HelperUpdateOpts,
HelperWrapperControllerDirection,
@ -20,7 +19,7 @@ import { LIMIT_QBLIQUE_ANGLE } from './../constant/element';
const limitQbliqueAngle = LIMIT_QBLIQUE_ANGLE;
export class Helper implements Helper {
export class Helper {
private _helperConfig: HelperConfig;
private _coreConfig: IDrawConfigStrict;
private _ctx: IDrawContext;

View file

@ -1,25 +1,24 @@
import { DataElement, DataElemDesc, DataElementBase } from '@idraw/types';
import { deepClone, createUUID } from '@idraw/util';
import { _data, _element, _engine, _draw, _emitChangeData } from './../names';
import { diffElementResourceChange } from './../lib/diff';
import Core from './../index';
import { Mode } from './../constant/static';
import { diffElementResourceChange } from '../lib/diff';
import Core from '../index';
import { Mode } from '../constant/static';
export function getSelectedElements(
core: Core
): DataElement<keyof DataElemDesc>[] {
const elems: DataElement<keyof DataElemDesc>[] = [];
let list: string[] = [];
const uuid = core[_engine].temp.get('selectedUUID');
const uuid = core.getEngine().temp.get('selectedUUID');
if (typeof uuid === 'string' && uuid) {
list.push(uuid);
} else {
list = core[_engine].temp.get('selectedUUIDList');
list = core.getEngine().temp.get('selectedUUIDList');
}
list.forEach((uuid) => {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (index !== null && index >= 0) {
const elem = core[_data]?.elements[index];
const elem = core.getData().elements[index];
if (elem) elems.push(elem);
}
});
@ -31,9 +30,9 @@ export function getElement(
uuid: string
): DataElement<keyof DataElemDesc> | null {
let elem: DataElement<keyof DataElemDesc> | null = null;
const index = core[_engine].helper.getElementIndexByUUID(uuid);
if (index !== null && core[_data].elements[index]) {
elem = deepClone(core[_data].elements[index]);
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (index !== null && core.getData().elements[index]) {
elem = deepClone(core.getData().elements[index]);
}
return elem;
}
@ -43,8 +42,8 @@ export function getElementByIndex(
index: number
): DataElement<keyof DataElemDesc> | null {
let elem: DataElement<keyof DataElemDesc> | null = null;
if (index >= 0 && core[_data].elements[index]) {
elem = deepClone(core[_data].elements[index]);
if (index >= 0 && core.getData().elements[index]) {
elem = deepClone(core.getData().elements[index]);
}
return elem;
}
@ -54,7 +53,7 @@ export function updateElement(
elem: DataElement<keyof DataElemDesc>
) {
const _elem = deepClone(elem) as DataElement<keyof DataElemDesc>;
const data = core[_data];
const data = core.getData();
const resourceChangeUUIDs: string[] = [];
for (let i = 0; i < data.elements.length; i++) {
if (_elem.uuid === data.elements[i]?.uuid) {
@ -66,81 +65,77 @@ export function updateElement(
break;
}
}
core[_emitChangeData]();
core[_draw]({ resourceChangeUUIDs });
core.__emitChangeData();
core.__draw({ resourceChangeUUIDs });
}
export function selectElementByIndex(core: Core, index: number): void {
if (core[_data].elements[index]) {
const uuid = core[_data].elements[index].uuid;
core[_engine].temp.set('mode', Mode.NULL);
if (core.getData().elements[index]) {
const uuid = core.getData().elements[index].uuid;
core.getEngine().temp.set('mode', Mode.NULL);
if (typeof uuid === 'string') {
core[_engine].temp.set('selectedUUID', uuid);
core[_engine].temp.set('selectedUUIDList', []);
core.getEngine().temp.set('selectedUUID', uuid);
core.getEngine().temp.set('selectedUUIDList', []);
}
core[_draw]();
core.__draw();
}
}
export function selectElement(core: Core, uuid: string): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (typeof index === 'number' && index >= 0) {
core.selectElementByIndex(index);
}
}
export function cancelElementByIndex(core: Core, index: number): void {
if (core[_data].elements[index]) {
const uuid = core[_data].elements[index].uuid;
const selectedUUID = core[_engine].temp.get('selectedUUID');
if (core.getData().elements[index]) {
const uuid = core.getData().elements[index].uuid;
const selectedUUID = core.getEngine().temp.get('selectedUUID');
if (typeof uuid === 'string' && uuid === selectedUUID) {
core[_engine].temp.set('mode', Mode.NULL);
core[_engine].temp.set('selectedUUID', null);
core[_engine].temp.set('selectedUUIDList', []);
core.getEngine().temp.set('mode', Mode.NULL);
core.getEngine().temp.set('selectedUUID', null);
core.getEngine().temp.set('selectedUUIDList', []);
}
core[_draw]();
core.__draw();
}
}
export function cancelElement(
core: Core,
uuid: string,
opts?: { useMode?: boolean }
): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
export function cancelElement(core: Core, uuid: string): void {
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (typeof index === 'number' && index >= 0) {
core.cancelElementByIndex(index, opts);
core.cancelElementByIndex(index);
}
}
export function moveUpElement(core: Core, uuid: string): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (
typeof index === 'number' &&
index >= 0 &&
index < core[_data].elements.length - 1
index < core.getData().elements.length - 1
) {
const temp = core[_data].elements[index];
core[_data].elements[index] = core[_data].elements[index + 1];
core[_data].elements[index + 1] = temp;
const temp = core.getData().elements[index];
core.getData().elements[index] = core.getData().elements[index + 1];
core.getData().elements[index + 1] = temp;
}
core[_emitChangeData]();
core[_draw]();
core.__emitChangeData();
core.__draw();
}
export function moveDownElement(core: Core, uuid: string): void {
const index = core[_engine].helper.getElementIndexByUUID(uuid);
const index = core.getEngine().helper.getElementIndexByUUID(uuid);
if (
typeof index === 'number' &&
index > 0 &&
index < core[_data].elements.length
index < core.getData().elements.length
) {
const temp = core[_data].elements[index];
core[_data].elements[index] = core[_data].elements[index - 1];
core[_data].elements[index - 1] = temp;
const temp = core.getData().elements[index];
core.getData().elements[index] = core.getData().elements[index - 1];
core.getData().elements[index - 1] = temp;
}
core[_emitChangeData]();
core[_draw]();
core.__emitChangeData();
core.__draw();
}
export function addElement(
@ -149,18 +144,20 @@ export function addElement(
): string | null {
const _elem = deepClone(elem);
_elem.uuid = createUUID();
core[_data].elements.push(_elem);
core[_emitChangeData]();
core[_draw]();
core.getData().elements.push(_elem);
core.__emitChangeData();
core.__draw();
return _elem.uuid;
}
export function deleteElement(core: Core, uuid: string) {
const index = core[_element].getElementIndex(core[_data], uuid);
const index = core
.__getElementHandler()
.getElementIndex(core.getData(), uuid);
if (index >= 0) {
core[_data].elements.splice(index, 1);
core[_emitChangeData]();
core[_draw]();
core.getData().elements.splice(index, 1);
core.__emitChangeData();
core.__draw();
}
}
@ -169,7 +166,7 @@ export function insertElementBefore(
elem: DataElementBase<keyof DataElemDesc>,
beforeUUID: string
) {
const index = core[_engine].helper.getElementIndexByUUID(beforeUUID);
const index = core.getEngine().helper.getElementIndexByUUID(beforeUUID);
if (index !== null) {
return core.insertElementBeforeIndex(elem, index);
}
@ -184,9 +181,9 @@ export function insertElementBeforeIndex(
const _elem = deepClone(elem);
_elem.uuid = createUUID();
if (index >= 0) {
core[_data].elements.splice(index, 0, _elem);
core[_emitChangeData]();
core[_draw]();
core.getData().elements.splice(index, 0, _elem);
core.__emitChangeData();
core.__draw();
return _elem.uuid;
}
return null;
@ -197,7 +194,7 @@ export function insertElementAfter(
elem: DataElementBase<keyof DataElemDesc>,
beforeUUID: string
) {
const index = core[_engine].helper.getElementIndexByUUID(beforeUUID);
const index = core.getEngine().helper.getElementIndexByUUID(beforeUUID);
if (index !== null) {
return core.insertElementAfterIndex(elem, index);
}
@ -212,9 +209,9 @@ export function insertElementAfterIndex(
const _elem = deepClone(elem);
_elem.uuid = createUUID();
if (index >= 0) {
core[_data].elements.splice(index + 1, 0, _elem);
core[_emitChangeData]();
core[_draw]();
core.getData().elements.splice(index + 1, 0, _elem);
core.__emitChangeData();
core.__draw();
return _elem.uuid;
}
return null;

View file

@ -1,20 +0,0 @@
const _board = Symbol('_board');
const _data = Symbol('_data');
const _opts = Symbol('_opts');
const _config = Symbol('_config');
const _renderer = Symbol('_renderer');
const _element = Symbol('_element');
const _helper = Symbol('_helper');
const _tempData = Symbol('_tempData');
const _draw = Symbol('_draw');
const _coreEvent = Symbol('_coreEvent');
const _mapper = Symbol('_mapper');
const _emitChangeScreen = Symbol('_emitChangeScreen');
const _emitChangeData = Symbol('_emitChangeData');
const _engine = Symbol('_engine');
export {
_board, _data, _opts, _config, _renderer, _element, _helper,
_tempData, _draw, _coreEvent, _mapper,
_emitChangeScreen, _emitChangeData, _engine,
};

View file

@ -4,15 +4,7 @@ import { Options, PrivateOptions } from './types';
import { defaultOptions } from './config';
import { TempData } from './lib/temp';
import { KeyboardWatcher } from './lib/keyboard-watcher';
import {
_opts,
_hasInited,
_initEvent,
_tempData,
_createOpts,
_pushRecord,
_keyboardWatcher
} from './names';
import { redo, undo } from './mixins/record';
import { exportDataURL, toDataURL } from './mixins/file';
import {
@ -29,10 +21,10 @@ import {
// import { version } from './../package.json';
export default class iDraw extends Core {
private [_opts]: PrivateOptions;
private [_hasInited] = false;
private [_tempData] = new TempData();
private [_keyboardWatcher] = new KeyboardWatcher();
private _opts: PrivateOptions;
private _hasInited = false;
private _tempData = new TempData();
private _keyboardWatcher = new KeyboardWatcher();
// static version = version;
@ -50,8 +42,8 @@ export default class iDraw extends Core {
},
config || {}
);
this[_opts] = this[_createOpts](opts);
this[_initEvent]();
this._opts = this._createOpts(opts);
this._initEvent();
}
undo(): { doRecordCount: number; data: IDrawData | null } {
@ -66,6 +58,10 @@ export default class iDraw extends Core {
return toDataURL(this, type, quality);
}
getTempData() {
return this._tempData;
}
async exportDataURL(
type: 'image/png' | 'image/jpeg',
quality?: number
@ -73,21 +69,21 @@ export default class iDraw extends Core {
return exportDataURL(this, type, quality);
}
private [_initEvent]() {
if (this[_hasInited] === true) {
private _initEvent() {
if (this._hasInited === true) {
return;
}
this.on('changeData', (data: IDrawData) => {
this[_pushRecord](data);
this._pushRecord(data);
});
this.on('mouseLeaveScreen', () => {
this[_tempData].set('isFocus', false);
this._tempData.set('isFocus', false);
});
this.on('mouseOverScreen', () => {
this[_tempData].set('isFocus', true);
this._tempData.set('isFocus', true);
});
if (this[_opts].disableKeyboard === false) {
this[_keyboardWatcher]
if (this._opts.disableKeyboard === false) {
this._keyboardWatcher
.on('keyboardCopy', () => copyElements(this))
.on('keyboardPaste', () => pasteElements(this))
.on('keyboardCut', () => cutElements(this))
@ -98,20 +94,20 @@ export default class iDraw extends Core {
.on('keyboardArrowRight', () => keyArrowRight(this))
.on('keyboardUndo', () => keyUndo(this));
}
this[_hasInited] = true;
this._hasInited = true;
}
private [_pushRecord](data: IDrawData) {
const doRecords = this[_tempData].get('doRecords');
if (doRecords.length >= this[_opts].maxRecords) {
private _pushRecord(data: IDrawData) {
const doRecords = this._tempData.get('doRecords');
if (doRecords.length >= this._opts.maxRecords) {
doRecords.shift();
}
doRecords.push({ data, time: Date.now() });
this[_tempData].set('doRecords', doRecords);
this[_tempData].set('unDoRecords', []);
this._tempData.set('doRecords', doRecords);
this._tempData.set('unDoRecords', []);
}
private [_createOpts](opts: Options): PrivateOptions {
private _createOpts(opts: Options): PrivateOptions {
return { ...{}, ...defaultOptions, ...opts };
}
}

View file

@ -1,4 +1,3 @@
import { _tempData } from '../names';
import iDraw from './../index';
export async function exportDataURL(
@ -6,16 +5,16 @@ export async function exportDataURL(
type: 'image/png' | 'image/jpeg',
quality?: number
): Promise<string> {
if (idraw[_tempData].get('isDownloading') === true) {
if (idraw.getTempData().get('isDownloading') === true) {
return Promise.reject('Busy!');
}
idraw[_tempData].set('isDownloading', true);
idraw.getTempData().set('isDownloading', true);
return new Promise((resolve, reject) => {
let dataURL: string = '';
let dataURL = '';
function listenRenderFrameComplete() {
idraw.off('drawFrameComplete', listenRenderFrameComplete);
idraw[_tempData].set('isDownloading', false);
idraw.getTempData().set('isDownloading', false);
const ctx = idraw.__getOriginContext2D();
const canvas = ctx.canvas;
dataURL = canvas.toDataURL(type, quality);
@ -30,8 +29,6 @@ export async function exportDataURL(
});
}
export function toDataURL(
idraw: iDraw,
type: 'image/png' | 'image/jpeg',
@ -41,4 +38,4 @@ export function toDataURL(
const canvas = ctx.canvas;
const dataURL: string = canvas.toDataURL(type, quality);
return dataURL;
}
}

View file

@ -1,43 +1,42 @@
import { deepClone } from '@idraw/util';
import { DataElement, DataElemDesc } from '@idraw/types';
import iDraw from './../index';
import { _tempData } from './../names';
export function copyElements(idraw: iDraw) {
if (idraw[_tempData].get('isFocus') !== true) {
if (idraw.getTempData().get('isFocus') !== true) {
return;
}
const elems = deepClone(idraw.getSelectedElements());
idraw[_tempData].set('clipboardElements', elems);
idraw.getTempData().set('clipboardElements', elems);
}
export function pasteElements(idraw: iDraw) {
if (idraw[_tempData].get('isFocus') !== true) {
if (idraw.getTempData().get('isFocus') !== true) {
return;
}
const elems = idraw[_tempData].get('clipboardElements');
const elems = idraw.getTempData().get('clipboardElements');
const moveRate = 0.1;
elems.forEach((elem) => {
elem.x += elem.w * moveRate;
elem.y += elem.w * moveRate;
idraw.addElement(elem);
});
idraw[_tempData].set('clipboardElements', []);
idraw.getTempData().set('clipboardElements', []);
}
export function cutElements(idraw: iDraw) {
if (idraw[_tempData].get('isFocus') !== true) {
if (idraw.getTempData().get('isFocus') !== true) {
return;
}
const elems = deepClone(idraw.getSelectedElements());
elems.forEach((elem: DataElement<keyof DataElemDesc>) => {
idraw.deleteElement(elem.uuid);
});
idraw[_tempData].set('clipboardElements', elems);
idraw.getTempData().set('clipboardElements', elems);
}
export function deleteElements(idraw: iDraw) {
if (idraw[_tempData].get('isFocus') !== true) {
if (idraw.getTempData().get('isFocus') !== true) {
return;
}
const elems = deepClone(idraw.getSelectedElements());

View file

@ -1,13 +1,12 @@
import { IDrawData } from '@idraw/types';
import iDraw from './../index';
import { _tempData } from './../names';
export function undo(idraw: iDraw): {
doRecordCount: number;
data: IDrawData | null;
} {
const doRecords = idraw[_tempData].get('doRecords');
const unDoRecords = idraw[_tempData].get('unDoRecords');
const doRecords = idraw.getTempData().get('doRecords');
const unDoRecords = idraw.getTempData().get('unDoRecords');
if (!(doRecords.length > 1)) {
return {
doRecordCount: doRecords.length,
@ -22,8 +21,8 @@ export function undo(idraw: iDraw): {
if (record?.data) {
idraw.setData(record.data);
}
idraw[_tempData].set('doRecords', doRecords);
idraw[_tempData].set('unDoRecords', unDoRecords);
idraw.getTempData().set('doRecords', doRecords);
idraw.getTempData().set('unDoRecords', unDoRecords);
return {
doRecordCount: doRecords.length,
data: record?.data || null
@ -34,7 +33,7 @@ export function redo(idraw: iDraw): {
undoRecordCount: number;
data: IDrawData | null;
} {
const unDoRecords = idraw[_tempData].get('unDoRecords');
const unDoRecords = idraw.getTempData().get('unDoRecords');
if (!(unDoRecords.length > 0)) {
return {
undoRecordCount: unDoRecords.length,
@ -45,7 +44,7 @@ export function redo(idraw: iDraw): {
if (record?.data) {
idraw.setData(record.data);
}
idraw[_tempData].set('unDoRecords', unDoRecords);
idraw.getTempData().set('unDoRecords', unDoRecords);
return {
undoRecordCount: unDoRecords.length,
data: record?.data || null

View file

@ -1,12 +0,0 @@
const _opts = Symbol('_opts');
const _hasInited = Symbol('_hasInited');
const _initEvent = Symbol('_initEvent');
const _tempData = Symbol('_tempData');
const _createOpts = Symbol('_createOpts');
const _pushRecord = Symbol('_pushRecord');
const _keyboardWatcher = Symbol('_keyboardWatcher');
export {
_opts, _hasInited, _initEvent, _tempData,
_createOpts, _pushRecord, _keyboardWatcher,
}

View file

@ -9,16 +9,6 @@ import { drawContext } from './lib/draw';
import { TypeLoadDataItem } from './lib/loader-event';
import Loader from './lib/loader';
import { RendererEvent } from './lib/renderer-event';
import {
_queue,
_ctx,
_status,
_loader,
_opts,
_freeze,
_drawFrame,
_retainQueueOneItem
} from './names';
const { requestAnimationFrame } = window;
@ -40,26 +30,26 @@ type Options = {
};
export default class Renderer extends RendererEvent {
private [_queue]: QueueItem[] = [];
private [_ctx]: IDrawContext | null = null;
private [_status]: DrawStatus = DrawStatus.NULL;
private [_loader]: Loader;
private [_opts]?: Options;
private _queue: QueueItem[] = [];
private _ctx: IDrawContext | null = null;
private _status: DrawStatus = DrawStatus.NULL;
private _loader: Loader;
private _opts?: Options;
constructor(opts?: Options) {
super();
this[_opts] = opts;
this[_loader] = new Loader({
this._opts = opts;
this._loader = new Loader({
maxParallelNum: 6
});
this[_loader].on('load', (res: TypeLoadDataItem) => {
this[_drawFrame]();
this._loader.on('load', (res: TypeLoadDataItem) => {
this._drawFrame();
this.trigger('load', { element: res.element });
});
this[_loader].on('error', (res: TypeLoadDataItem) => {
this._loader.on('error', (res: TypeLoadDataItem) => {
this.trigger('error', { element: res.element, error: res.error });
});
this[_loader].on('complete', () => {
this._loader.on('complete', () => {
this.trigger('loadComplete', { t: Date.now() });
});
}
@ -72,13 +62,13 @@ export default class Renderer extends RendererEvent {
changeResourceUUIDs?: string[];
}
): void {
// if ([DrawStatus.STOP, DrawStatus.FREEZE].includes(this[_status])) {
// if ([DrawStatus.STOP, DrawStatus.FREEZE].includes(this._status)) {
// return;
// }
// this[_status] = DrawStatus.FREE;
// this._status = DrawStatus.FREE;
const { changeResourceUUIDs = [] } = opts || {};
this[_status] = DrawStatus.FREE;
this._status = DrawStatus.FREE;
const data = deepClone(originData);
if (Array.isArray(data.elements)) {
@ -89,19 +79,19 @@ export default class Renderer extends RendererEvent {
});
}
if (!this[_ctx]) {
if (!this._ctx) {
// TODO
if (
this[_opts] &&
this._opts &&
Object.prototype.toString.call(target) === '[object HTMLCanvasElement]'
) {
const { width, height, contextWidth, contextHeight, devicePixelRatio } =
this[_opts] as Options;
this._opts as Options;
const canvas = target as HTMLCanvasElement;
canvas.width = width * devicePixelRatio;
canvas.height = height * devicePixelRatio;
const ctx2d = canvas.getContext('2d') as CanvasRenderingContext2D;
this[_ctx] = new Context(ctx2d, {
this._ctx = new Context(ctx2d, {
width,
height,
contextWidth: contextWidth || width,
@ -110,93 +100,93 @@ export default class Renderer extends RendererEvent {
});
} else if (target) {
// TODO
this[_ctx] = target as IDrawContext;
this._ctx = target as IDrawContext;
}
}
if ([DrawStatus.FREEZE].includes(this[_status])) {
if ([DrawStatus.FREEZE].includes(this._status)) {
return;
}
const _data: QueueItem = deepClone({ data }) as QueueItem;
this[_queue].push(_data);
// if (this[_status] !== DrawStatus.DRAWING) {
// this[_status] = DrawStatus.DRAWING;
// this[_drawFrame]();
this._queue.push(_data);
// if (this._status !== DrawStatus.DRAWING) {
// this._status = DrawStatus.DRAWING;
// this._drawFrame();
// }
this[_drawFrame]();
this[_loader].load(data, changeResourceUUIDs || []);
this._drawFrame();
this._loader.load(data, changeResourceUUIDs || []);
}
getContext(): IDrawContext | null {
return this[_ctx];
return this._ctx;
}
thaw() {
this[_status] = DrawStatus.FREE;
this._status = DrawStatus.FREE;
}
private [_freeze]() {
this[_status] = DrawStatus.FREEZE;
private _freeze() {
this._status = DrawStatus.FREEZE;
}
private [_drawFrame]() {
if (this[_status] === DrawStatus.FREEZE) {
private _drawFrame() {
if (this._status === DrawStatus.FREEZE) {
return;
}
requestAnimationFrame(() => {
if (this[_status] === DrawStatus.FREEZE) {
if (this._status === DrawStatus.FREEZE) {
return;
}
const ctx = this[_ctx];
const ctx = this._ctx;
let item: QueueItem | undefined = this[_queue][0];
let item: QueueItem | undefined = this._queue[0];
let isLastFrame = false;
if (this[_queue].length > 1) {
item = this[_queue].shift();
if (this._queue.length > 1) {
item = this._queue.shift();
} else {
isLastFrame = true;
}
if (this[_loader].isComplete() !== true) {
this[_drawFrame]();
if (this._loader.isComplete() !== true) {
this._drawFrame();
if (item && ctx) {
drawContext(ctx, item.data, this[_loader]);
drawContext(ctx, item.data, this._loader);
// this._board.draw();
// this.trigger('drawFrame', { t: Date.now() })
}
} else if (item && ctx) {
drawContext(ctx, item.data, this[_loader]);
drawContext(ctx, item.data, this._loader);
// this._board.draw();
// this.trigger('drawFrame', { t: Date.now() })
this[_retainQueueOneItem]();
this._retainQueueOneItem();
if (!isLastFrame) {
this[_drawFrame]();
this._drawFrame();
} else {
this[_status] = DrawStatus.FREE;
this._status = DrawStatus.FREE;
}
} else {
this[_status] = DrawStatus.FREE;
this._status = DrawStatus.FREE;
}
this.trigger('drawFrame', { t: Date.now() });
if (
this[_loader].isComplete() === true &&
this[_queue].length === 1 &&
this[_status] === DrawStatus.FREE
this._loader.isComplete() === true &&
this._queue.length === 1 &&
this._status === DrawStatus.FREE
) {
if (ctx && this[_queue][0] && this[_queue][0].data) {
drawContext(ctx, this[_queue][0].data, this[_loader]);
if (ctx && this._queue[0] && this._queue[0].data) {
drawContext(ctx, this._queue[0].data, this._loader);
}
this.trigger('drawFrameComplete', { t: Date.now() });
this[_freeze]();
this._freeze();
}
});
}
private [_retainQueueOneItem]() {
if (this[_queue].length <= 1) {
private _retainQueueOneItem() {
if (this._queue.length <= 1) {
return;
}
const lastOne = deepClone(this[_queue][this[_queue].length - 1]);
this[_queue] = [lastOne];
const lastOne = deepClone(this._queue[this._queue.length - 1]);
this._queue = [lastOne];
}
}

View file

@ -1,14 +0,0 @@
const _queue = Symbol('_queue');
const _ctx = Symbol('_ctx');
const _status = Symbol('_status');
const _loader = Symbol('_loader');
const _opts = Symbol('_opts');
const _freeze = Symbol('_freeze');
const _drawFrame = Symbol('_drawFrame');
const _retainQueueOneItem = Symbol('_retainQueueOneItem');
export {
_queue, _ctx, _status, _loader, _opts, _freeze,
_drawFrame, _retainQueueOneItem
}

View file

@ -61,10 +61,10 @@ type HelperUpdateOpts = {
scrollY: number;
};
interface Helper {
updateConfig(data: IDrawData, opts: HelperUpdateOpts): void;
getConfig(): HelperConfig;
}
// interface Helper {
// updateConfig(data: IDrawData, opts: HelperUpdateOpts): void;
// getConfig(): HelperConfig;
// }
type HelperWrapperControllerDirection =
| 'top-left'
@ -78,7 +78,7 @@ type HelperWrapperControllerDirection =
| 'rotate';
export {
Helper,
// Helper,
HelperConfig,
HelperUpdateOpts,
HelperWrapperControllerDirection,