chore: clear unuse code

This commit is contained in:
chenshenhai 2021-11-23 23:34:25 +08:00
parent 88620b5f3a
commit d8fb200f71
17 changed files with 10 additions and 1058 deletions

View file

@ -1,6 +1,6 @@
import {
TypeScreenPosition, TypeScreenSize, TypeScreenContext, TypePoint, TypePointCursor,
TypeBoardOptions, TypeBoardSizeOptions, InterfacePlugin, TypeContext,
TypeBoardOptions, TypeBoardSizeOptions, TypeContext,
} from '@idraw/types';
import util from '@idraw/util';
import { ScreenWatcher } from './lib/screen-watcher';
@ -8,7 +8,7 @@ import { setStyle } from './lib/style';
import { TypeBoardEventArgMap } from './lib/event';
import { Scroller } from './lib/scroller';
import { Screen } from './lib/screen';
import { TempData } from './lib/temp';
// import { TempData } from './lib/temp';
import {
_canvas, _displayCanvas, _mount, _opts, _hasRendered, _ctx,
_watcher, _render, _parsePrivateOptions, _scroller, _helperCanvas, _helperCtx,
@ -38,10 +38,10 @@ class Board {
private [_watcher]: ScreenWatcher;
private [_scroller]: Scroller;
private [_screen]: Screen;
private [_tempData]: TempData;
// private [_tempData]: TempData;
constructor(mount: HTMLDivElement, opts: TypeBoardOptions) {
this[_tempData] = new TempData(opts);
// this[_tempData] = new TempData(opts);
this[_mount] = mount;
this[_canvas] = document.createElement('canvas');
@ -159,10 +159,6 @@ class Board {
return { position, size };
}
addPlugin(plugin: InterfacePlugin) {
this[_tempData].get('plugins').push(plugin);
}
clear() {
const displayCtx = this[_displayCanvas].getContext('2d');
displayCtx?.clearRect(0, 0, this[_displayCanvas].width, this[_displayCanvas].height);

View file

@ -1,12 +1,10 @@
import { InterfacePlugin, TypeBoardOptions, TypeContext } from '@idraw/types';
import { TypeBoardOptions, TypeContext } from '@idraw/types';
import util from '@idraw/util';
const Context = util.Context;
type TempDataDesc = {
plugins: InterfacePlugin[],
ctx: TypeContext,
}
function createDefaultData(opts: TypeBoardOptions) {

View file

@ -1,77 +0,0 @@
import { TypeContext, TypeElement, } from '@idraw/types';
// import util from '@idraw/util'
import { rotateElement } from './../transform';
// import is from './../is';
import { clearContext } from './base';
export function drawCircle(ctx: TypeContext, elem: TypeElement<'circle'>) {
clearContext(ctx);
rotateElement(ctx, elem, (ctx) => {
const { x, y, w, h, desc } = elem;
const {
bgColor = '#000000',
borderColor = '#000000',
borderWidth = 0,
} = desc;
const a = w / 2;
const b = h / 2;
const centerX = x + a;
const centerY = y + b;
// draw border
if (borderWidth && borderWidth > 0) {
const ba = borderWidth / 2 + a;
const bb = borderWidth / 2 + b;
ctx.beginPath();
ctx.setStrokeStyle(borderColor);
ctx.setLineWidth(borderWidth);
ctx.ellipse(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI)
ctx.closePath();
ctx.stroke();
}
// draw content
ctx.beginPath();
ctx.setFillStyle(bgColor);
ctx.ellipse(centerX, centerY, a, b, 0, 0, 2 * Math.PI)
ctx.closePath();
ctx.fill();
// // draw shadow
// clearContext(ctx);
// if ((desc.shadowOffsetX !== undefined && is.number(desc.shadowOffsetX)) || desc.shadowOffsetY !== undefined && is.number(desc.shadowOffsetY)) {
// if (desc.shadowColor !== undefined && util.color.isColorStr(desc.shadowColor)) {
// ctx.setShadowColor(desc.shadowColor);
// }
// if (desc.shadowOffsetX !== undefined && is.number(desc.shadowOffsetX)) {
// ctx.setShadowOffsetX(desc.shadowOffsetX);
// }
// if (desc.shadowOffsetY !== undefined && is.number(desc.shadowOffsetY)) {
// ctx.setShadowOffsetY(desc.shadowOffsetY);
// }
// if (desc.shadowBlur !== undefined && is.number(desc.shadowBlur)) {
// ctx.setShadowBlur(desc.shadowBlur);
// }
// const a = (w + borderWidth * 2) / 2;
// const b = (h + borderWidth * 2) / 2;
// const centerX = x + a - borderWidth;
// const centerY = y + b - borderWidth;
// const unit = (a > b) ? 1 / a : 1 / b;
// ctx.beginPath();
// ctx.setFillStyle('#ffffff6a');
// ctx.moveTo(centerX + a, centerY);
// for(var i = 0; i < 2 * Math.PI; i += unit) {
// ctx.lineTo(centerX + a * Math.cos(i), centerY + b * Math.sin(i));
// }
// ctx.closePath();
// ctx.fill();
// }
})
}

View file

@ -1,20 +0,0 @@
import {
TypeContext,
TypeElement,
} from '@idraw/types';
import { rotateElement } from '../transform';
import Loader from '../loader';
export function drawHTML(
ctx: TypeContext,
elem: TypeElement<'html'>,
loader: Loader,
) {
const content = loader.getContent(elem.uuid);
rotateElement(ctx, elem, () => {
if (content) {
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
}
});
}

View file

@ -1,53 +0,0 @@
import {
TypeContext,
TypeElement,
} from '@idraw/types';
import { rotateElement } from '../transform';
import Loader from '../loader';
export function drawImage (
ctx: TypeContext,
elem: TypeElement<'image'>,
loader: Loader,
) {
// const desc = elem.desc as TypeElemDesc['rect'];
const content = loader.getContent(elem.uuid);
rotateElement(ctx, elem, () => {
// ctx.setFillStyle(desc.color);
// ctx.fillRect(elem.x, elem.y, elem.w, elem.h);
if (content) {
// ctx.drawImage(content, 0, 0, elem.w, elem.h, elem.x, elem.y, elem.w, elem.h);
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
}
});
}
// import {
// TypeContext,
// TypeElement,
// TypeHelperConfig,
// TypeElemDesc,
// } from '@idraw/types';
// import Loader from '../loader';
// import { drawBox } from './base';
// export function drawImage(
// ctx: TypeContext,
// elem: TypeElement<'image'>,
// loader: Loader,
// helperConfig: TypeHelperConfig
// ) {
// const content = loader.getPattern(elem, {
// forceUpdate: helperConfig?.selectedElementWrapper?.uuid === elem.uuid
// });
// drawBox(ctx, elem, content);
// }

View file

@ -1,81 +0,0 @@
import {
TypeContext,
TypeData,
TypeElement,
TypeHelperConfig,
// TypePoint,
} from '@idraw/types';
import util from '@idraw/util';
import Loader from '../loader';
import { clearContext, drawBgColor } from './base';
import { drawRect } from './rect';
import { drawImage } from './image';
import { drawSVG } from './svg';
import { drawHTML } from './html';
import { drawText } from './text';
import { drawCircle } from './circle';
import {
drawElementWrapper, drawAreaWrapper, drawElementListWrappers,
} from './wrapper';
const { isColorStr } = util.color;
export function drawContext(
ctx: TypeContext,
data: TypeData,
helperConfig: TypeHelperConfig,
loader: Loader,
): void {
clearContext(ctx);
const size = ctx.getSize();
ctx.clearRect(0, 0, size.contextWidth, size.contextHeight);
if (typeof data.bgColor === 'string' && isColorStr(data.bgColor)) {
drawBgColor(ctx, data.bgColor);
}
if (!(data.elements.length > 0)) {
return;
}
for (let i = 0; i < data.elements.length; i++) {
const elem = data.elements[i];
if (elem?.operation?.invisible === true) {
continue;
}
switch (elem.type) {
case 'rect': {
drawRect(ctx, elem as TypeElement<'rect'>);
break;
}
case 'text': {
drawText(ctx, elem as TypeElement<'text'>, loader, helperConfig);
break;
}
case 'image': {
drawImage(ctx, elem as TypeElement<'image'>, loader);
break;
}
case 'svg': {
drawSVG(ctx, elem as TypeElement<'svg'>, loader);
break;
}
case 'html': {
drawHTML(ctx, elem as TypeElement<'html'>, loader);
break;
}
case 'circle': {
drawCircle(ctx, elem as TypeElement<'circle'>);
break;
}
default: {
// nothing
break;
}
}
}
drawElementWrapper(ctx, helperConfig);
drawAreaWrapper(ctx, helperConfig);
drawElementListWrappers(ctx, helperConfig);
}

View file

@ -1,13 +0,0 @@
import {
TypeContext,
TypeElement,
} from '@idraw/types';
import { drawBox } from './base';
export function drawRect(ctx: TypeContext, elem: TypeElement<'rect'>) {
drawBox(ctx, elem, elem.desc.bgColor as string);
}

View file

@ -1,47 +0,0 @@
import {
TypeContext,
TypeElement,
} from '@idraw/types';
import { rotateElement } from '../transform';
import Loader from '../loader';
export function drawSVG (
ctx: TypeContext,
elem: TypeElement<'svg'>,
loader: Loader,
) {
// const desc = elem.desc as TypeElemDesc['rect'];
const content = loader.getContent(elem.uuid);
rotateElement(ctx, elem, () => {
// ctx.setFillStyle(desc.color);
// ctx.fillRect(elem.x, elem.y, elem.w, elem.h);
if (content) {
// ctx.drawImage(content, 0, 0, elem.w, elem.h, elem.x, elem.y, elem.w, elem.h);
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
}
});
}
// import {
// TypeContext,
// TypeElement,
// TypeHelperConfig,
// } from '@idraw/types';
// import Loader from '../loader';
// import { drawBox } from './base';
// export function drawSVG(
// ctx: TypeContext,
// elem: TypeElement<'svg'>,
// loader: Loader,
// helperConfig: TypeHelperConfig
// ) {
// const content = loader.getPattern(elem, {
// forceUpdate: helperConfig?.selectedElementWrapper?.uuid === elem.uuid
// });
// drawBox(ctx, elem, content);
// }

View file

@ -1,143 +0,0 @@
import {
TypeContext,
TypeElemDescText,
TypeElement,
TypeHelperConfig,
} from '@idraw/types';
import util from '@idraw/util';
import Loader from '../loader';
import { clearContext, drawBox } from './base';
import { rotateElement } from './../transform';
import is from './../is';
export function drawText(
ctx: TypeContext,
elem: TypeElement<'text'>,
loader: Loader,
helperConfig: TypeHelperConfig
) {
clearContext(ctx);
drawBox(ctx, elem, elem.desc.bgColor || 'transparent');
rotateElement(ctx, elem, () => {
const desc: TypeElemDescText = {
...{
fontSize: 12,
fontFamily: 'sans-serif',
textAlign: 'center',
},
...elem.desc
};
ctx.setFillStyle(elem.desc.color);
ctx.setTextBaseline('top');
ctx.setFont({
fontWeight: desc.fontWeight,
fontSize: desc.fontSize,
fontFamily: desc.fontFamily
});
const descText = desc.text.replace(/\r\n/ig, '\n');
const fontHeight = desc.lineHeight || desc.fontSize;
const descTextList = descText.split('\n');
const lines: {text: string, width: number}[] = [];
descTextList.forEach((tempText) => {
let lineText = '';
let lineNum = 0;
for (let i = 0; i < tempText.length; i++) {
if (ctx.measureText(lineText + (tempText[i] || '')).width < ctx.calcDeviceNum(elem.w)) {
lineText += (tempText[i] || '');
} else {
lines.push({
text: lineText,
width: ctx.calcScreenNum(ctx.measureText(lineText).width),
});
lineText = (tempText[i] || '');
lineNum ++;
}
if ((lineNum + 1) * fontHeight > elem.h) {
break;
}
if (lineText && tempText.length - 1 === i) {
if ((lineNum + 1) * fontHeight < elem.h) {
lines.push({
text: lineText,
width: ctx.calcScreenNum(ctx.measureText(lineText).width),
});
break;
}
}
}
});
// draw text lines
{
let _y = elem.y;
if (lines.length * fontHeight < elem.h) {
_y += ((elem.h - lines.length * fontHeight) / 2);
}
if (desc.textShadowColor !== undefined && util.color.isColorStr(desc.textShadowColor)) {
ctx.setShadowColor(desc.textShadowColor);
}
if (desc.textShadowOffsetX !== undefined && is.number(desc.textShadowOffsetX)) {
ctx.setShadowOffsetX(desc.textShadowOffsetX);
}
if (desc.textShadowOffsetY !== undefined && is.number(desc.textShadowOffsetY)) {
ctx.setShadowOffsetY(desc.textShadowOffsetY);
}
if (desc.textShadowBlur !== undefined && is.number(desc.textShadowBlur)) {
ctx.setShadowBlur(desc.textShadowBlur);
}
lines.forEach((line, i) => {
let _x = elem.x;
if (desc.textAlign === 'center') {
_x = elem.x + (elem.w - line.width) / 2;
} else if (desc.textAlign === 'right') {
_x = elem.x + (elem.w - line.width);
}
ctx.fillText(line.text, _x, _y + fontHeight * i);
});
clearContext(ctx);
}
// draw text stroke
if (util.color.isColorStr(desc.strokeColor) && desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
let _y = elem.y;
if (lines.length * fontHeight < elem.h) {
_y += ((elem.h - lines.length * fontHeight) / 2);
}
lines.forEach((line, i) => {
let _x = elem.x;
if (desc.textAlign === 'center') {
_x = elem.x + (elem.w - line.width) / 2;
} else if (desc.textAlign === 'right') {
_x = elem.x + (elem.w - line.width);
}
if (desc.strokeColor !== undefined) {
ctx.setStrokeStyle(desc.strokeColor);
}
if (desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
ctx.setLineWidth(desc.strokeWidth);
}
ctx.strokeText(line.text, _x, _y + fontHeight * i);
});
}
});
}
// export function createTextSVG(elem: TypeElement<'text'>): string {
// const svg = `
// <svg xmlns="http://www.w3.org/2000/svg" width="${elem.w}" height = "${elem.h}">
// <foreignObject width="100%" height="100%">
// <div xmlns = "http://www.w3.org/1999/xhtml" style="font-size: ${elem.desc.size}px; color:${elem.desc.color};">
// <span>${elem.desc.text || ''}</span>
// </div>
// </foreignObject>
// </svg>
// `;
// return svg;
// }

View file

@ -0,0 +1,5 @@
export class Engine {
constructor() {
}
}

View file

@ -1,4 +1,3 @@
export * from './draw/index';
export * from './calculate';
export * from './check';
export * from './config';
@ -7,11 +6,8 @@ export * from './diff';
export * from './element';
export * from './helper';
export * from './is';
export * from './loader-event';
export * from './loader';
export * from './mapper';
export * from './parse';
export * from './renderer';
export * from './temp';
export * from './transform';
export * from './value';

View file

@ -1,83 +0,0 @@
export type TypeLoadData = {
[uuid: string]: {
type: 'image' | 'svg' | 'html',
status: 'null' | 'loaded' | 'fail',
content: null | HTMLImageElement | HTMLCanvasElement,
elemW: number;
elemH: number;
source: string,
error?: any,
}
}
export type TypeLoaderEventArgMap = {
'complete': undefined;
'load': TypeLoadData[string];
'error': TypeLoadData[string];
}
export interface TypeLoaderEvent {
on<T extends keyof TypeLoaderEventArgMap >(key: T, callback: (p: TypeLoaderEventArgMap[T]) => void): void
off<T extends keyof TypeLoaderEventArgMap >(key: T, callback: (p: TypeLoaderEventArgMap[T]) => void): void
trigger<T extends keyof TypeLoaderEventArgMap >(key: T, p: TypeLoaderEventArgMap[T]): void
}
export class LoaderEvent implements TypeLoaderEvent {
private _listeners: Map<string, ((p: any) => void)[]>;
constructor() {
this._listeners = new Map();
}
on<T extends keyof TypeLoaderEventArgMap >(eventKey: T, callback: (p: TypeLoaderEventArgMap[T]) => void) {
if (this._listeners.has(eventKey)) {
const callbacks = this._listeners.get(eventKey);
callbacks?.push(callback);
this._listeners.set(eventKey, callbacks || []);
} else {
this._listeners.set(eventKey, [callback]);
}
}
off<T extends keyof TypeLoaderEventArgMap >(eventKey: T, callback: (p: TypeLoaderEventArgMap[T]) => void) {
if (this._listeners.has(eventKey)) {
const callbacks = this._listeners.get(eventKey);
if (Array.isArray(callbacks)) {
for (let i = 0; i < callbacks?.length; i++) {
if (callbacks[i] === callback) {
callbacks.splice(i, 1);
break;
}
}
}
this._listeners.set(eventKey, callbacks || []);
}
}
trigger<T extends keyof TypeLoaderEventArgMap >(eventKey: T, arg: TypeLoaderEventArgMap[T]) {
const callbacks = this._listeners.get(eventKey);
if (Array.isArray(callbacks)) {
callbacks.forEach((cb) => {
cb(arg);
});
return true;
} else {
return false;
}
}
has<T extends keyof TypeLoaderEventArgMap> (name: string) {
if (this._listeners.has(name)) {
const list: ((p: TypeLoaderEventArgMap[T]) => void)[] | undefined = this._listeners.get(name);
if (Array.isArray(list) && list.length > 0) {
return true;
}
}
return false;
}
}

View file

@ -1,323 +0,0 @@
import { TypeData, TypeElement } from '@idraw/types';
import Board from '@idraw/board';
import util from '@idraw/util';
import { LoaderEvent, TypeLoadData, TypeLoaderEventArgMap } from './loader-event';
import { filterScript } from './../util/filter';
const { loadImage, loadSVG, loadHTML } = util.loader;
type Options = {
board: Board;
maxParallelNum: number
}
enum LoaderStatus {
FREE = 'free',
LOADING = 'loading',
COMPLETE = 'complete',
}
export default class Loader {
private _opts: Options;
private _event: LoaderEvent;
// private _patternMap: {[uuid: string]: CanvasPattern} = {}
private _currentLoadData: TypeLoadData = {};
private _currentUUIDQueue: string[] = [];
private _storageLoadData: TypeLoadData = {};
private _status: LoaderStatus = LoaderStatus.FREE;
private _waitingLoadQueue: Array<{
uuidQueue: string[],
loadData: TypeLoadData,
}> = [];
constructor(opts: Options) {
this._opts = opts;
this._event = new LoaderEvent();
this._waitingLoadQueue = [];
}
load(data: TypeData, changeResourceUUIDs: string[]): void {
const [uuidQueue, loadData] = this._resetLoadData(data, changeResourceUUIDs);
if (this._status === LoaderStatus.FREE || this._status === LoaderStatus.COMPLETE) {
this._currentUUIDQueue = uuidQueue;
this._currentLoadData = loadData;
this._loadTask();
} else if (this._status === LoaderStatus.LOADING && uuidQueue.length > 0) {
this._waitingLoadQueue.push({
uuidQueue,
loadData,
});
}
}
on<T extends keyof TypeLoaderEventArgMap>(
name: T,
callback: (arg: TypeLoaderEventArgMap[T]
) => void) {
this._event.on(name, callback);
}
off<T extends keyof TypeLoaderEventArgMap>(
name: T,
callback: (arg: TypeLoaderEventArgMap[T]
) => void) {
this._event.off(name, callback);
}
isComplete() {
return this._status === LoaderStatus.COMPLETE;
}
getContent(uuid: string): null | HTMLImageElement | HTMLCanvasElement {
if (this._storageLoadData[uuid]?.status === 'loaded') {
return this._storageLoadData[uuid].content;
}
return null;
}
// getPattern(
// elem: TypeElement<keyof TypeElemDesc>,
// opts?: {
// forceUpdate: boolean
// }
// ): null | CanvasPattern {
// if (this._patternMap[elem.uuid] ) {
// if (!(opts && opts.forceUpdate === true)) {
// return this._patternMap[elem.uuid];
// }
// }
// const item = this._currentLoadData[elem.uuid];
// if (item?.status === 'loaded') {
// const board = this._opts.board;
// const tempCanvas = board.createCanvas();
// const tempCtx = board.createContext(tempCanvas);
// const image = this.getContent(elem.uuid);
// tempCtx.drawImage(image, elem.x, elem.y, elem.w, elem.h);
// const canvas = board.createCanvas();
// const ctx = board.createContext(canvas);
// const pattern = ctx.createPattern(tempCanvas, 'no-repeat');
// if (pattern) this._patternMap[elem.uuid] = pattern;
// return pattern;
// }
// return null;
// }
private _resetLoadData(data: TypeData, changeResourceUUIDs: string[]): [string[], TypeLoadData] {
const loadData: TypeLoadData = {};
const uuidQueue: string[] = [];
const storageLoadData = this._storageLoadData;
// add new load-data
for (let i = data.elements.length - 1; i >= 0; i --) {
const elem = data.elements[i] as TypeElement<'image' | 'svg' | 'html'>;
if (['image', 'svg', 'html', ].includes(elem.type)) {
if (!storageLoadData[elem.uuid]) {
loadData[elem.uuid] = this._createEmptyLoadItem(elem);
uuidQueue.push(elem.uuid);
} else {
if (changeResourceUUIDs.includes(elem.uuid)) {
loadData[elem.uuid] = this._createEmptyLoadItem(elem);
uuidQueue.push(elem.uuid);
}
// if (elem.type === 'image') {
// const _ele = elem as TypeElement<'image'>;
// if (_ele.desc.src !== storageLoadData[elem.uuid].source) {
// loadData[elem.uuid] = this._createEmptyLoadItem(elem);
// uuidQueue.push(elem.uuid);
// }
// } else if (elem.type === 'svg') {
// const _ele = elem as TypeElement<'svg'>;
// if (_ele.desc.svg !== storageLoadData[elem.uuid].source) {
// loadData[elem.uuid] = this._createEmptyLoadItem(elem);
// uuidQueue.push(elem.uuid);
// }
// } else if (elem.type === 'html') {
// const _ele = elem as TypeElement<'html'>;
// if (filterScript(_ele.desc.html) !== storageLoadData[elem.uuid].source) {
// loadData[elem.uuid] = this._createEmptyLoadItem(elem);
// uuidQueue.push(elem.uuid);
// }
// }
}
}
}
// // clear unuse load-data
// const uuids = Object.keys(currentLoadData);
// data.elements.forEach((elem) => {
// if (uuids.includes(elem.uuid) !== true) {
// delete loadData[elem.uuid];
// }
// });
return [uuidQueue, loadData];
}
private _createEmptyLoadItem(elem: TypeElement<'image' | 'svg' | 'html'>): TypeLoadData[string] {
let source = '';
const type: TypeLoadData[string]['type'] = elem.type as TypeLoadData[string]['type'];
let elemW: number = elem.w;
let elemH: number = elem.h;
if (elem.type === 'image') {
const _elem = elem as TypeElement<'image'>;
source = _elem.desc.src || '';
} else if (elem.type === 'svg') {
const _elem = elem as TypeElement<'svg'>;
source = _elem.desc.svg || '';
} else if (elem.type === 'html') {
const _elem = elem as TypeElement<'html'>;
source = filterScript(_elem.desc.html || '');
elemW = _elem.desc.width || elem.w;
elemH = _elem.desc.height || elem.h;
}
return {
type: type,
status: 'null',
content: null,
source,
elemW,
elemH,
};
}
private _loadTask() {
if (this._status === LoaderStatus.LOADING) {
return;
}
this._status = LoaderStatus.LOADING;
if (this._currentUUIDQueue.length === 0) {
if (this._waitingLoadQueue.length === 0) {
this._status = LoaderStatus.COMPLETE;
this._event.trigger('complete', undefined);
return;
} else {
const waitingItem = this._waitingLoadQueue.shift();
if (waitingItem) {
const { uuidQueue, loadData } = waitingItem;
this._currentLoadData = loadData;
this._currentUUIDQueue = uuidQueue;
}
}
}
const { maxParallelNum } = this._opts;
const uuids = this._currentUUIDQueue.splice(0, maxParallelNum);
const uuidMap: {[uuid: string]: number} = {};
uuids.forEach((url, i) => {
uuidMap[url] = i;
});
const loadUUIDList: string[] = [];
const _loadAction = () => {
if (loadUUIDList.length >= maxParallelNum) {
return false;
}
if (uuids.length === 0) {
return true;
}
for (let i = loadUUIDList.length; i < maxParallelNum; i++) {
const uuid = uuids.shift();
if (uuid === undefined) {
break;
}
loadUUIDList.push(uuid);
this._loadElementSource(this._currentLoadData[uuid]).then((image) => {
loadUUIDList.splice(loadUUIDList.indexOf(uuid), 1);
const status = _loadAction();
this._storageLoadData[uuid] = {
type: this._currentLoadData[uuid].type,
status: 'loaded',
content: image,
source: this._currentLoadData[uuid].source,
elemW: this._currentLoadData[uuid].elemW,
elemH: this._currentLoadData[uuid].elemH,
};
if (loadUUIDList.length === 0 && uuids.length === 0 && status === true) {
this._status = LoaderStatus.FREE;
this._loadTask();
}
this._event.trigger('load', {
type: this._storageLoadData[uuid].type,
status: this._storageLoadData[uuid].status,
content: this._storageLoadData[uuid].content,
source: this._storageLoadData[uuid].source,
elemW: this._storageLoadData[uuid].elemW,
elemH: this._storageLoadData[uuid].elemH,
});
}).catch((err) => {
console.warn(err);
loadUUIDList.splice(loadUUIDList.indexOf(uuid), 1);
const status = _loadAction();
if (this._currentLoadData[uuid]) {
this._storageLoadData[uuid] = {
type: this._currentLoadData[uuid]?.type,
status: 'fail',
content: null,
error: err,
source: this._currentLoadData[uuid]?.source,
elemW: this._currentLoadData[uuid]?.elemW,
elemH: this._currentLoadData[uuid]?.elemH,
};
}
if (loadUUIDList.length === 0 && uuids.length === 0 && status === true) {
this._status = LoaderStatus.FREE;
this._loadTask();
}
if (this._currentLoadData[uuid]) {
this._event.trigger('error', {
type: this._storageLoadData[uuid]?.type,
status: this._storageLoadData[uuid]?.status,
content: this._storageLoadData[uuid]?.content,
source: this._storageLoadData[uuid]?.source,
elemW: this._storageLoadData[uuid]?.elemW,
elemH: this._storageLoadData[uuid]?.elemH,
});
}
});
}
return false;
};
_loadAction();
}
private async _loadElementSource(
params: TypeLoadData[string]
): Promise<HTMLImageElement> {
if (params && params.type === 'image') {
const image = await loadImage(params.source);
return image;
} else if (params && params.type === 'svg') {
const image = await loadSVG(
params.source
);
return image;
} else if (params && params.type === 'html') {
const image = await loadHTML(
params.source, {
width: params.elemW, height: params.elemH
}
);
return image;
}
throw Error('Element\'s source is not support!');
}
}

View file

@ -1,69 +0,0 @@
export type TypeRendererEventArgMap = {
'drawFrame': void;
'drawFrameComplete': void;
}
export interface TypeRendererEvent {
on<T extends keyof TypeRendererEventArgMap >(key: T, callback: (p: TypeRendererEventArgMap[T]) => void): void
off<T extends keyof TypeRendererEventArgMap >(key: T, callback: (p: TypeRendererEventArgMap[T]) => void): void
trigger<T extends keyof TypeRendererEventArgMap >(key: T, p: TypeRendererEventArgMap[T]): void
}
export class RendererEvent implements TypeRendererEvent {
private _listeners: Map<string, ((p: any) => void)[]>;
constructor() {
this._listeners = new Map();
}
on<T extends keyof TypeRendererEventArgMap >(eventKey: T, callback: (p: TypeRendererEventArgMap[T]) => void) {
if (this._listeners.has(eventKey)) {
const callbacks = this._listeners.get(eventKey);
callbacks?.push(callback);
this._listeners.set(eventKey, callbacks || []);
} else {
this._listeners.set(eventKey, [callback]);
}
}
off<T extends keyof TypeRendererEventArgMap >(eventKey: T, callback: (p: TypeRendererEventArgMap[T]) => void) {
if (this._listeners.has(eventKey)) {
const callbacks = this._listeners.get(eventKey);
if (Array.isArray(callbacks)) {
for (let i = 0; i < callbacks?.length; i++) {
if (callbacks[i] === callback) {
callbacks.splice(i, 1);
break;
}
}
}
this._listeners.set(eventKey, callbacks || []);
}
}
trigger<T extends keyof TypeRendererEventArgMap >(eventKey: T, arg: TypeRendererEventArgMap[T]) {
const callbacks = this._listeners.get(eventKey);
if (Array.isArray(callbacks)) {
callbacks.forEach((cb) => {
cb(arg);
});
return true;
} else {
return false;
}
}
has<T extends keyof TypeRendererEventArgMap> (name: string) {
if (this._listeners.has(name)) {
const list: ((p: TypeRendererEventArgMap[T]) => void)[] | undefined = this._listeners.get(name);
if (Array.isArray(list) && list.length > 0) {
return true;
}
}
return false;
}
}

View file

@ -1,132 +0,0 @@
import { TypeData, TypeHelperConfig, } from '@idraw/types';
import util from '@idraw/util';
import Board from '@idraw/board';
import { drawContext } from './draw';
import Loader from './loader';
import { RendererEvent } from './renderer-event';
const { requestAnimationFrame } = window;
const { deepClone } = util.data;
type QueueItem = { data: TypeData, helper: TypeHelperConfig };
enum DrawStatus {
NULL = 'null',
FREE = 'free',
DRAWING = 'drawing',
FREEZE = 'freeze',
// STOP = 'stop',
}
export class Renderer extends RendererEvent {
private _queue: QueueItem[] = [];
private _board: Board;
private _status: DrawStatus = DrawStatus.NULL;
private _loader: Loader;
constructor(board: Board) {
super();
this._board = board;
this._loader = new Loader({
board: board,
maxParallelNum: 6
});
this._loader.on('load', (res) => {
this._drawFrame();
// console.log('Load: ', res);
});
this._loader.on('error', (res) => {
console.log('Loader Error: ', res);
});
this._loader.on('complete', (res) => {
// console.log('complete: ', res);
});
}
freeze() {
this._status = DrawStatus.FREEZE;
}
thaw() {
this._status = DrawStatus.FREE;
}
// stop() {
// this._status = DrawStatus.STOP;
// }
// restart() {
// this._status = DrawStatus.NULL;
// }
render(data: TypeData, helper: TypeHelperConfig, changeResourceUUIDs: string[]): void {
// if ([DrawStatus.STOP, DrawStatus.FREEZE].includes(this._status)) {
// return;
// }
if ([DrawStatus.FREEZE].includes(this._status)) {
return;
}
const _data: QueueItem = deepClone({ data, helper }) as QueueItem;
this._queue.push(_data);
if (this._status !== DrawStatus.DRAWING) {
this._status = DrawStatus.DRAWING;
this._drawFrame();
}
this._loader.load(data, changeResourceUUIDs);
}
private _drawFrame() {
if (this._status === DrawStatus.FREEZE) {
return;
}
requestAnimationFrame(() => {
if (this._status === DrawStatus.FREEZE) {
return;
}
const ctx = this._board.getContext();
let item: QueueItem | undefined = this._queue[0];
let isLastFrame = false;
if (this._queue.length > 1) {
item = this._queue.shift();
} else {
isLastFrame = true;
}
if (this._loader.isComplete() !== true) {
this._drawFrame();
if (item) {
drawContext(ctx, item.data, item.helper, this._loader);
this._board.draw();
}
} else if (item) {
drawContext(ctx, item.data, item.helper, this._loader);
this._board.draw();
this._retainQueueOneItem();
if (!isLastFrame) {
this._drawFrame();
} else {
this._status = DrawStatus.FREE;
}
} else {
this._status = DrawStatus.FREE;
}
this.trigger('drawFrame', undefined)
if (this._loader.isComplete() === true && this._queue.length === 1 && this._status === DrawStatus.FREE) {
this.trigger('drawFrameComplete', undefined);
this.freeze();
}
});
}
private _retainQueueOneItem() {
if (this._queue.length <= 1) {
return;
}
const lastOne = deepClone(this._queue[this._queue.length - 1]);
this._queue = [lastOne];
}
}

View file

@ -30,7 +30,6 @@ export class HelperPlugin implements Required<InterfaceHelperPlugin> {
}
onMoveStart(detail: TypeHelperPluginEventDetail): void | TypeHelperPluginEventResult {
}

View file

@ -1,4 +1,3 @@
export * from './draw/index';
export * from './diff';
export * from './loader-event';
export * from './loader';