diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts index 1bf02ca..c742754 100644 --- a/packages/board/src/index.ts +++ b/packages/board/src/index.ts @@ -51,7 +51,7 @@ class Board { height: opts.height, devicePixelRatio: opts.devicePixelRatio || 1, scrollConfig: opts.scrollConfig, - }) + }); this[_render](); } @@ -137,7 +137,7 @@ class Board { getScreenInfo(): { size: TypeScreenSize, position: TypeScreenPosition, deviceSize: TypeScreenSize, width: number, height: number, devicePixelRatio: number - } { + } { return this[_screen].calcScreen(); } @@ -224,13 +224,13 @@ class Board { this.on('move', throttle((p: TypePoint) => { if (scrollType) { - this[_doMoveScroll](scrollType, p) + this[_doMoveScroll](scrollType, p); } }, 16)); this.on('moveEnd', throttle((p: TypePoint) => { if (scrollType) { - this[_doMoveScroll](scrollType, p) + this[_doMoveScroll](scrollType, p); } scrollType = null; }, 16)); @@ -241,7 +241,7 @@ class Board { 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); @@ -254,7 +254,7 @@ class Board { 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); diff --git a/packages/board/src/lib/context.ts b/packages/board/src/lib/context.ts index 9b7ee66..f0b3ab3 100644 --- a/packages/board/src/lib/context.ts +++ b/packages/board/src/lib/context.ts @@ -40,7 +40,7 @@ class Context implements TypeContext { } resetSize(opts: TypeBoardSizeOptions) { - this._opts = {...this._opts, ...opts} + this._opts = {...this._opts, ...opts}; } calcDeviceNum(num: number): number { @@ -175,7 +175,7 @@ class Context implements TypeContext { } createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null { - return this._ctx.createPattern(image, repetition) + return this._ctx.createPattern(image, repetition); } measureText(text: string): TextMetrics { diff --git a/packages/board/src/lib/istype.ts b/packages/board/src/lib/istype.ts index 8f320b1..c13a8bb 100644 --- a/packages/board/src/lib/istype.ts +++ b/packages/board/src/lib/istype.ts @@ -1,3 +1,3 @@ -import util from '@idraw/util' +import util from '@idraw/util'; export default util.istype; \ No newline at end of file diff --git a/packages/board/src/lib/screen.ts b/packages/board/src/lib/screen.ts index 7771915..0281adf 100644 --- a/packages/board/src/lib/screen.ts +++ b/packages/board/src/lib/screen.ts @@ -13,7 +13,7 @@ type Options = { const _opts = Symbol('_opts'); -const _ctx = Symbol('_ctx') +const _ctx = Symbol('_ctx'); export class Screen { private [_opts]: Options; @@ -25,13 +25,13 @@ export class Screen { } resetSize(opts: TypeBoardSizeOptions) { - this[_opts] = {...this[_opts], ...opts} + this[_opts] = {...this[_opts], ...opts}; } calcScreen(): { size: TypeScreenSize, position: TypeScreenPosition, deviceSize: TypeScreenSize, width: number, height: number, devicePixelRatio: number - } { + } { const scaleRatio = this[_ctx].getTransform().scale; const { width, height, contextWidth, contextHeight, @@ -43,25 +43,25 @@ export class Screen { // make context center this[_ctx].setTransform({ scrollX: (width - contextWidth * scaleRatio) / 2, - }) + }); } if (contextHeight * scaleRatio <= height) { // make context center this[_ctx].setTransform({ scrollY: (height - contextHeight * scaleRatio) / 2, - }) + }); } if (contextWidth * scaleRatio >= width && this[_ctx].getTransform().scrollX > 0) { this[_ctx].setTransform({ scrollX: 0, - }) + }); } if (contextHeight * scaleRatio >= height && this[_ctx].getTransform().scrollY > 0) { this[_ctx].setTransform({ scrollY: 0, - }) + }); } const { scrollX: _scrollX, scrollY: _scrollY } = this[_ctx].getTransform(); @@ -70,12 +70,12 @@ export class Screen { if (_scrollX < 0 && Math.abs(_scrollX) > Math.abs(contextWidth * scaleRatio - width)) { this[_ctx].setTransform({ scrollX: 0 - Math.abs(contextWidth * scaleRatio - width) - }) + }); } if (_scrollY < 0 && Math.abs(_scrollY) > Math.abs(contextHeight * scaleRatio - height)) { this[_ctx].setTransform({ scrollY: 0 - Math.abs(contextHeight * scaleRatio - height) - }) + }); } // result size @@ -110,7 +110,7 @@ export class Screen { } calcScreenScroll( start: number, end: number, sliderSize: number, limitLen: number, moveDistance: number - ): number { + ): number { let scrollDistance = start; let scrollLen = limitLen - sliderSize; if (start <= 0 && end <= 0) { diff --git a/packages/board/src/lib/scroller.ts b/packages/board/src/lib/scroller.ts index e50b8cd..977886f 100644 --- a/packages/board/src/lib/scroller.ts +++ b/packages/board/src/lib/scroller.ts @@ -22,7 +22,7 @@ type TypePrivateOptions = TypeOptions & { const defaultScrollConfig = { lineWidth: 12, color: '#a0a0a0' -} +}; export class Scroller { @@ -123,7 +123,7 @@ export class Scroller { } getLineWidth(): number { - let lineWidth = this._opts.scrollConfig.lineWidth; + const lineWidth = this._opts.scrollConfig.lineWidth; return lineWidth; } @@ -202,7 +202,7 @@ function drawBox( r = Math.min(r, w / 2, h / 2); if (w < r * 2 || h < r * 2) { r = 0; - }; + } ctx.beginPath(); ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); diff --git a/packages/board/src/lib/watcher.ts b/packages/board/src/lib/watcher.ts index eedaca5..74e3042 100644 --- a/packages/board/src/lib/watcher.ts +++ b/packages/board/src/lib/watcher.ts @@ -32,7 +32,7 @@ export class Watcher { canvas.addEventListener('mousedown', this._listenMoveStart.bind(this), true); canvas.addEventListener('mousemove', this._listenMove.bind(this), true); canvas.addEventListener('mouseup', this._listenMoveEnd.bind(this), true); - canvas.addEventListener('mouseleave', this._listenMoveEnd.bind(this), true) + canvas.addEventListener('mouseleave', this._listenMoveEnd.bind(this), true); canvas.addEventListener('wheel', this._listenWheel.bind(this), true); canvas.addEventListener('touchstart', this._listenMoveStart.bind(this), true); diff --git a/packages/board/src/names.ts b/packages/board/src/names.ts index 99217e7..4bc9562 100644 --- a/packages/board/src/names.ts +++ b/packages/board/src/names.ts @@ -22,4 +22,4 @@ export { _originCtx, _watcher, _render, _parsePrivateOptions, _scroller, _initEvent, _doScrollX, _doScrollY, _doMoveScroll, _resetContext, _screen, -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/core/examples/features/css/index.css b/packages/core/examples/features/css/index.css index 4ee4a38..8a18b74 100644 --- a/packages/core/examples/features/css/index.css +++ b/packages/core/examples/features/css/index.css @@ -55,7 +55,7 @@ html, body { .elem-item { height: 32px; - width: 200px; + width: 240px; border: 1px solid #999999; border-bottom: none; line-height: 30px; diff --git a/packages/core/examples/features/lib/data/circle.js b/packages/core/examples/features/lib/data/circle.js index 3560f7a..a84ccd0 100644 --- a/packages/core/examples/features/lib/data/circle.js +++ b/packages/core/examples/features/lib/data/circle.js @@ -1,56 +1,53 @@ - const data = { // bgColor: '#ffffff', elements: [ { - name: 'rect-001', + name: "rect-001", x: 10, y: 10, w: 200, h: 100, - type: 'circle', + type: "circle", desc: { - color: '#f0f0f0', - } + color: "#f0f0f0", + }, }, { - name: 'rect-002', + name: "rect-002", x: 80, y: 80, w: 200, h: 120, // angle: 30, - type: 'rect', + type: "rect", desc: { - color: '#cccccc', - } + color: "#cccccc", + }, }, { - name: 'rect-003', + name: "rect-003", x: 160, y: 160, w: 200, h: 20, - type: 'rect', + type: "rect", angle: 80, desc: { - color: '#c0c0c0', - } + color: "#c0c0c0", + }, }, { - name: 'rect-004', + name: "rect-004", x: 400 - 10, y: 300 - 10, w: 200, h: 100, - type: 'rect', + type: "rect", desc: { - color: '#e0e0e0', - } - } - ] -} + color: "#e0e0e0", + }, + }, + ], +}; - - -export default data; \ No newline at end of file +export default data; diff --git a/packages/core/examples/features/lib/data/image.js b/packages/core/examples/features/lib/data/image.js index 2cee87f..a956aba 100644 --- a/packages/core/examples/features/lib/data/image.js +++ b/packages/core/examples/features/lib/data/image.js @@ -1,25 +1,24 @@ - const data = { // bgColor: '#ffffff', elements: [ { - name: 'image-001', + name: "image-001", x: 10, y: 10, w: 200, h: 100, - type: 'image', + type: "image", borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', + borderColor: "#bd0b64", // angle: 30, // angle: 0, desc: { - src: './../images/computer.png', - } + src: "./../images/computer.png", + }, }, { - name: 'image-002', + name: "image-002", x: 80, y: 80, w: 200, @@ -27,60 +26,58 @@ const data = { // angle: 30, borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', - type: 'image', + borderColor: "#bd0b64", + type: "image", desc: { - src: './../images/chart.png', - } + src: "./../images/chart.png", + }, }, { - name: 'image-003', + name: "image-003", x: 160, y: 160, w: 200, h: 20, - type: 'image', + type: "image", angle: 80, desc: { - src: './../images/phone.png', - } + src: "./../images/phone.png", + }, }, { - name: 'image-004', + name: "image-004", x: 400 - 10, y: 300 - 10, w: 100, h: 100, - type: 'image', + type: "image", desc: { - src: './../images/building-001.png', - } + src: "./../images/building-001.png", + }, }, { - name: 'image-004', + name: "image-004", x: 400 - 40, y: 300 - 40, w: 100, h: 100, - type: 'image', + type: "image", desc: { - src: './../images/building-002.png', - } + src: "./../images/building-002.png", + }, }, { - name: 'image-004', + name: "image-004", x: 400 - 100, y: 300 - 100, w: 100, h: 100, - type: 'image', + type: "image", desc: { - src: './../images/building-003.png', - } - } - ] -} + src: "./../images/building-003.png", + }, + }, + ], +}; - - -export default data; \ No newline at end of file +export default data; diff --git a/packages/core/examples/features/lib/data/index.js b/packages/core/examples/features/lib/data/index.js index b62a2de..d59aa25 100644 --- a/packages/core/examples/features/lib/data/index.js +++ b/packages/core/examples/features/lib/data/index.js @@ -1,19 +1,19 @@ -import dataRect from './rect.js'; -import dataImage from './image.js'; -import dataSVG from './svg.js'; -import dataText from './text.js'; +import dataRect from "./rect.js"; +import dataImage from "./image.js"; +import dataSVG from "./svg.js"; +import dataText from "./text.js"; const url = new URLSearchParams(window.location.search); const dataMap = { - 'rect': dataRect, - 'image': dataImage, - 'svg': dataSVG, - 'text': dataText -} + rect: dataRect, + image: dataImage, + svg: dataSVG, + text: dataText, +}; export function getData() { - return dataMap[getPageName()] || dataMap[url.get('data')] || dataMap['rect']; + return dataMap[getPageName()] || dataMap[url.get("data")] || dataMap["rect"]; } function getPageName() { @@ -22,16 +22,15 @@ function getPageName() { // const page = reg.exec(pathname)?.groups?.pageName || ''; // return page; - const pathname = window.location.pathname || ''; - const list = pathname.split('/'); - let pageName = list.pop() || ''; - pageName = pageName.replace(/\.html$/ig, ''); + const pathname = window.location.pathname || ""; + const list = pathname.split("/"); + let pageName = list.pop() || ""; + pageName = pageName.replace(/\.html$/gi, ""); return pageName; // return getQueryString('data') || 'rect'; } - // function getQueryString(name) { // let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); // let r = window.location.search.substr(1).match(reg); @@ -39,4 +38,4 @@ function getPageName() { // return decodeURIComponent(r[2]); // }; // return null; -// } \ No newline at end of file +// } diff --git a/packages/core/examples/features/lib/data/rect.js b/packages/core/examples/features/lib/data/rect.js index 3dd6fea..2da69f4 100644 --- a/packages/core/examples/features/lib/data/rect.js +++ b/packages/core/examples/features/lib/data/rect.js @@ -1,68 +1,66 @@ - const data = { // bgColor: '#ffffff', elements: [ { - name: 'rect-001', + name: "rect-001", x: 10, y: 10, w: 200, h: 100, - type: 'rect', + type: "rect", + lock: true, desc: { - color: '#f0f0f0', + color: "#f0f0f0", borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'rect-002', + name: "rect-002", x: 80, y: 80, w: 200, h: 120, // angle: 30, - type: 'rect', + type: "rect", desc: { - color: '#cccccc', + color: "#cccccc", borderRadius: 60, borderWidth: 10, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'rect-003', + name: "rect-003", x: 160, y: 160, w: 200, h: 20, - type: 'rect', + type: "rect", angle: 80, desc: { - color: '#c0c0c0', + color: "#c0c0c0", borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'rect-004', + name: "rect-004", x: 400 - 10, y: 300 - 10, w: 200, h: 100, - type: 'rect', + type: "rect", desc: { - color: '#e0e0e0', + color: "#e0e0e0", borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', - } - } - ] -} + borderColor: "#bd0b64", + }, + }, + ], +}; - - -export default data; \ No newline at end of file +export default data; diff --git a/packages/core/examples/features/lib/data/svg.js b/packages/core/examples/features/lib/data/svg.js index 02f29d6..71a81e4 100644 --- a/packages/core/examples/features/lib/data/svg.js +++ b/packages/core/examples/features/lib/data/svg.js @@ -1,58 +1,55 @@ - const data = { // bgColor: '#ffffff', elements: [ { - name: 'svg-001', + name: "svg-001", x: 10, y: 10, w: 200, h: 100, - type: 'svg', + type: "svg", // angle: 30, // angle: 0, desc: { svg: ``, - } + }, }, { - name: 'svg-002', + name: "svg-002", x: 80, y: 80, w: 200, h: 120, // angle: 30, - type: 'svg', + type: "svg", desc: { svg: '', - } + }, }, { - name: 'svg-003', + name: "svg-003", x: 160, y: 160, w: 200, h: 200, - type: 'svg', + type: "svg", angle: 80, desc: { svg: '', - } + }, }, { - name: 'svg-004', + name: "svg-004", x: 400 - 10, y: 300 - 100, w: 200, h: 200, - type: 'svg', + type: "svg", desc: { svg: '', - } - } - ] -} + }, + }, + ], +}; - - -export default data; \ No newline at end of file +export default data; diff --git a/packages/core/examples/features/lib/data/text.js b/packages/core/examples/features/lib/data/text.js index 0b4891a..6d8a1dc 100644 --- a/packages/core/examples/features/lib/data/text.js +++ b/packages/core/examples/features/lib/data/text.js @@ -1,80 +1,77 @@ - const data = { // bgColor: '#ffffff', elements: [ { - name: 'text-001', + name: "text-001", x: 10, y: 10, w: 200, h: 100, - type: 'text', + type: "text", desc: { fontSize: 20, - color: '#333333', - text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。', - fontFamily: '', + color: "#333333", + text: "生活就像海洋,只有意志坚强的人,才能到达彼岸。", + fontFamily: "", borderRadius: 20, borderWidth: 2, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'text-002', + name: "text-002", x: 80, y: 80, w: 200, h: 120, // angle: 30, - type: 'text', + type: "text", desc: { fontSize: 20, - text: 'Hello Text', - color: '#666666', + text: "Hello Text", + color: "#666666", borderRadius: 60, borderWidth: 10, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'text-003', + name: "text-003", x: 160, y: 160, w: 200, h: 100, - type: 'text', + type: "text", desc: { fontSize: 20, - color: '#333333', - text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。', - fontFamily: '', - textAlign: 'right', + color: "#333333", + text: "生活就像海洋,只有意志坚强的人,才能到达彼岸。", + fontFamily: "", + textAlign: "right", borderRadius: 20, borderWidth: 2, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'text-004', + name: "text-004", x: 400 - 10, y: 300 - 10, w: 200, h: 100, - type: 'text', + type: "text", desc: { fontSize: 20, - color: '#333333', - text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。', - fontFamily: '', - textAlign: 'left', + color: "#333333", + text: "生活就像海洋,只有意志坚强的人,才能到达彼岸。", + fontFamily: "", + textAlign: "left", borderRadius: 20, borderWidth: 2, - borderColor: '#bd0b64', - } - } - ] -} + borderColor: "#bd0b64", + }, + }, + ], +}; - - -export default data; \ No newline at end of file +export default data; diff --git a/packages/core/examples/features/lib/element.js b/packages/core/examples/features/lib/element.js index a050c4c..cc8085f 100644 --- a/packages/core/examples/features/lib/element.js +++ b/packages/core/examples/features/lib/element.js @@ -21,6 +21,7 @@ function renderElemens(core) { ${ele.name || 'Unnamed'} Up Down + Lock `); } diff --git a/packages/core/examples/features/lib/main.js b/packages/core/examples/features/lib/main.js index 90a64fa..440b53a 100644 --- a/packages/core/examples/features/lib/main.js +++ b/packages/core/examples/features/lib/main.js @@ -11,7 +11,7 @@ const defaultConf = { scale: 1, scrollX: 0, scrollY: 0, -} +}; const core = new Core(mount, { width: 600, height: 400, diff --git a/packages/core/examples/test/data.js b/packages/core/examples/test/data.js index a1868bc..81897c6 100644 --- a/packages/core/examples/test/data.js +++ b/packages/core/examples/test/data.js @@ -1,63 +1,62 @@ const data = { - bgColor: '#ffffff', + bgColor: "#ffffff", elements: [ { - name: 'rect-001', + name: "rect-001", x: 10, y: 10, w: 200, h: 100, - type: 'rect', + type: "rect", desc: { - color: '#f0f0f0', + color: "#f0f0f0", borderRadius: 20, borderWidth: 10, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'text-002', + name: "text-002", x: 80, y: 80, w: 200, h: 120, // angle: 30, - type: 'text', + type: "text", desc: { fontSize: 20, - text: 'Hello Text', - color: '#666666', + text: "Hello Text", + color: "#666666", borderRadius: 60, borderWidth: 2, - borderColor: '#bd0b64', - } + borderColor: "#bd0b64", + }, }, { - name: 'image-003', + name: "image-003", x: 160, y: 160, w: 200, h: 100, - type: 'image', + type: "image", desc: { src: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOgAAACqCAYAAACnOQMfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAgAElEQVR4nOy9ebylV1Xn/V17P88Z71xzhYTMZDYkAdQAioDyiiAoDbS0/dqtttptD0LLIIIi2ioBbGca7XZ4G7UVpG1FoZHRhCGQkHmokKQqNd95PtOz93r/2Pt5zrlVt5K6t+6tITm/zyepe8895zz7PGevvdb6rQn66KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz766KOPPvroo48++uijjz76OItwVHVgyfvdZ3odffTRRw9UVaZarddPdTqPzbaz2fl29rY9e/aUz/S6+ujjGY+ZVuuGqVb2uaOtjh9vZX6i43Sy43Smkz3Q8P57zvT6jsV82794upN9ZaLjPjDn/ZYzvZ4++tgULHi/Y7LZ+dB4q9OZ6Did6DidaHk/2XY60fF6tO39eDPzs233141G4+Izvd5l758913Z/Ptlsu4lW5sdb3k+0OpMz7exnnvC+eqbX93SGnOkFPJOgqumsc/8u8/rzImaL96rGiAB4FRVBBEW9qogRAKN+0VhuGTLmFmNM43Su13tfXcz8WzrKW50wgAKY/K8AGOGbieFdw9b+pYjo6VzfMwF9AT0NUFWZzrLv8cj78VxV3PW44fNdHUUVjQ8I4MUAnlR4rIx5cy2Rv91sQVBVWc70tW11t2TKRYoNi1G/YunSI6xW+UpStm8dErl1M9f2TENfQDcZc95fnnl/i3P+VV3tE/4tNrt4utrJh3+jsIrmAuwRVZLE/n3V8JaKMQ9vxnoXvL+209EPZOjLwGDwKArYKJTdhWvUouEhA95pauzHJeHnho3Zsxnre6ahL6CbBO/90Kxz73TO/3s1pgICao57ngBrUYeCx0DTJOY3Roz8qogsbsR6Z1VHXbv9HlX5N86YktEeLSng1YEITpW9E3DeiKVaBtEopBoOFw9Y1ZZY8+E0Me8dEpnciPU9U9EX0A2Gqtp5xw9nLvsvDtlZaBwF5XgBXTOitg3vq/tTI289Ff9PVZMF5/51x/n3Osw2MIh4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`, - } + }, }, { - name: 'svg-004', + name: "svg-004", x: 400 - 10, y: 300 - 100, w: 200, h: 200, - type: 'svg', + type: "svg", desc: { svg: '', - } - } - ] -} + }, + }, + ], +}; export function getData() { return data; } - diff --git a/packages/core/src/constant/element.ts b/packages/core/src/constant/element.ts index 7f44234..5d54fa5 100644 --- a/packages/core/src/constant/element.ts +++ b/packages/core/src/constant/element.ts @@ -4,7 +4,7 @@ const elementTypes = { 'rect': {}, // TODO 'image': {}, // TODO 'svg': {}, // TODO -} +}; export const elementNames = Object.keys(elementTypes); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ae68482..47f1bf1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -14,7 +14,13 @@ import { CoreEvent, TypeCoreEventArgMap } from './lib/core-event'; import { parseData } from './lib/parse'; import is, { TypeIs } from './lib/is'; import check, { TypeCheck } from './lib/check'; -import * as names from './names'; +import { + _board, _data, _opts, _config, _renderer, _element, _helper, _hasInited, + _hasInitedData, _mode, _selectedUUID, _selectedUUIDList, _prevPoint, + _selectedDotDirection, _coreEvent, _mapper, _initEvent, _handlePoint, + _handleMoveStart, _handleMove, _handleMoveEnd, _handleHover, _dragElements, + _transfromElement, _emitChangeScreen, _emitChangeData, _onlyRender, _cursorStatus, +} from './names'; import { Mode, CursorStatus } from './constant/static'; const { time } = util; @@ -23,258 +29,258 @@ const { createUUID } = util.uuid; class Core { - private [names._board]: Board; - private [names._data]: TypeData; - private [names._opts]: TypeCoreOptions; - private [names._config]: TypeConfigStrict; - private [names._renderer]: Renderer; - private [names._element]: Element; - private [names._helper]: Helper; - private [names._mapper]: Mapper; - private [names._hasInited] = false; - private [names._hasInitedData] = false; - private [names._mode]: Mode = Mode.NULL; - private [names._coreEvent]: CoreEvent = new CoreEvent(); - private [names._selectedUUID]: string | null = null; - private [names._selectedUUIDList]: string[] = []; - private [names._prevPoint]: TypePoint | null = null; - private [names._selectedDotDirection]: TypeHelperWrapperDotDirection | null = null; - private [names._onlyRender]: boolean = false; - private [names._cursorStatus]: CursorStatus = CursorStatus.NULL; + private [_board]: Board; + private [_data]: TypeData; + private [_opts]: TypeCoreOptions; + private [_config]: TypeConfigStrict; + private [_renderer]: Renderer; + private [_element]: Element; + private [_helper]: Helper; + private [_mapper]: Mapper; + private [_hasInited] = false; + private [_hasInitedData] = false; + private [_mode]: Mode = Mode.NULL; + private [_coreEvent]: CoreEvent = new CoreEvent(); + private [_selectedUUID]: string | null = null; + private [_selectedUUIDList]: string[] = []; + private [_prevPoint]: TypePoint | null = null; + private [_selectedDotDirection]: TypeHelperWrapperDotDirection | null = null; + private [_onlyRender] = false; + private [_cursorStatus]: CursorStatus = CursorStatus.NULL; static is: TypeIs = is; static check: TypeCheck = check; constructor(mount: HTMLDivElement, opts: TypeCoreOptions, config?: TypeConfig) { - this[names._data] = { elements: [] }; - this[names._opts] = opts; - this[names._onlyRender] = opts.onlyRender === true; - this[names._config] = mergeConfig(config || {}); + this[_data] = { elements: [] }; + this[_opts] = opts; + this[_onlyRender] = opts.onlyRender === true; + this[_config] = mergeConfig(config || {}); - this[names._board] = new Board(mount, { - ...this[names._opts], + this[_board] = new Board(mount, { + ...this[_opts], canScroll: config?.scrollWrapper?.use, scrollConfig: { color: config?.scrollWrapper?.color || '#a0a0a0', lineWidth: config?.scrollWrapper?.lineWidth || 12, } }); - this[names._renderer] = new Renderer(this[names._board]); - this[names._element] = new Element(this[names._board].getContext()); - this[names._helper] = new Helper(this[names._board], this[names._config]); - this[names._mapper] = new Mapper({ - board: this[names._board], - helper: this[names._helper], - element: this[names._element] + this[_renderer] = new Renderer(this[_board]); + this[_element] = new Element(this[_board].getContext()); + this[_helper] = new Helper(this[_board], this[_config]); + this[_mapper] = new Mapper({ + board: this[_board], + helper: this[_helper], + element: this[_element] }); - this[names._initEvent](); - this[names._hasInited] = true; + this[_initEvent](); + this[_hasInited] = true; } draw(): void { - const transfrom = this[names._board].getTransform(); - this[names._helper].updateConfig(this[names._data], { - width: this[names._opts].width, - height: this[names._opts].height, - canScroll: this[names._opts].canScroll === true, - selectedUUID: this[names._selectedUUID], - selectedUUIDList: this[names._selectedUUIDList], - devicePixelRatio: this[names._opts].devicePixelRatio, + const transfrom = this[_board].getTransform(); + this[_helper].updateConfig(this[_data], { + width: this[_opts].width, + height: this[_opts].height, + canScroll: this[_opts].canScroll === true, + selectedUUID: this[_selectedUUID], + selectedUUIDList: this[_selectedUUIDList], + devicePixelRatio: this[_opts].devicePixelRatio, scale: transfrom.scale, scrollX: transfrom.scrollX, scrollY: transfrom.scrollY, }); - this[names._renderer].render(this[names._data], this[names._helper].getConfig()); + this[_renderer].render(this[_data], this[_helper].getConfig()); } resetSize(opts: TypeBoardSizeOptions) { - this[names._opts] = { ...this[names._opts], ...opts }; - this[names._board].resetSize(opts); + this[_opts] = { ...this[_opts], ...opts }; + this[_board].resetSize(opts); this.draw(); } selectElement(index: number, opts?: { useMode?: boolean }): void { - if (this[names._onlyRender] === true) return; - if (this[names._data].elements[index]) { - const uuid = this[names._data].elements[index].uuid; + if (this[_onlyRender] === true) return; + if (this[_data].elements[index]) { + const uuid = this[_data].elements[index].uuid; if (opts?.useMode === true) { - this[names._mode] = Mode.SELECT_ELEMENT; + this[_mode] = Mode.SELECT_ELEMENT; } else { - this[names._mode] = Mode.NULL; + this[_mode] = Mode.NULL; } - this[names._selectedUUID] = uuid; - this[names._selectedUUIDList] = []; + this[_selectedUUID] = uuid; + this[_selectedUUIDList] = []; this.draw(); } } selectElementByUUID(uuid: string, opts?: { useMode?: boolean }): void { - if (this[names._onlyRender] === true) return; - const index = this[names._helper].getElementIndexByUUID(uuid); + if (this[_onlyRender] === true) return; + const index = this[_helper].getElementIndexByUUID(uuid); if (typeof index === 'number' && index >= 0) { this.selectElement(index, opts); } } moveDownElement(uuid: string): void { - if (this[names._onlyRender] === true) return; - const index = this[names._helper].getElementIndexByUUID(uuid); - if (typeof index === 'number' && index >= 0 && index < this[names._data].elements.length - 1) { - const temp = this[names._data].elements[index]; - this[names._data].elements[index] = this[names._data].elements[index + 1]; - this[names._data].elements[index + 1] = temp; + if (this[_onlyRender] === true) return; + const index = this[_helper].getElementIndexByUUID(uuid); + if (typeof index === 'number' && index >= 0 && index < this[_data].elements.length - 1) { + const temp = this[_data].elements[index]; + this[_data].elements[index] = this[_data].elements[index + 1]; + this[_data].elements[index + 1] = temp; } - this[names._emitChangeData](); + this[_emitChangeData](); this.draw(); } moveUpElement(uuid: string): void { - if (this[names._onlyRender] === true) return; - const index = this[names._helper].getElementIndexByUUID(uuid); - if (typeof index === 'number' && index > 0 && index < this[names._data].elements.length) { - const temp = this[names._data].elements[index]; - this[names._data].elements[index] = this[names._data].elements[index - 1]; - this[names._data].elements[index - 1] = temp; + if (this[_onlyRender] === true) return; + const index = this[_helper].getElementIndexByUUID(uuid); + if (typeof index === 'number' && index > 0 && index < this[_data].elements.length) { + const temp = this[_data].elements[index]; + this[_data].elements[index] = this[_data].elements[index - 1]; + this[_data].elements[index - 1] = temp; } - this[names._emitChangeData](); + this[_emitChangeData](); this.draw(); } scale(ratio: number): TypeScreenContext { - const screen = this[names._board].scale(ratio); - this[names._emitChangeScreen](); + const screen = this[_board].scale(ratio); + this[_emitChangeScreen](); return screen; } scrollX(x: number): TypeScreenContext { - const screen = this[names._board].scrollX(x); - this[names._emitChangeScreen](); + const screen = this[_board].scrollX(x); + this[_emitChangeScreen](); return screen; } scrollY(y: number): TypeScreenContext { - const screen = this[names._board].scrollY(y); - this[names._emitChangeScreen](); + const screen = this[_board].scrollY(y); + this[_emitChangeScreen](); return screen; } getData(): TypeData { - return deepClone(this[names._data]); + return deepClone(this[_data]); } initData(data: any | TypeData): void { - if (this[names._hasInitedData] === true) { + if (this[_hasInitedData] === true) { return; } this.setData(data); - this[names._emitChangeData](); - this[names._hasInitedData] = true; + this[_emitChangeData](); + this[_hasInitedData] = true; } setData(data: any | TypeData): void { - this[names._data] = this[names._element].initData(deepClone(parseData(data))); + this[_data] = this[_element].initData(deepClone(parseData(data))); this.draw(); } updateElement(elem: TypeElement) { - if (this[names._onlyRender] === true) return; + if (this[_onlyRender] === true) return; const _elem = deepClone(elem) as TypeElement; - const data = this[names._data]; + const data = this[_data]; for (let i = 0; i < data.elements.length; i++) { if (_elem.uuid === data.elements[i]?.uuid) { data.elements[i] = _elem; break; } } - this[names._emitChangeData](); + this[_emitChangeData](); this.draw(); } addElement(elem: TypeElement): string | null { - if (this[names._onlyRender] === true) return null; + if (this[_onlyRender] === true) return null; const _elem = deepClone(elem); _elem.uuid = createUUID(); - this[names._data].elements.unshift(_elem); - this[names._emitChangeData](); + this[_data].elements.unshift(_elem); + this[_emitChangeData](); this.draw(); return _elem.uuid; } deleteElement(uuid: string) { - if (this[names._onlyRender] === true) return; - const index = this[names._element].getElementIndex(this[names._data], uuid); + if (this[_onlyRender] === true) return; + const index = this[_element].getElementIndex(this[_data], uuid); if (index >= 0) { - this[names._data].elements.splice(index, 1); - this[names._emitChangeData](); + this[_data].elements.splice(index, 1); + this[_emitChangeData](); this.draw(); } } on(key: T, callback: (p: TypeCoreEventArgMap[T]) => void) { - this[names._coreEvent].on(key, callback); + this[_coreEvent].on(key, callback); } off(key: T, callback: (p: TypeCoreEventArgMap[T]) => void) { - this[names._coreEvent].off(key, callback); + this[_coreEvent].off(key, callback); } __getBoardContext(): TypeContext { - return this[names._board].getContext(); + return this[_board].getContext(); } __getDisplayContext(): CanvasRenderingContext2D { - return this[names._board].getDisplayContext() + return this[_board].getDisplayContext(); } __getOriginContext(): CanvasRenderingContext2D { - return this[names._board].getOriginContext() + return this[_board].getOriginContext(); } - private [names._initEvent](): void { - if (this[names._onlyRender] === true) { + private [_initEvent](): void { + if (this[_onlyRender] === true) { return; } - if (this[names._hasInited] === true) { + if (this[_hasInited] === true) { return; } - this[names._board].on('point', this[names._handlePoint].bind(this)); - this[names._board].on('moveStart', this[names._handleMoveStart].bind(this)); - this[names._board].on('move', time.throttle(this[names._handleMove].bind(this), 16)); - this[names._board].on('moveEnd', this[names._handleMoveEnd].bind(this)); - this[names._board].on('hover', time.throttle(this[names._handleHover].bind(this), 32)); + this[_board].on('point', this[_handlePoint].bind(this)); + this[_board].on('moveStart', this[_handleMoveStart].bind(this)); + this[_board].on('move', time.throttle(this[_handleMove].bind(this), 16)); + this[_board].on('moveEnd', this[_handleMoveEnd].bind(this)); + this[_board].on('hover', time.throttle(this[_handleHover].bind(this), 32)); } - private [names._handlePoint](point: TypePoint): void { - if (!this[names._mapper].isEffectivePoint(point)) { + private [_handlePoint](point: TypePoint): void { + if (!this[_mapper].isEffectivePoint(point)) { return; } - if (this[names._helper].isPointInElementList(point, this[names._data])) { + if (this[_helper].isPointInElementList(point, this[_data])) { // Coontroll Element-List - this[names._mode] = Mode.SELECT_ELEMENT_LIST; + this[_mode] = Mode.SELECT_ELEMENT_LIST; } else { - const [uuid, direction] = this[names._helper].isPointInElementWrapperDot(point); + const [uuid, direction] = this[_helper].isPointInElementWrapperDot(point); if (uuid && direction) { // Controll Element-Wrapper - this[names._mode] = Mode.SELECT_ELEMENT_WRAPPER_DOT; - this[names._selectedDotDirection] = direction; - this[names._selectedUUID] = uuid; + this[_mode] = Mode.SELECT_ELEMENT_WRAPPER_DOT; + this[_selectedDotDirection] = direction; + this[_selectedUUID] = uuid; } else { - const [index, uuid] = this[names._element].isPointInElement(point, this[names._data]); + const [index, uuid] = this[_element].isPointInElement(point, this[_data]); if (index >= 0) { // Controll Element this.selectElement(index, { useMode: true }); - if (typeof uuid === 'string' && this[names._coreEvent].has('screenSelectElement')) { - this[names._coreEvent].trigger( + if (typeof uuid === 'string' && this[_coreEvent].has('screenSelectElement')) { + this[_coreEvent].trigger( 'screenSelectElement', - { index, uuid, element: deepClone(this[names._data].elements?.[index])} + { index, uuid, element: deepClone(this[_data].elements?.[index])} ); - this[names._emitChangeScreen](); + this[_emitChangeScreen](); } - this[names._mode] = Mode.SELECT_ELEMENT; + this[_mode] = Mode.SELECT_ELEMENT; } else { // Controll Area - this[names._selectedUUIDList] = []; - this[names._mode] = Mode.SELECT_AREA; + this[_selectedUUIDList] = []; + this[_mode] = Mode.SELECT_AREA; } } } @@ -282,63 +288,63 @@ class Core { this.draw(); } - private [names._handleMoveStart](point: TypePoint): void { - this[names._prevPoint] = point; - const uuid = this[names._selectedUUID]; + private [_handleMoveStart](point: TypePoint): void { + this[_prevPoint] = point; + const uuid = this[_selectedUUID]; - if (this[names._mode] === Mode.SELECT_ELEMENT_LIST) { + if (this[_mode] === Mode.SELECT_ELEMENT_LIST) { // TODO - } else if (this[names._mode] === Mode.SELECT_ELEMENT) { - if (typeof uuid === 'string' && this[names._coreEvent].has('screenMoveElementStart')) { - this[names._coreEvent].trigger('screenMoveElementStart', { - index: this[names._element].getElementIndex(this[names._data], uuid), + } else if (this[_mode] === Mode.SELECT_ELEMENT) { + if (typeof uuid === 'string' && this[_coreEvent].has('screenMoveElementStart')) { + this[_coreEvent].trigger('screenMoveElementStart', { + index: this[_element].getElementIndex(this[_data], uuid), uuid, x: point.x, y: point.y }); } - } else if (this[names._mode] === Mode.SELECT_AREA) { - this[names._helper].startSelectArea(point); + } else if (this[_mode] === Mode.SELECT_AREA) { + this[_helper].startSelectArea(point); } } - private [names._handleMove](point: TypePoint): void { - if (this[names._mode] === Mode.SELECT_ELEMENT_LIST) { - this[names._dragElements](this[names._selectedUUIDList], point, this[names._prevPoint]); + private [_handleMove](point: TypePoint): void { + if (this[_mode] === Mode.SELECT_ELEMENT_LIST) { + this[_dragElements](this[_selectedUUIDList], point, this[_prevPoint]); this.draw(); - this[names._cursorStatus] = CursorStatus.DRAGGING; - } else if (typeof this[names._selectedUUID] === 'string') { - if (this[names._mode] === Mode.SELECT_ELEMENT) { - this[names._dragElements]([this[names._selectedUUID] as string], point, this[names._prevPoint]); + this[_cursorStatus] = CursorStatus.DRAGGING; + } else if (typeof this[_selectedUUID] === 'string') { + if (this[_mode] === Mode.SELECT_ELEMENT) { + this[_dragElements]([this[_selectedUUID] as string], point, this[_prevPoint]); this.draw(); - this[names._cursorStatus] = CursorStatus.DRAGGING; - } else if (this[names._mode] === Mode.SELECT_ELEMENT_WRAPPER_DOT && this[names._selectedDotDirection]) { - this[names._transfromElement](this[names._selectedUUID] as string, point, this[names._prevPoint], this[names._selectedDotDirection] as TypeHelperWrapperDotDirection); - this[names._cursorStatus] = CursorStatus.DRAGGING; + this[_cursorStatus] = CursorStatus.DRAGGING; + } else if (this[_mode] === Mode.SELECT_ELEMENT_WRAPPER_DOT && this[_selectedDotDirection]) { + this[_transfromElement](this[_selectedUUID] as string, point, this[_prevPoint], this[_selectedDotDirection] as TypeHelperWrapperDotDirection); + this[_cursorStatus] = CursorStatus.DRAGGING; } - } else if (this[names._mode] === Mode.SELECT_AREA) { - this[names._helper].changeSelectArea(point); + } else if (this[_mode] === Mode.SELECT_AREA) { + this[_helper].changeSelectArea(point); this.draw(); } - this[names._prevPoint] = point; + this[_prevPoint] = point; } - private [names._handleMoveEnd](point: TypePoint): void { - const uuid = this[names._selectedUUID]; + private [_handleMoveEnd](point: TypePoint): void { + const uuid = this[_selectedUUID]; if (typeof uuid === 'string') { - const index = this[names._element].getElementIndex(this[names._data], uuid); - const elem = this[names._data].elements[index]; + const index = this[_element].getElementIndex(this[_data], uuid); + const elem = this[_data].elements[index]; if (elem) { - if (this[names._coreEvent].has('screenMoveElementEnd')) { - this[names._coreEvent].trigger('screenMoveElementEnd', { + if (this[_coreEvent].has('screenMoveElementEnd')) { + this[_coreEvent].trigger('screenMoveElementEnd', { index, uuid, x: point.x, y: point.y }); } - if (this[names._coreEvent].has('screenChangeElement')) { - this[names._coreEvent].trigger('screenChangeElement', { + if (this[_coreEvent].has('screenChangeElement')) { + this[_coreEvent].trigger('screenChangeElement', { index, uuid, width: elem.w, @@ -346,45 +352,45 @@ class Core { angle: elem.angle || 0 }); } - this[names._emitChangeData](); + this[_emitChangeData](); } - } else if (this[names._mode] === Mode.SELECT_AREA) { - const uuids = this[names._helper].calcSelectedElements(this[names._data]); + } else if (this[_mode] === Mode.SELECT_AREA) { + const uuids = this[_helper].calcSelectedElements(this[_data]); if (uuids.length > 0) { - this[names._selectedUUIDList] = uuids; - this[names._selectedUUID] = null; + this[_selectedUUIDList] = uuids; + this[_selectedUUID] = null; } else { - this[names._mode] = Mode.NULL; + this[_mode] = Mode.NULL; } - this[names._helper].clearSelectedArea(); + this[_helper].clearSelectedArea(); this.draw(); } - this[names._selectedUUID] = null; - this[names._prevPoint] = null; - this[names._cursorStatus] = CursorStatus.NULL; - this[names._mode] = Mode.NULL; + this[_selectedUUID] = null; + this[_prevPoint] = null; + this[_cursorStatus] = CursorStatus.NULL; + this[_mode] = Mode.NULL; } - private [names._handleHover](point: TypePoint): void { - if (this[names._mode] === Mode.SELECT_AREA) { - this[names._board].resetCursor(); - } else if (this[names._cursorStatus] === CursorStatus.NULL) { - const cursor = this[names._mapper].judgePointCursor(point, this[names._data]); - this[names._board].setCursor(cursor); + private [_handleHover](point: TypePoint): void { + if (this[_mode] === Mode.SELECT_AREA) { + this[_board].resetCursor(); + } else if (this[_cursorStatus] === CursorStatus.NULL) { + const cursor = this[_mapper].judgePointCursor(point, this[_data]); + this[_board].setCursor(cursor); } } - private [names._dragElements](uuids: string[], point: TypePoint, prevPoint: TypePoint|null): void { + private [_dragElements](uuids: string[], point: TypePoint, prevPoint: TypePoint|null): void { if (!prevPoint) { return; } uuids.forEach((uuid) => { - this[names._element].dragElement(this[names._data], uuid, point, prevPoint, this[names._board].getContext().getTransform().scale); - }) + this[_element].dragElement(this[_data], uuid, point, prevPoint, this[_board].getContext().getTransform().scale); + }); this.draw(); } - private [names._transfromElement]( + private [_transfromElement]( uuid: string, point: TypePoint, prevPoint: TypePoint|null, direction: TypeHelperWrapperDotDirection ): null | { width: number, @@ -394,25 +400,25 @@ class Core { if (!prevPoint) { return null; } - const result = this[names._element].transformElement(this[names._data], uuid, point, prevPoint, this[names._board].getContext().getTransform().scale, direction); + const result = this[_element].transformElement(this[_data], uuid, point, prevPoint, this[_board].getContext().getTransform().scale, direction); this.draw(); return result; } - private [names._emitChangeScreen]() { - if (this[names._coreEvent].has('changeScreen')) { - this[names._coreEvent].trigger('changeScreen', { - ...this[names._board].getTransform(), + private [_emitChangeScreen]() { + if (this[_coreEvent].has('changeScreen')) { + this[_coreEvent].trigger('changeScreen', { + ...this[_board].getTransform(), ...{ - selectedElementUUID: this[names._selectedUUID] + selectedElementUUID: this[_selectedUUID] } - }) + }); } } - private [names._emitChangeData]() { - if (this[names._coreEvent].has('changeData')) { - this[names._coreEvent].trigger('changeData', deepClone(this[names._data])); + private [_emitChangeData]() { + if (this[_coreEvent].has('changeData')) { + this[_coreEvent].trigger('changeData', deepClone(this[_data])); } } } diff --git a/packages/core/src/lib/check.ts b/packages/core/src/lib/check.ts index 4663ff9..f424860 100644 --- a/packages/core/src/lib/check.ts +++ b/packages/core/src/lib/check.ts @@ -102,7 +102,7 @@ const check = { imageDesc, svgDesc, textDesc, -} +}; type TypeCheck = { attrs: (value: any) => boolean, @@ -114,6 +114,6 @@ type TypeCheck = { export { TypeCheck -} +}; export default check; \ No newline at end of file diff --git a/packages/core/src/lib/draw/base.ts b/packages/core/src/lib/draw/base.ts index 57e90cd..a21aadb 100644 --- a/packages/core/src/lib/draw/base.ts +++ b/packages/core/src/lib/draw/base.ts @@ -61,8 +61,8 @@ export function drawBoxBorder( if (!(elem.desc.borderWidth && elem.desc.borderWidth > 0)) { return; } - let bw = elem.desc.borderWidth; - let borderColor: string = '#000000'; + const bw = elem.desc.borderWidth; + let borderColor = '#000000'; if (color.isColorStr(elem.desc.borderColor) === true) { borderColor = elem.desc.borderColor as string; } @@ -74,11 +74,11 @@ export function drawBoxBorder( let r: number = elem.desc.borderRadius || 0; r = Math.min(r, w / 2, h / 2); if (r < w / 2 && r < h / 2) { - r = r + bw / 2 + r = r + bw / 2; } ctx.beginPath(); ctx.setLineWidth(bw); - ctx.setStrokeStyle(borderColor) + ctx.setStrokeStyle(borderColor); ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r); @@ -86,5 +86,5 @@ export function drawBoxBorder( ctx.arcTo(x, y, x + w, y, r); ctx.closePath(); ctx.stroke(); - }) + }); } \ No newline at end of file diff --git a/packages/core/src/lib/draw/text.ts b/packages/core/src/lib/draw/text.ts index 8b49168..cf7e960 100644 --- a/packages/core/src/lib/draw/text.ts +++ b/packages/core/src/lib/draw/text.ts @@ -70,7 +70,7 @@ export function drawText( lines.forEach((line, i) => { let _x = elem.x; if (desc.textAlign === 'center') { - _x = elem.x + (elem.w - line.width) / 2 + _x = elem.x + (elem.w - line.width) / 2; } else if (desc.textAlign === 'right') { _x = elem.x + (elem.w - line.width); } diff --git a/packages/core/src/lib/draw/wrapper.ts b/packages/core/src/lib/draw/wrapper.ts index c922011..4f79942 100644 --- a/packages/core/src/lib/draw/wrapper.ts +++ b/packages/core/src/lib/draw/wrapper.ts @@ -116,6 +116,6 @@ export function drawElementListWrappers(ctx: TypeContext, config: TypeHelperConf ctx.stroke(); ctx.closePath(); }); - }) + }); } diff --git a/packages/core/src/lib/element.ts b/packages/core/src/lib/element.ts index 5b7522a..421e97c 100644 --- a/packages/core/src/lib/element.ts +++ b/packages/core/src/lib/element.ts @@ -174,7 +174,7 @@ export class Element { width: limitNum(elem.w), height: limitNum(elem.h), angle: limitAngle(elem.angle || 0), - } + }; } getElementIndex(data: TypeData, uuid: string): number { diff --git a/packages/core/src/lib/helper.ts b/packages/core/src/lib/helper.ts index 0bf9d23..bf15cb4 100644 --- a/packages/core/src/lib/helper.ts +++ b/packages/core/src/lib/helper.ts @@ -191,10 +191,10 @@ export class Helper implements TypeHelper { endPoint: {x: end.x, y: end.y}, lineWidth: areaLineWidth / scale, lineDash: areaLineDash.map((num) => { - return num / scale + return num / scale; }), color: areaColor, - } + }; } private _updateElementIndex(data: TypeData) { diff --git a/packages/core/src/lib/is.ts b/packages/core/src/lib/is.ts index 4d9dc9f..46f3357 100644 --- a/packages/core/src/lib/is.ts +++ b/packages/core/src/lib/is.ts @@ -5,7 +5,7 @@ const { isColorStr } = util.color; function number(value: any) { - return (typeof value === 'number' && (value > 0 || value <= 0)) + return (typeof value === 'number' && (value > 0 || value <= 0)); } function x(value: any) { @@ -17,15 +17,15 @@ function y(value: any) { } function w(value: any) { - return (typeof value === 'number' && value >= 0) + return (typeof value === 'number' && value >= 0); } function h(value: any) { - return (typeof value === 'number' && value >= 0) + return (typeof value === 'number' && value >= 0); } function angle(value: any) { - return (typeof value === 'number' && value >= -360 && value <= 360) + return (typeof value === 'number' && value >= -360 && value <= 360); } function borderWidth(value: any) { @@ -41,15 +41,15 @@ function color(value: any) { } function imageURL(value: any) { - return (typeof value === 'string' && /^(http:\/\/|https:\/\/|\.\/|\/)/.test(`${value}`)) + return (typeof value === 'string' && /^(http:\/\/|https:\/\/|\.\/|\/)/.test(`${value}`)); } function imageBase64(value: any) { - return (typeof value === 'string' && /^(data:image\/)/.test(`${value}`)) + return (typeof value === 'string' && /^(data:image\/)/.test(`${value}`)); } function imageSrc(value: any) { - return (imageBase64(value) || imageURL(value)) + return (imageBase64(value) || imageURL(value)); } function svg(value: any) { @@ -81,7 +81,7 @@ const is: TypeIs = { borderWidth, borderRadius, color, imageSrc, imageURL, imageBase64, svg, text, fontSize, lineHeight, textAlign, fontFamily, -} +}; type TypeIs = { x: (value: any) => boolean, @@ -109,4 +109,4 @@ export default is; export { TypeIs, -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/core/src/lib/loader.ts b/packages/core/src/lib/loader.ts index b7d1a26..fb99f1b 100644 --- a/packages/core/src/lib/loader.ts +++ b/packages/core/src/lib/loader.ts @@ -47,7 +47,7 @@ export default class Loader { this._waitingLoadQueue.push({ uuidQueue, loadData, - }) + }); } } @@ -148,7 +148,7 @@ export default class Loader { private _createEmptyLoadItem(elem: TypeElement): TypeLoadData[string] { let source = ''; - let type: TypeLoadData[string]['type'] = elem.type as TypeLoadData[string]['type']; + const type: TypeLoadData[string]['type'] = elem.type as TypeLoadData[string]['type']; if (elem.type === 'image') { const _elem = elem as TypeElement<'image'>; source = _elem.desc.src || ''; @@ -163,7 +163,7 @@ export default class Loader { source, elemW: elem.w, elemH: elem.h, - } + }; } private _loadTask() { @@ -206,7 +206,7 @@ export default class Loader { for (let i = loadUUIDList.length; i < maxParallelNum; i++) { const uuid = uuids.shift(); if (uuid === undefined) { - break + break; } loadUUIDList.push(uuid); @@ -221,7 +221,7 @@ export default class Loader { 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; @@ -248,7 +248,7 @@ export default class Loader { 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; @@ -261,12 +261,12 @@ export default class Loader { source: this._storageLoadData[uuid].source, elemW: this._storageLoadData[uuid].elemW, elemH: this._storageLoadData[uuid].elemH, - }) - }) + }); + }); } return false; - } + }; _loadAction(); } @@ -284,7 +284,7 @@ export default class Loader { ); return image; } - throw Error('Element\'s source is not support!') + throw Error('Element\'s source is not support!'); } } diff --git a/packages/core/src/lib/parse.ts b/packages/core/src/lib/parse.ts index 269d4f9..73619c1 100644 --- a/packages/core/src/lib/parse.ts +++ b/packages/core/src/lib/parse.ts @@ -32,5 +32,5 @@ function isElement( function isNumber(num: any) { - return (num >= 0 || num < 0) + return (num >= 0 || num < 0); } \ No newline at end of file diff --git a/packages/core/src/lib/renderer.ts b/packages/core/src/lib/renderer.ts index 4ef1cee..436fa2c 100644 --- a/packages/core/src/lib/renderer.ts +++ b/packages/core/src/lib/renderer.ts @@ -34,7 +34,7 @@ export class Renderer { }); this._loader.on('complete', (res) => { // console.log('complete: ', res); - }) + }); } render(data: TypeData, helper: TypeHelperConfig): void { @@ -77,7 +77,7 @@ export class Renderer { } else { this._status = DrawStatus.FREE; } - }) + }); } private _retainQueueOneItem() { diff --git a/packages/core/src/names.ts b/packages/core/src/names.ts index a77204d..58ca0d3 100644 --- a/packages/core/src/names.ts +++ b/packages/core/src/names.ts @@ -33,4 +33,4 @@ export { _selectedDotDirection, _coreEvent, _mapper, _initEvent, _handlePoint, _handleMoveStart, _handleMove, _handleMoveEnd, _handleHover, _dragElements, _transfromElement, _emitChangeScreen, _emitChangeData, _onlyRender, _cursorStatus, -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/idraw/src/index.ts b/packages/idraw/src/index.ts index 1c320d2..91ea752 100644 --- a/packages/idraw/src/index.ts +++ b/packages/idraw/src/index.ts @@ -85,15 +85,15 @@ class IDraw extends Core { if (this[_doRecords].length >= this[_opts].maxRecords) { this[_doRecords].shift(); } - this[_doRecords].push({ data, time: Date.now() }) + this[_doRecords].push({ data, time: Date.now() }); this[_unDoRecords] = []; } private _createOpts(opts: Options): PrivateOptions { const defaultOpts = { maxRecords: 10, - } - return { ...defaultOpts, ...opts } + }; + return { ...defaultOpts, ...opts }; } } diff --git a/packages/types/src/lib/core.ts b/packages/types/src/lib/core.ts index 3daaea2..b05a7d6 100644 --- a/packages/types/src/lib/core.ts +++ b/packages/types/src/lib/core.ts @@ -11,4 +11,4 @@ type TypeCoreOptions = { export { TypeCoreOptions -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/types/src/lib/device.ts b/packages/types/src/lib/device.ts index 3c76278..1005fd3 100644 --- a/packages/types/src/lib/device.ts +++ b/packages/types/src/lib/device.ts @@ -7,4 +7,4 @@ type TypeDeviceSize = { export { TypeDeviceSize, -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/types/src/lib/screen.ts b/packages/types/src/lib/screen.ts index c81fcc8..89ac700 100644 --- a/packages/types/src/lib/screen.ts +++ b/packages/types/src/lib/screen.ts @@ -29,4 +29,4 @@ export { TypeScreenPosition, TypeScreenSize, TypeScreenContext, -} \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/util/src/lib/loader.ts b/packages/util/src/lib/loader.ts index 55769b4..13578ec 100644 --- a/packages/util/src/lib/loader.ts +++ b/packages/util/src/lib/loader.ts @@ -40,11 +40,11 @@ export function loadSVG(svg: string, opts?: { width: number, height: number }): const base64: string = event?.target?.result as string; image.onload = function() { resolve(image); - } + }; image.src = base64; }; reader.onerror = function(err) { reject(err); }; - }) + }); } \ No newline at end of file