feat: init engine for @idraw/core

This commit is contained in:
chenshenhai 2021-11-26 12:44:01 +08:00
parent d8fb200f71
commit 78a47280ac
2 changed files with 326 additions and 5 deletions

View file

@ -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](

View file

@ -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;
}