mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
feat: init engine for @idraw/core
This commit is contained in:
parent
d8fb200f71
commit
78a47280ac
2 changed files with 326 additions and 5 deletions
|
|
@ -14,13 +14,14 @@ import {
|
|||
} from './lib';
|
||||
import {
|
||||
_board, _data, _opts, _config, _renderer, _element, _helper, _tempData, _draw, _coreEvent,
|
||||
_mapper, _emitChangeScreen, _emitChangeData,_todo
|
||||
_mapper, _emitChangeScreen, _emitChangeData, _todo
|
||||
} from './names';
|
||||
import { getSelectedElements, updateElement, selectElementByIndex, getElement, getElementByIndex,
|
||||
selectElement, moveUpElement, moveDownElement, addElement, deleteElement,
|
||||
insertElementBefore, insertElementBeforeIndex, insertElementAfter, insertElementAfterIndex,
|
||||
} from './mixins/element';
|
||||
import { initEvent } from './mixins/event';
|
||||
// import { initEvent } from './mixins/event';
|
||||
import { Engine } from './lib/engine';
|
||||
import { drawElementWrapper, drawAreaWrapper, drawElementListWrappers } from './lib/draw/wrapper'
|
||||
const { deepClone } = util.data;
|
||||
|
||||
|
|
@ -78,7 +79,9 @@ class Core {
|
|||
helper: this[_helper],
|
||||
element: this[_element]
|
||||
});
|
||||
initEvent(this);
|
||||
// initEvent(this);
|
||||
const engine = new Engine(this);
|
||||
engine.init();
|
||||
}
|
||||
|
||||
[_draw](
|
||||
|
|
|
|||
|
|
@ -1,5 +1,323 @@
|
|||
import {
|
||||
TypePoint, TypeHelperWrapperControllerDirection,InterfaceHelperPlugin
|
||||
} from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import {
|
||||
_board, _data, _opts, _config, _renderer, _element, _helper,
|
||||
_tempData, _draw, _coreEvent, _mapper,
|
||||
_emitChangeScreen, _emitChangeData,
|
||||
} from './../names';
|
||||
import { Mode, CursorStatus } from './../constant/static';
|
||||
import Core from './../index';
|
||||
const { time } = util;
|
||||
const { deepClone } = util.data;
|
||||
|
||||
// type Options = {
|
||||
// ctx: TypeContext,
|
||||
// helperCtx: TypeContext,
|
||||
// }
|
||||
|
||||
|
||||
export class Engine {
|
||||
constructor() {
|
||||
|
||||
|
||||
private _plugins: InterfaceHelperPlugin[] = [];
|
||||
private _core: Core;
|
||||
|
||||
constructor(core: Core) {
|
||||
this._core = core;
|
||||
}
|
||||
|
||||
addPlugin(plugin: InterfaceHelperPlugin) {
|
||||
this._plugins.push(plugin);
|
||||
}
|
||||
|
||||
init() {
|
||||
initEvent(this._core);
|
||||
}
|
||||
}
|
||||
|
||||
function initEvent(core: Core): void {
|
||||
|
||||
if (core[_tempData].get('hasInited') === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
core[_board].on('hover', time.throttle(handleHover(core), 32));
|
||||
core[_board].on('leave', time.throttle(handleLeave(core), 32));
|
||||
core[_board].on('point', time.throttle(handleClick(core), 16));
|
||||
core[_board].on('doubleClick', handleDoubleClick(core));
|
||||
if (core[_tempData].get('onlyRender') === true) {
|
||||
return;
|
||||
}
|
||||
core[_board].on('point', handlePoint(core));
|
||||
core[_board].on('moveStart', handleMoveStart(core));
|
||||
core[_board].on('move', time.throttle(handleMove(core), 16));
|
||||
core[_board].on('moveEnd', handleMoveEnd(core));
|
||||
|
||||
core[_renderer].on('drawFrame', () => {
|
||||
core[_coreEvent].trigger('drawFrame', undefined);
|
||||
});
|
||||
core[_renderer].on('drawFrameComplete', () => {
|
||||
core[_coreEvent].trigger('drawFrameComplete', undefined);
|
||||
})
|
||||
|
||||
core[_tempData].set('hasInited', true);
|
||||
}
|
||||
|
||||
|
||||
function handleDoubleClick(core: Core) {
|
||||
return function ( point: TypePoint) {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && uuid) {
|
||||
const elem = deepClone(core[_data].elements?.[index]);
|
||||
if (elem?.operation?.invisible !== true) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenDoubleClickElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
}
|
||||
}
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handlePoint(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
if (!core[_mapper].isEffectivePoint(point)) {
|
||||
return;
|
||||
}
|
||||
if (core[_helper].isPointInElementList(point, core[_data])) {
|
||||
// Coontroll Element-List
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT_LIST);
|
||||
} else {
|
||||
const {
|
||||
uuid, selectedControllerDirection
|
||||
} = core[_helper].isPointInElementWrapperController(point, core[_data]);
|
||||
if (uuid && selectedControllerDirection) {
|
||||
// Controll Element-Wrapper
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER);
|
||||
core[_tempData].set('selectedControllerDirection', selectedControllerDirection);
|
||||
core[_tempData].set('selectedUUID', uuid);
|
||||
} else {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && core[_data].elements[index]?.operation?.invisible !== true) {
|
||||
// Controll Element
|
||||
core.selectElementByIndex(index, { useMode: true });
|
||||
if (typeof uuid === 'string' && core[_coreEvent].has('screenSelectElement')) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenSelectElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
core[_emitChangeScreen]();
|
||||
}
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT);
|
||||
} else {
|
||||
// Controll Area
|
||||
core[_tempData].set('selectedUUIDList', []);
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
core[_tempData].set('mode', Mode.SELECT_AREA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleClick(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && uuid) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenClickElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
}
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoveStart(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
core[_tempData].set('prevPoint', point);
|
||||
const uuid = core[_tempData].get('selectedUUID');
|
||||
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_LIST) {
|
||||
// TODO
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT) {
|
||||
if (typeof uuid === 'string' && core[_coreEvent].has('screenMoveElementStart')) {
|
||||
core[_coreEvent].trigger('screenMoveElementStart', {
|
||||
index: core[_element].getElementIndex(core[_data], uuid),
|
||||
uuid,
|
||||
x: point.x,
|
||||
y: point.y
|
||||
});
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
core[_helper].startSelectArea(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleMove(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_LIST) {
|
||||
dragElements(core, core[_tempData].get('selectedUUIDList'), point, core[_tempData].get('prevPoint'));
|
||||
core[_draw]();
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING);
|
||||
} else if (typeof core[_tempData].get('selectedUUID') === 'string') {
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT) {
|
||||
dragElements(core, [core[_tempData].get('selectedUUID') as string], point, core[_tempData].get('prevPoint'));
|
||||
core[_draw]();
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING);
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER && core[_tempData].get('selectedControllerDirection')) {
|
||||
transfromElement(
|
||||
core,
|
||||
core[_tempData].get('selectedUUID') as string,
|
||||
point,
|
||||
core[_tempData].get('prevPoint'),
|
||||
core[_tempData].get('selectedControllerDirection') as TypeHelperWrapperControllerDirection
|
||||
);
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING)
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
core[_helper].changeSelectArea(point);
|
||||
core[_draw]();
|
||||
}
|
||||
core[_tempData].set('prevPoint', point)
|
||||
}
|
||||
}
|
||||
|
||||
function dragElements(core: Core, uuids: string[], point: TypePoint, prevPoint: TypePoint|null): void {
|
||||
if (!prevPoint) {
|
||||
return;
|
||||
}
|
||||
uuids.forEach((uuid) => {
|
||||
const idx = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (idx === null) return;
|
||||
const elem = core[_data].elements[idx];
|
||||
if (elem?.operation?.lock !== true && elem?.operation?.invisible !== true) {
|
||||
core[_element].dragElement(core[_data], uuid, point, prevPoint, core[_board].getContext().getTransform().scale);
|
||||
}
|
||||
});
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
|
||||
function handleMoveEnd(core: Core) {
|
||||
return function (point: TypePoint): void {
|
||||
const uuid = core[_tempData].get('selectedUUID');
|
||||
if (typeof uuid === 'string') {
|
||||
const index = core[_element].getElementIndex(core[_data], uuid);
|
||||
const elem = core[_data].elements[index];
|
||||
if (elem) {
|
||||
if (core[_coreEvent].has('screenMoveElementEnd')) {
|
||||
core[_coreEvent].trigger('screenMoveElementEnd', {
|
||||
index,
|
||||
uuid,
|
||||
x: point.x,
|
||||
y: point.y
|
||||
});
|
||||
}
|
||||
if (core[_coreEvent].has('screenChangeElement')) {
|
||||
core[_coreEvent].trigger('screenChangeElement', {
|
||||
index,
|
||||
uuid,
|
||||
width: elem.w,
|
||||
height: elem.h,
|
||||
angle: elem.angle || 0
|
||||
});
|
||||
}
|
||||
core[_emitChangeData]();
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
const uuids = core[_helper].calcSelectedElements(core[_data]);
|
||||
if (uuids.length > 0) {
|
||||
core[_tempData].set('selectedUUIDList', uuids);
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
} else {
|
||||
core[_tempData].set('mode', Mode.NULL);
|
||||
}
|
||||
core[_helper].clearSelectedArea();
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
if (core[_tempData].get('mode') !== Mode.SELECT_ELEMENT) {
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
}
|
||||
core[_tempData].set('cursorStatus', CursorStatus.NULL);
|
||||
core[_tempData].set('mode', Mode.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
function handleHover(core: Core) {
|
||||
return function (point: TypePoint): void {
|
||||
let isMouseOverElement: boolean = false;
|
||||
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
if (core[_tempData].get('onlyRender') !== true) core[_board].resetCursor();
|
||||
} else if (core[_tempData].get('cursorStatus') === CursorStatus.NULL) {
|
||||
const { cursor, elementUUID } = core[_mapper].judgePointCursor(point, core[_data]);
|
||||
if (core[_tempData].get('onlyRender') !== true) core[_board].setCursor(cursor);
|
||||
if (elementUUID) {
|
||||
const index: number | null = core[_helper].getElementIndexByUUID(elementUUID);
|
||||
if (index !== null && index >= 0) {
|
||||
const elem = core[_data].elements[index];
|
||||
if (elem?.operation?.lock === true || elem?.operation?.invisible === true) {
|
||||
core[_board].resetCursor();
|
||||
return;
|
||||
}
|
||||
if (core[_tempData].get('hoverUUID') !== elem.uuid) {
|
||||
const preIndex = core[_helper].getElementIndexByUUID(core[_tempData].get('hoverUUID') || '');
|
||||
if (preIndex !== null && core[_data].elements[preIndex]) {
|
||||
core[_coreEvent].trigger('mouseLeaveElement', {
|
||||
uuid: core[_tempData].get('hoverUUID'),
|
||||
index: preIndex,
|
||||
element: core[_data].elements[preIndex]
|
||||
});
|
||||
}
|
||||
}
|
||||
if (elem) {
|
||||
core[_coreEvent].trigger('mouseOverElement', { uuid: elem.uuid, index, element: elem, });
|
||||
core[_tempData].set('hoverUUID', elem.uuid);
|
||||
isMouseOverElement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isMouseOverElement !== true && core[_tempData].get('hoverUUID') !== null) {
|
||||
const uuid = core[_tempData].get('hoverUUID');
|
||||
const index: number | null = core[_helper].getElementIndexByUUID(uuid || '');
|
||||
if (index !== null) core[_coreEvent].trigger('mouseLeaveElement', { uuid, index, element: core[_data].elements[index] })
|
||||
core[_tempData].set('hoverUUID', null);
|
||||
}
|
||||
if (core[_coreEvent].has('mouseOverScreen')) core[_coreEvent].trigger('mouseOverScreen', point);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLeave(core: Core) {
|
||||
return function(): void {
|
||||
if (core[_coreEvent].has('mouseLeaveScreen')) {
|
||||
core[_coreEvent].trigger('mouseLeaveScreen', undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transfromElement(
|
||||
core: Core,
|
||||
uuid: string, point: TypePoint, prevPoint: TypePoint|null, direction: TypeHelperWrapperControllerDirection
|
||||
): null | {
|
||||
width: number,
|
||||
height: number,
|
||||
angle: number,
|
||||
} {
|
||||
if (!prevPoint) {
|
||||
return null;
|
||||
}
|
||||
const result = core[_element].transformElement(core[_data], uuid, point, prevPoint, core[_board].getContext().getTransform().scale, direction);
|
||||
core[_draw]();
|
||||
return result;
|
||||
}
|
||||
Loading…
Reference in a new issue