From c9203aef7fdf9b2dcccd806fbea0e47c1575ccc0 Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Thu, 27 May 2021 15:39:55 +0800 Subject: [PATCH] feat: core add element's wrapper render --- packages/board/src/index.ts | 4 ++ packages/board/src/util/context.ts | 10 ++++- packages/core/example/main.js | 12 ++++-- packages/core/src/index.ts | 11 +++++- packages/core/src/lib/draw.ts | 29 +++++++++++++- packages/core/src/lib/helper.ts | 62 ++++++++++++++++++++++++++++-- packages/core/src/lib/renderer.ts | 4 +- packages/types/src/lib/board.ts | 2 + packages/types/src/lib/helper.ts | 18 ++++++--- 9 files changed, 132 insertions(+), 20 deletions(-) diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts index 34b5c16..6fd7778 100644 --- a/packages/board/src/index.ts +++ b/packages/board/src/index.ts @@ -67,6 +67,10 @@ class Board { } } + getTransform() { + return this._ctx.getTransform(); + } + draw() { this.clear(); const size = this._calculateSize(); diff --git a/packages/board/src/util/context.ts b/packages/board/src/util/context.ts index f555050..e7ca815 100644 --- a/packages/board/src/util/context.ts +++ b/packages/board/src/util/context.ts @@ -91,8 +91,16 @@ class Context implements TypeContext { return this._ctx.lineTo(this._doSize(x), this._doSize(y)); } + moveTo(x: number, y: number) { + return this._ctx.moveTo(this._doSize(x), this._doSize(y)); + } + setLineWidth(w: number) { - this._ctx.lineWidth = w; + return this._ctx.lineWidth = this._doSize(w); + } + + setLineDash(nums: number[]) { + return this._ctx.setLineDash(nums.map(n => this._doSize(n))); } isPointInPath(x: number, y: number) { diff --git a/packages/core/example/main.js b/packages/core/example/main.js index 7e1d58f..a8220a8 100644 --- a/packages/core/example/main.js +++ b/packages/core/example/main.js @@ -5,10 +5,16 @@ import { doScroll } from './lib/scroll.js'; const { Core } = window.iDraw; const mount = document.querySelector('#mount'); +// const defaultConf = { +// scale: 0.8, +// scrollX: 100, +// scrollY: 50, +// } + const defaultConf = { - scale: 0.5, - scrollX: 100, - scrollY: 200, + scale: 1, + scrollX: 0, + scrollY: 0, } const core = new Core(mount, { width: 600, diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 72e0842..50f78e8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -42,11 +42,17 @@ class Core { } draw() { - this._helper.updateConfig(this._data, { selectedUUID: this._selectedUUID }); + this._helper.updateConfig(this._data, { + selectedUUID: this._selectedUUID, + devicePixelRatio: this._opts.devicePixelRatio, + scale: this._board.getTransform().scale // TODO + }); this._renderer.render(this._data, this._helper.getConfig()); } + // TODO selectElement(index: number) { + // TODO console.log('index'); } @@ -84,7 +90,8 @@ class Core { const [index, uuid] = this._element.isPointInElement(point, this._data); if (index >= 0) { this._mode = Mode.SELECT_ELEMENT; - this._selectedUUID = uuid + this._selectedUUID = uuid; + this.draw(); } } diff --git a/packages/core/src/lib/draw.ts b/packages/core/src/lib/draw.ts index ba8575f..3dcf2fd 100644 --- a/packages/core/src/lib/draw.ts +++ b/packages/core/src/lib/draw.ts @@ -1,9 +1,15 @@ -import { TypeContext, TypeData, TypeElement, TypeElemDesc } from '@idraw/types'; +import { + TypeContext, + TypeData, + TypeElement, + TypeElemDesc, + TypeHelperConfig, +} from '@idraw/types'; import util from './../util'; const { isColorStr } = util.color; -export function drawContext(ctx: TypeContext, data: TypeData) { +export function drawContext(ctx: TypeContext, data: TypeData, config: TypeHelperConfig) { if (typeof data.bgColor === 'string' && isColorStr(data.bgColor)) { drawBgColor(ctx, data.bgColor); } @@ -17,6 +23,7 @@ export function drawContext(ctx: TypeContext, data: TypeData) { // nothing } } + drawElementWrapper(ctx, ele.uuid, config); } } @@ -31,4 +38,22 @@ function drawBgColor(ctx: TypeContext, color: string) { const size = ctx.getSize(); ctx.setFillStyle(color); ctx.fillRect(0, 0, size.width, size.height); +} + +function drawElementWrapper(ctx: TypeContext, uuid: string, config: TypeHelperConfig) { + if (uuid !== config?.selectedElementWrapper?.uuid) { + return; + } + const wrapper = config.selectedElementWrapper; + ctx.beginPath(); + ctx.setLineDash(wrapper.lineDash); + ctx.setLineWidth(wrapper.lineWidth); + ctx.setStrokeStyle(wrapper.color); + ctx.moveTo(wrapper.topLeft.x, wrapper.topLeft.y); + ctx.lineTo(wrapper.topRight.x, wrapper.topRight.y); + ctx.lineTo(wrapper.bottomRight.x, wrapper.bottomRight.y); + ctx.lineTo(wrapper.bottomLeft.x, wrapper.bottomLeft.y); + ctx.lineTo(wrapper.topLeft.x, wrapper.topLeft.y - wrapper.lineWidth / 2); + ctx.stroke(); + ctx.closePath(); } \ No newline at end of file diff --git a/packages/core/src/lib/helper.ts b/packages/core/src/lib/helper.ts index ad45fa4..e6c05cd 100644 --- a/packages/core/src/lib/helper.ts +++ b/packages/core/src/lib/helper.ts @@ -2,7 +2,7 @@ import { TypeData, TypeHelper, TypeHelperConfig, - TypeHelperCreateOpts, + TypeHelperUpdateOpts, TypeElement, TypeElemDesc } from '@idraw/types'; @@ -19,8 +19,9 @@ export class Helper implements TypeHelper { updateConfig ( data: TypeData, - opts: TypeHelperCreateOpts ) { + opts: TypeHelperUpdateOpts ) { this._updateElementIndex(data); + this._updateSelectedElementWrapper(data, opts); } getConfig() { @@ -35,7 +36,60 @@ export class Helper implements TypeHelper { }); } - // private _updateSelectedElementWrapper() { + private _updateSelectedElementWrapper(data: TypeData, opts: TypeHelperUpdateOpts) { + const { selectedUUID: uuid, scale } = opts; + if (!(typeof uuid === 'string' && this._config.elementIndexMap[uuid] >= 0)) { + delete this._config.selectedElementWrapper; + return; + } + const index: number = this._config.elementIndexMap[uuid]; + const elem = data.elements[index]; - // } + // TODO + const dotSize = 4 / Math.min(1, scale); + const lineWidth = 1 / Math.min(1, scale); + const lineDash = [4, 2].map(n => (n / Math.min(1, scale))) + + const wrapper = { + uuid, + dotSize: dotSize, + lineWidth: lineWidth, + lineDash: lineDash, + color: '#2ab6f1', + topLeft: { + x: elem.x - dotSize, + y: elem.y - dotSize, + }, + top: { + x: elem.x + elem.w / 2, + y: elem.y - dotSize, + }, + topRight: { + x: elem.x + elem.w + dotSize, + y: elem.y - dotSize, + }, + right: { + x: elem.x + elem.w + dotSize, + y: elem.y + elem.h / 2, + }, + bottomRight: { + x: elem.x + elem.w + dotSize, + y: elem.y + elem.h + dotSize, + }, + bottom: { + x: elem.x + elem.w / 2, + y: elem.y + elem.h / 2 + dotSize, + }, + bottomLeft: { + x: elem.x - dotSize, + y: elem.y + elem.h + dotSize, + }, + left: { + x: elem.x + dotSize, + y: elem.y + elem.h / 2 - dotSize, + }, + } + this._config.selectedElementWrapper = wrapper; + + } } \ No newline at end of file diff --git a/packages/core/src/lib/renderer.ts b/packages/core/src/lib/renderer.ts index 647bdb3..c71e943 100644 --- a/packages/core/src/lib/renderer.ts +++ b/packages/core/src/lib/renderer.ts @@ -13,9 +13,9 @@ export default class Renderer { this._ctx = this._board.getContext(); } - render(data: TypeData, config?: TypeHelperConfig) { + render(data: TypeData, config: TypeHelperConfig) { this._data = data; - drawContext(this._ctx, this._data); + drawContext(this._ctx, this._data, config); this._board.draw(); } } \ No newline at end of file diff --git a/packages/types/src/lib/board.ts b/packages/types/src/lib/board.ts index cb8463d..8450b0f 100644 --- a/packages/types/src/lib/board.ts +++ b/packages/types/src/lib/board.ts @@ -24,8 +24,10 @@ interface TypeContext { clearRect(x: number, y: number, w: number, h: number): void; beginPath(): void; closePath(): void; + moveTo(x: number, y: number): void; lineTo(x: number, y: number): void; setLineWidth(w: number): void; + setLineDash(nums: number[]): void; isPointInPath(x: number, y: number): boolean; setStrokeStyle(color: string): void; stroke(): void; diff --git a/packages/types/src/lib/helper.ts b/packages/types/src/lib/helper.ts index 312c9e1..d8ca046 100644 --- a/packages/types/src/lib/helper.ts +++ b/packages/types/src/lib/helper.ts @@ -4,9 +4,13 @@ import { TypePoint } from './board'; // type test = {[uuid string]: TypeElement} type TypeHelperConfig = { - elementIndexMap: {[key: string]: Number}, + elementIndexMap: {[key: string]: number}, selectedElementWrapper?: { - size: number; + uuid: string; + dotSize: number; + lineDash: number[]; + lineWidth: number; + color: string; topLeft: TypePoint, top: TypePoint, topRight: TypePoint, @@ -18,14 +22,16 @@ type TypeHelperConfig = { } } -type TypeHelperCreateOpts = { - selectedUUID?: string | null, +type TypeHelperUpdateOpts = { + selectedUUID?: string | null; + devicePixelRatio: number; + scale: number; } interface TypeHelper { updateConfig( data: TypeData, - opts: TypeHelperCreateOpts + opts: TypeHelperUpdateOpts ): void; getConfig(): TypeHelperConfig; } @@ -33,5 +39,5 @@ interface TypeHelper { export { TypeHelper, TypeHelperConfig, - TypeHelperCreateOpts, + TypeHelperUpdateOpts, } \ No newline at end of file