diff --git a/lerna.json b/lerna.json index d34e2d45e..97587f84f 100644 --- a/lerna.json +++ b/lerna.json @@ -6,5 +6,5 @@ "packages/core", "packages/idraw" ], - "version": "0.1.1" + "version": "0.1.2" } diff --git a/packages/board/package.json b/packages/board/package.json index 74d5b4c45..18f673bc3 100644 --- a/packages/board/package.json +++ b/packages/board/package.json @@ -1,6 +1,6 @@ { "name": "@idraw/board", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "dist/index.cjs.js", "module": "dist/index.es.js", @@ -23,10 +23,10 @@ "author": "chenshenhai", "license": "MIT", "devDependencies": { - "@idraw/types": "^0.1.1" + "@idraw/types": "^0.1.2" }, "dependencies": { - "@idraw/util": "^0.1.1" + "@idraw/util": "^0.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/core/examples/features/lib/main.js b/packages/core/examples/features/lib/main.js index a2f8f5d8f..2b45cff8d 100644 --- a/packages/core/examples/features/lib/main.js +++ b/packages/core/examples/features/lib/main.js @@ -18,6 +18,7 @@ const core = new Core(mount, { contextWidth: 600, contextHeight: 400, devicePixelRatio: 4, + onlyRender: true, }, { scrollWrapper: { use: true, @@ -46,6 +47,13 @@ core.on('changeScreen', (data) => { core.on('screenSelectElement', (data) => { console.log('screenSelectElement: ', data); }); +core.on('mouseOverElement', (data) => { + console.log('mouseOverElement: ', data); +}); +core.on('mouseLeaveElement', (data) => { + console.log('mouseLeaveElement: ', data); +}); + core.on('screenMoveElementStart', (data) => { console.log('screenMoveElementStart: ', data); }); diff --git a/packages/core/examples/features/lib/scale.js b/packages/core/examples/features/lib/scale.js index b41354b6b..5be9e2b0f 100644 --- a/packages/core/examples/features/lib/scale.js +++ b/packages/core/examples/features/lib/scale.js @@ -10,9 +10,9 @@ export function doScale(core, scale) { } input.addEventListener('change', () => { const val = input.value * 1; - console.log('scale ===', val); if (val > 0) { core.scale(val); + console.log(core.getScreenTransform()); } }); hasInited = true; diff --git a/packages/core/examples/features/lib/scroll.js b/packages/core/examples/features/lib/scroll.js index 1ed6c4dbe..73c9942c1 100644 --- a/packages/core/examples/features/lib/scroll.js +++ b/packages/core/examples/features/lib/scroll.js @@ -20,12 +20,14 @@ export function doScroll(core, conf = {}) { const val = inputX.value * 1; if (val >= 0 || val < 0) { core.scrollLeft(val); + console.log(core.getScreenTransform()); } }); inputY.addEventListener('change', () => { const val = inputY.value * 1; if (val >= 0 || val < 0) { core.scrollTop(val); + console.log(core.getScreenTransform()); } }); hasInited = true; diff --git a/packages/core/package.json b/packages/core/package.json index eeb5592ca..56f3f17c6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@idraw/core", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "dist/index.cjs.js", "module": "dist/index.es.js", @@ -23,11 +23,11 @@ "author": "chenshenhai", "license": "MIT", "devDependencies": { - "@idraw/types": "^0.1.1" + "@idraw/types": "^0.1.2" }, "dependencies": { - "@idraw/board": "^0.1.1", - "@idraw/util": "^0.1.1" + "@idraw/board": "^0.1.2", + "@idraw/util": "^0.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b7baf329a..63ef502ab 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,7 +1,7 @@ import { TypeData, TypePoint, TypeBoardSizeOptions, TypeHelperWrapperDotDirection, TypeConfig, TypeConfigStrict, TypeElementBase, - TypeElement, TypeElemDesc, TypeContext, TypeCoreOptions, TypeScreenContext, + TypeElement, TypeElemDesc, TypeContext, TypeCoreOptions, TypeScreenContext, TypeScreenData, } from '@idraw/types'; import Board from '@idraw/board'; import util from '@idraw/util'; @@ -14,9 +14,10 @@ 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 { TempData } from './lib/temp'; import { _board, _data, _opts, _config, _renderer, _element, _helper, _hasInited, - _mode, _selectedUUID, _selectedUUIDList, _prevPoint, _draw, + _mode, _tempData, _prevPoint, _draw, _selectedDotDirection, _coreEvent, _mapper, _initEvent, _handlePoint, _handleMoveStart, _handleMove, _handleMoveEnd, _handleHover, _dragElements, _transfromElement, _emitChangeScreen, _emitChangeData, _onlyRender, _cursorStatus, @@ -40,8 +41,7 @@ class Core { private [_hasInited] = false; private [_mode]: Mode = Mode.NULL; private [_coreEvent]: CoreEvent = new CoreEvent(); - private [_selectedUUID]: string | null = null; - private [_selectedUUIDList]: string[] = []; + private [_tempData]: TempData; private [_prevPoint]: TypePoint | null = null; private [_selectedDotDirection]: TypeHelperWrapperDotDirection | null = null; private [_onlyRender] = false; @@ -55,7 +55,7 @@ class Core { this[_opts] = opts; this[_onlyRender] = opts.onlyRender === true; this[_config] = mergeConfig(config || {}); - + this[_tempData] = new TempData(); this[_board] = new Board(mount, { ...this[_opts], canScroll: config?.scrollWrapper?.use, @@ -82,8 +82,8 @@ class Core { width: this[_opts].width, height: this[_opts].height, canScroll: this[_config]?.scrollWrapper?.use === true, - selectedUUID: this[_selectedUUID], - selectedUUIDList: this[_selectedUUIDList], + selectedUUID: this[_tempData].get('selectedUUID'), + selectedUUIDList: this[_tempData].get('selectedUUIDList'), devicePixelRatio: this[_opts].devicePixelRatio, scale: transfrom.scale, scrollX: transfrom.scrollX, @@ -108,8 +108,8 @@ class Core { this[_mode] = Mode.NULL; } if (typeof uuid === 'string') { - this[_selectedUUID] = uuid; - this[_selectedUUIDList] = []; + this[_tempData].set('selectedUUID', uuid); + this[_tempData].set('selectedUUIDList', []); } this[_draw](); } @@ -168,6 +168,15 @@ class Core { return screen; } + getScreenTransform(): TypeScreenData { + const transform = this[_board].getTransform(); + return { + scale: transform.scale, + scrollTop: Math.max(0, 0 - transform.scrollY), + scrollLeft: Math.max(0, 0 - transform.scrollX), + } + } + getData(): TypeData { return deepClone(this[_data]); } @@ -243,17 +252,18 @@ class Core { } private [_initEvent](): void { - if (this[_onlyRender] === true) { + if (this[_hasInited] === true) { return; } - if (this[_hasInited] === true) { + + this[_board].on('hover', time.throttle(this[_handleHover].bind(this), 32)); + if (this[_onlyRender] === true) { return; } 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 [_handlePoint](point: TypePoint): void { @@ -269,7 +279,7 @@ class Core { // Controll Element-Wrapper this[_mode] = Mode.SELECT_ELEMENT_WRAPPER_DOT; this[_selectedDotDirection] = direction; - this[_selectedUUID] = uuid; + this[_tempData].set('selectedUUID', uuid); } else { const [index, uuid] = this[_element].isPointInElement(point, this[_data]); if (index >= 0) { @@ -285,7 +295,7 @@ class Core { this[_mode] = Mode.SELECT_ELEMENT; } else { // Controll Area - this[_selectedUUIDList] = []; + this[_tempData].set('selectedUUIDList', []); this[_mode] = Mode.SELECT_AREA; } } @@ -296,7 +306,7 @@ class Core { private [_handleMoveStart](point: TypePoint): void { this[_prevPoint] = point; - const uuid = this[_selectedUUID]; + const uuid = this[_tempData].get('selectedUUID'); if (this[_mode] === Mode.SELECT_ELEMENT_LIST) { // TODO @@ -316,16 +326,16 @@ class Core { private [_handleMove](point: TypePoint): void { if (this[_mode] === Mode.SELECT_ELEMENT_LIST) { - this[_dragElements](this[_selectedUUIDList], point, this[_prevPoint]); + this[_dragElements](this[_tempData].get('selectedUUIDList'), point, this[_prevPoint]); this[_draw](); this[_cursorStatus] = CursorStatus.DRAGGING; - } else if (typeof this[_selectedUUID] === 'string') { + } else if (typeof this[_tempData].get('selectedUUID') === 'string') { if (this[_mode] === Mode.SELECT_ELEMENT) { - this[_dragElements]([this[_selectedUUID] as string], point, this[_prevPoint]); + this[_dragElements]([this[_tempData].get('selectedUUID') as string], point, this[_prevPoint]); this[_draw](); 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[_transfromElement](this[_tempData].get('selectedUUID') as string, point, this[_prevPoint], this[_selectedDotDirection] as TypeHelperWrapperDotDirection); this[_cursorStatus] = CursorStatus.DRAGGING; } } else if (this[_mode] === Mode.SELECT_AREA) { @@ -336,7 +346,7 @@ class Core { } private [_handleMoveEnd](point: TypePoint): void { - const uuid = this[_selectedUUID]; + const uuid = this[_tempData].get('selectedUUID'); if (typeof uuid === 'string') { const index = this[_element].getElementIndex(this[_data], uuid); const elem = this[_data].elements[index]; @@ -363,26 +373,45 @@ class Core { } else if (this[_mode] === Mode.SELECT_AREA) { const uuids = this[_helper].calcSelectedElements(this[_data]); if (uuids.length > 0) { - this[_selectedUUIDList] = uuids; - this[_selectedUUID] = null; + this[_tempData].set('selectedUUIDList', uuids); + this[_tempData].set('selectedUUID', null); } else { this[_mode] = Mode.NULL; } this[_helper].clearSelectedArea(); this[_draw](); } - this[_selectedUUID] = null; + this[_tempData].set('selectedUUID', null); this[_prevPoint] = null; this[_cursorStatus] = CursorStatus.NULL; this[_mode] = Mode.NULL; } private [_handleHover](point: TypePoint): void { + let isMouseOverElement: boolean = false; + if (this[_mode] === Mode.SELECT_AREA) { - this[_board].resetCursor(); + if (this[_onlyRender] !== true) this[_board].resetCursor(); } else if (this[_cursorStatus] === CursorStatus.NULL) { - const cursor = this[_mapper].judgePointCursor(point, this[_data]); - this[_board].setCursor(cursor); + const { cursor, elementUUID } = this[_mapper].judgePointCursor(point, this[_data]); + if (this[_onlyRender] !== true) this[_board].setCursor(cursor); + if (elementUUID) { + const index: number | null = this[_helper].getElementIndexByUUID(elementUUID); + if (index !== null && index >= 0) { + const elem = this[_data].elements[index]; + if (elem) { + this[_coreEvent].trigger('mouseOverElement', { index, uuid: elem.uuid, element: elem, }); + this[_tempData].set('hoverUUID', elem.uuid); + isMouseOverElement = true; + } + } + } + } + if (isMouseOverElement !== true && this[_tempData].get('hoverUUID') !== null) { + const uuid = this[_tempData].get('hoverUUID'); + const index: number | null = this[_helper].getElementIndexByUUID(uuid || ''); + this[_coreEvent].trigger('mouseLeaveElement', { uuid, index }) + this[_tempData].set('hoverUUID', null); } } @@ -419,10 +448,10 @@ class Core { private [_emitChangeScreen]() { if (this[_coreEvent].has('changeScreen')) { this[_coreEvent].trigger('changeScreen', { - ...this[_board].getTransform(), - ...{ - selectedElementUUID: this[_selectedUUID] - } + ...this.getScreenTransform(), + // ...{ + // selectedElementUUID: this[_tempData].get('selectedUUID') + // } }); } } diff --git a/packages/core/src/lib/core-event.ts b/packages/core/src/lib/core-event.ts index 99feae7b3..d22040683 100644 --- a/packages/core/src/lib/core-event.ts +++ b/packages/core/src/lib/core-event.ts @@ -7,12 +7,14 @@ import { } from '@idraw/types'; export type TypeCoreEventSelectBaseArg = { - index: number; - uuid: string; + index: number | null; + uuid: string | null; } export type TypeCoreEventArgMap = { 'error': any; + 'mouseOverElement': TypeCoreEventSelectBaseArg & { element: TypeElement } + 'mouseLeaveElement': TypeCoreEventSelectBaseArg; 'screenSelectElement': TypeCoreEventSelectBaseArg & { element: TypeElement } 'screenMoveElementStart': TypeCoreEventSelectBaseArg & TypePoint, 'screenMoveElementEnd': TypeCoreEventSelectBaseArg & TypePoint, diff --git a/packages/core/src/lib/loader.ts b/packages/core/src/lib/loader.ts index 882a913f7..a681ad510 100644 --- a/packages/core/src/lib/loader.ts +++ b/packages/core/src/lib/loader.ts @@ -254,29 +254,35 @@ export default class Loader { loadUUIDList.splice(loadUUIDList.indexOf(uuid), 1); const status = _loadAction(); - - 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 (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(); } - 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, - }); + + 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, + }); + } + }); } diff --git a/packages/core/src/lib/mapper.ts b/packages/core/src/lib/mapper.ts index b15a2ec30..ef7592018 100644 --- a/packages/core/src/lib/mapper.ts +++ b/packages/core/src/lib/mapper.ts @@ -37,10 +37,14 @@ export class Mapper { return false; } - judgePointCursor(p: TypePoint, data: TypeData): TypePointCursor { + judgePointCursor(p: TypePoint, data: TypeData): { + cursor: TypePointCursor, + elementUUID: string | null, + } { let cursor: TypePointCursor = 'auto'; + let elementUUID: string | null = null; if (!this.isEffectivePoint(p)) { - return cursor; + return { cursor, elementUUID}; } const [uuid, direction] = this[_helper].isPointInElementWrapperDot(p); if (uuid && direction) { @@ -85,13 +89,22 @@ export class Mapper { break; } } + if (uuid) { + elementUUID = uuid; + } } else { - const [index] = this[_element].isPointInElement(p, data); + const [index, uuid] = this[_element].isPointInElement(p, data); if (index >= 0) { cursor = 'move'; } + if (uuid) { + elementUUID = uuid; + } } - return cursor; + return { + cursor, + elementUUID, + }; } } diff --git a/packages/core/src/lib/temp.ts b/packages/core/src/lib/temp.ts new file mode 100644 index 000000000..a3e289063 --- /dev/null +++ b/packages/core/src/lib/temp.ts @@ -0,0 +1,36 @@ + +type TempDataDesc = { + selectedUUID: string | null, + selectedUUIDList: string[], + hoverUUID: string | null, +} + + +export class TempData { + + private _temp: TempDataDesc + + constructor() { + this._temp = { + selectedUUID: null, + selectedUUIDList: [], + hoverUUID: null, + } + } + + set(name: T, value: TempDataDesc[T]) { + this._temp[name] = value; + } + + get(name: T): TempDataDesc[T] { + return this._temp[name]; + } + + clear() { + this._temp = { + selectedUUID: null, + hoverUUID: null, + selectedUUIDList: [], + } + } +} \ No newline at end of file diff --git a/packages/core/src/names.ts b/packages/core/src/names.ts index bfff74f6a..c103371ef 100644 --- a/packages/core/src/names.ts +++ b/packages/core/src/names.ts @@ -7,8 +7,7 @@ const _element = Symbol('_element'); const _helper = Symbol('_helper'); const _hasInited = Symbol('_hasInited'); const _mode = Symbol('_mode'); -const _selectedUUID = Symbol('_selectedUUID'); -const _selectedUUIDList = Symbol('_selectedUUIDList'); +const _tempData = Symbol('_tempData'); const _prevPoint = Symbol('_prevPoint'); const _draw = Symbol('_draw'); const _selectedDotDirection = Symbol('_selectedDotDirection'); @@ -29,7 +28,7 @@ const _cursorStatus = Symbol('_cursorStatus'); export { _board, _data, _opts, _config, _renderer, _element, _helper, _hasInited, - _mode, _selectedUUID, _selectedUUIDList, _prevPoint, _draw, + _mode, _tempData, _prevPoint, _draw, _selectedDotDirection, _coreEvent, _mapper, _initEvent, _handlePoint, _handleMoveStart, _handleMove, _handleMoveEnd, _handleHover, _dragElements, _transfromElement, _emitChangeScreen, _emitChangeData, _onlyRender, _cursorStatus, diff --git a/packages/idraw/package.json b/packages/idraw/package.json index d94a1215c..d8be21d1c 100644 --- a/packages/idraw/package.json +++ b/packages/idraw/package.json @@ -1,6 +1,6 @@ { "name": "idraw", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "dist/index.cjs.js", "module": "dist/index.es.js", @@ -23,10 +23,10 @@ "author": "chenshenhai", "license": "MIT", "devDependencies": { - "@idraw/types": "^0.1.1" + "@idraw/types": "^0.1.2" }, "dependencies": { - "@idraw/core": "^0.1.1" + "@idraw/core": "^0.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/types/package.json b/packages/types/package.json index e1ec105b9..79f33ba5c 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@idraw/types", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/types/src/lib/screen.ts b/packages/types/src/lib/screen.ts index 89ac7000e..10f6bb3ec 100644 --- a/packages/types/src/lib/screen.ts +++ b/packages/types/src/lib/screen.ts @@ -1,8 +1,8 @@ type TypeScreenData = { scale: number; - scrollY: number; - scrollX: number; - selectedElementUUID: string | null; + scrollLeft: number; + scrollTop: number; + // selectedElementUUID: string | null; } type TypeScreenPosition = { diff --git a/packages/util/package.json b/packages/util/package.json index 8897cb963..3adedcf4d 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@idraw/util", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "dist/index.cjs.js", "module": "dist/index.es.js",