mirror of
https://github.com/idrawjs/idraw
synced 2026-05-23 09:38:22 +00:00
Merge pull request #337 from idrawjs/dev-v0.4
refactor: refactor events
This commit is contained in:
commit
f8bb1ef804
23 changed files with 350 additions and 209 deletions
|
|
@ -129,6 +129,7 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
|
|||
this.#watcher.on('scrollY', this.#handleScrollY.bind(this));
|
||||
this.#watcher.on('resize', this.#handleResize.bind(this));
|
||||
this.#watcher.on('doubleClick', this.#handleDoubleClick.bind(this));
|
||||
this.#watcher.on('contextMenu', this.#handleContextMenu.bind(this));
|
||||
|
||||
this.#renderer.on('load', () => {
|
||||
this.#eventHub.trigger('loadResource');
|
||||
|
|
@ -185,6 +186,16 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
|
|||
}
|
||||
}
|
||||
|
||||
#handleContextMenu(e: BoardWatcherEventMap['contextMenu']) {
|
||||
for (let i = 0; i < this.#activeMiddlewareObjs.length; i++) {
|
||||
const obj = this.#activeMiddlewareObjs[i];
|
||||
const result = obj?.contextMenu?.(e);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#handleWheel(e: BoardWatcherEventMap['wheel']) {
|
||||
for (let i = 0; i < this.#activeMiddlewareObjs.length; i++) {
|
||||
const obj = this.#activeMiddlewareObjs[i];
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
};
|
||||
|
||||
#onContextMenu = (e: MouseEvent) => {
|
||||
if (e.button !== 2) {
|
||||
return;
|
||||
}
|
||||
if (!this.#isInTarget(e)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -83,7 +86,7 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
if (!this.#isVaildPoint(point)) {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
this.trigger('contextMenu', { point });
|
||||
};
|
||||
|
||||
#onClick = (e: MouseEvent) => {
|
||||
|
|
@ -146,6 +149,12 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
};
|
||||
|
||||
#onPointStart = (e: MouseEvent) => {
|
||||
// mouse-left-click: button = 0
|
||||
// mouse-right-click: button = 2
|
||||
// mouse-scroll button = 1
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
if (!this.#isInTarget(e)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,49 @@
|
|||
export const eventChange = 'change';
|
||||
export const EVENT_KEY_CHANGE = 'change';
|
||||
export const EVENT_KEY_CURSOR = 'cursor';
|
||||
export const EVENT_KEY_RULER = 'ruler';
|
||||
export const EVENT_KEY_SCALE = 'scale';
|
||||
export const EVENT_KEY_SELECT = 'select';
|
||||
export const EVENT_KEY_CLEAR_SELECT = 'clearSelect';
|
||||
export const EVENT_KEY_TEXT_EDIT = 'textEdit';
|
||||
export const EVENT_KEY_TEXT_CHANGE = 'textChange';
|
||||
export const EVENT_KEY_CONTEXT_MENU = 'contextMenu';
|
||||
export const EVENT_KEY_SELECT_IN_GROUP = 'selectInGroup';
|
||||
export const EVENT_KEY_SNAP_TO_GRID = 'snapToGrid';
|
||||
|
||||
export type CoreEventKeys = {
|
||||
CURSOR: typeof EVENT_KEY_CURSOR;
|
||||
CHANGE: typeof EVENT_KEY_CHANGE;
|
||||
RULER: typeof EVENT_KEY_RULER;
|
||||
SCALE: typeof EVENT_KEY_SCALE;
|
||||
SELECT: typeof EVENT_KEY_SELECT;
|
||||
CLEAR_SELECT: typeof EVENT_KEY_CLEAR_SELECT;
|
||||
TEXT_EDIT: typeof EVENT_KEY_TEXT_EDIT;
|
||||
TEXT_CHANGE: typeof EVENT_KEY_TEXT_CHANGE;
|
||||
CONTEXT_MENU: typeof EVENT_KEY_CONTEXT_MENU;
|
||||
SELECT_IN_GROUP: typeof EVENT_KEY_SELECT_IN_GROUP;
|
||||
SNAP_TO_GRID: typeof EVENT_KEY_SELECT_IN_GROUP;
|
||||
};
|
||||
|
||||
const innerEventKeys: CoreEventKeys = {
|
||||
CURSOR: EVENT_KEY_CURSOR,
|
||||
CHANGE: EVENT_KEY_CHANGE,
|
||||
RULER: EVENT_KEY_RULER,
|
||||
SCALE: EVENT_KEY_SCALE,
|
||||
SELECT: EVENT_KEY_SELECT,
|
||||
CLEAR_SELECT: EVENT_KEY_CLEAR_SELECT,
|
||||
TEXT_EDIT: EVENT_KEY_TEXT_EDIT,
|
||||
TEXT_CHANGE: EVENT_KEY_TEXT_CHANGE,
|
||||
CONTEXT_MENU: EVENT_KEY_CONTEXT_MENU,
|
||||
SELECT_IN_GROUP: EVENT_KEY_SELECT_IN_GROUP,
|
||||
SNAP_TO_GRID: EVENT_KEY_SELECT_IN_GROUP
|
||||
};
|
||||
|
||||
const coreEventKeys = {} as CoreEventKeys;
|
||||
Object.keys(innerEventKeys).forEach((keyName: string) => {
|
||||
Object.defineProperty(coreEventKeys, keyName, {
|
||||
value: innerEventKeys[keyName as keyof CoreEventKeys],
|
||||
writable: false
|
||||
});
|
||||
});
|
||||
|
||||
export { coreEventKeys };
|
||||
|
|
|
|||
|
|
@ -2,23 +2,19 @@ import type { Data, PointSize, CoreOptions, BoardMiddleware, ViewSizeInfo, CoreE
|
|||
import { Board } from '@idraw/board';
|
||||
import { createBoardContent, validateElements } from '@idraw/util';
|
||||
import { Cursor } from './lib/cursor';
|
||||
export { eventChange } from './config';
|
||||
export { coreEventKeys } from './config';
|
||||
export type { CoreEventKeys } from './config';
|
||||
|
||||
// export { MiddlewareSelector } from './middleware/selector';
|
||||
export {
|
||||
MiddlewareSelector,
|
||||
middlewareEventSelect,
|
||||
middlewareEventSelectClear,
|
||||
middlewareEventSelectInGroup,
|
||||
middlewareEventSnapToGrid
|
||||
} from './middleware/selector';
|
||||
export { MiddlewareSelector } from './middleware/selector';
|
||||
export { MiddlewareScroller } from './middleware/scroller';
|
||||
export { MiddlewareScaler, middlewareEventScale } from './middleware/scaler';
|
||||
export { MiddlewareRuler, middlewareEventRuler } from './middleware/ruler';
|
||||
export { MiddlewareTextEditor, middlewareEventTextEdit, middlewareEventTextChange } from './middleware/text-editor';
|
||||
export { MiddlewareScaler } from './middleware/scaler';
|
||||
export { MiddlewareRuler } from './middleware/ruler';
|
||||
export { MiddlewareTextEditor } from './middleware/text-editor';
|
||||
export { MiddlewareDragger } from './middleware/dragger';
|
||||
export { MiddlewareInfo } from './middleware/info';
|
||||
export { MiddlewareLayoutSelector } from './middleware/layout-selector';
|
||||
export { MiddlewarePointer } from './middleware/pointer';
|
||||
|
||||
export class Core<E extends CoreEventMap = CoreEventMap> {
|
||||
#board: Board<E>;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { UtilEventEmitter, CoreEventMap } from '@idraw/types';
|
||||
import { limitAngle, loadImage, parseAngleToRadian } from '@idraw/util';
|
||||
import { CURSOR, CURSOR_RESIZE, CURSOR_DRAG_DEFAULT, CURSOR_DRAG_ACTIVE, CURSOR_RESIZE_ROTATE } from './cursor-image';
|
||||
import { coreEventKeys } from '../config';
|
||||
|
||||
export class Cursor {
|
||||
#eventHub: UtilEventEmitter<CoreEventMap>;
|
||||
|
|
@ -29,7 +30,7 @@ export class Cursor {
|
|||
#init() {
|
||||
const eventHub = this.#eventHub;
|
||||
this.#resetCursor('default');
|
||||
eventHub.on('cursor', (e) => {
|
||||
eventHub.on(coreEventKeys.CURSOR, (e) => {
|
||||
if (e.type === 'over-element' || !e.type) {
|
||||
this.#resetCursor('auto');
|
||||
} else if (e.type === 'resize-rotate') {
|
||||
|
|
@ -78,7 +79,7 @@ export class Cursor {
|
|||
}
|
||||
}
|
||||
|
||||
#setCursorResize(e: CoreEventMap['cursor']) {
|
||||
#setCursorResize(e: CoreEventMap[typeof coreEventKeys.CURSOR]) {
|
||||
let totalAngle = 0;
|
||||
if (e.type === 'resize-top') {
|
||||
totalAngle += 0;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { BoardMiddleware, CoreEventMap, Point } from '@idraw/types';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
const key = 'DRAG';
|
||||
const keyPrevPoint = Symbol(`${key}_prevPoint`);
|
||||
|
|
@ -17,7 +18,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
|
|||
if (isDragging === true) {
|
||||
return;
|
||||
}
|
||||
eventHub.trigger('cursor', {
|
||||
eventHub.trigger(coreEventKeys.CURSOR, {
|
||||
type: 'drag-default'
|
||||
});
|
||||
},
|
||||
|
|
@ -26,7 +27,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
|
|||
const { point } = e;
|
||||
sharer.setSharedStorage(keyPrevPoint, point);
|
||||
isDragging = true;
|
||||
eventHub.trigger('cursor', {
|
||||
eventHub.trigger(coreEventKeys.CURSOR, {
|
||||
type: 'drag-active'
|
||||
});
|
||||
},
|
||||
|
|
@ -46,7 +47,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
|
|||
pointEnd() {
|
||||
isDragging = false;
|
||||
sharer.setSharedStorage(keyPrevPoint, null);
|
||||
eventHub.trigger('cursor', {
|
||||
eventHub.trigger(coreEventKeys.CURSOR, {
|
||||
type: 'drag-default'
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { BoardMiddleware, ViewRectInfo, Element, MiddlewareInfoConfig } from '@idraw/types';
|
||||
import type { BoardMiddleware, ViewRectInfo, Element, MiddlewareInfoConfig, CoreEventMap } from '@idraw/types';
|
||||
import { formatNumber, getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot, createUUID, limitAngle, rotatePoint, parseAngleToRadian } from '@idraw/util';
|
||||
import { keySelectedElementList, keyHoverElement, keyActionType, keyGroupQueue } from '../selector';
|
||||
import { keySelectedElementList, keyActionType, keyGroupQueue } from '../selector';
|
||||
import { drawSizeInfoText, drawPositionInfoText, drawAngleInfoText } from './draw-info';
|
||||
import type { DeepInfoSharedStorage } from './types';
|
||||
import { defaltStyle } from './config';
|
||||
|
|
@ -8,7 +8,7 @@ import { defaltStyle } from './config';
|
|||
const infoFontSize = 10;
|
||||
const infoLineHeight = 16;
|
||||
|
||||
export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, any, MiddlewareInfoConfig> = (opts, config) => {
|
||||
export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, CoreEventMap, MiddlewareInfoConfig> = (opts, config) => {
|
||||
const { boardContent, calculator } = opts;
|
||||
const { overlayContext } = boardContent;
|
||||
const innerConfig = {
|
||||
|
|
@ -28,11 +28,10 @@ export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, any, Middlew
|
|||
const { sharedStore } = snapshot;
|
||||
|
||||
const selectedElementList = sharedStore[keySelectedElementList];
|
||||
const hoverElement = sharedStore[keyHoverElement];
|
||||
const actionType = sharedStore[keyActionType];
|
||||
const groupQueue = sharedStore[keyGroupQueue] || [];
|
||||
|
||||
if (selectedElementList.length === 1 && !hoverElement?.operations?.locked) {
|
||||
if (selectedElementList.length === 1) {
|
||||
const elem = selectedElementList[0];
|
||||
if (elem && ['select', 'drag', 'resize'].includes(actionType as string)) {
|
||||
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig } from '@idraw/types';
|
||||
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig, CoreEventMap } from '@idraw/types';
|
||||
import { calcLayoutSizeController, isViewPointInVertexes, getViewScaleInfoFromSnapshot, isViewPointInElementSize, calcViewElementSize } from '@idraw/util';
|
||||
import type { LayoutSelectorSharedStorage, ControlType } from './types';
|
||||
import { keyLayoutActionType, keyLayoutController, keyLayoutControlType, keyLayoutIsHover, keyLayoutIsSelected, controllerSize, defaultStyle } from './config';
|
||||
import { keyActionType as keyElementActionType, keyHoverElement, middlewareEventSelectClear } from '../selector';
|
||||
import { keyActionType as keyElementActionType, keyHoverElement } from '../selector';
|
||||
import { drawLayoutController, drawLayoutHover } from './util';
|
||||
import { eventChange } from '../../config';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
export { keyLayoutIsSelected };
|
||||
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, any, MiddlewareLayoutSelectorConfig> = (opts, config) => {
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, CoreEventMap, MiddlewareLayoutSelectorConfig> = (opts, config) => {
|
||||
const { sharer, boardContent, calculator, viewer, eventHub } = opts;
|
||||
const { overlayContext } = boardContent;
|
||||
const innerConfig = {
|
||||
|
|
@ -110,7 +110,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
}
|
||||
if (layoutControlType) {
|
||||
sharer.setSharedStorage(keyLayoutControlType, layoutControlType);
|
||||
eventHub.trigger(middlewareEventSelectClear, {});
|
||||
eventHub.trigger(coreEventKeys.CLEAR_SELECT);
|
||||
return layoutControlType;
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
if (isBusy === true) {
|
||||
return;
|
||||
}
|
||||
eventHub.trigger('cursor', {
|
||||
eventHub.trigger(coreEventKeys.CURSOR, {
|
||||
type: controlType ? `resize-${controlType}` : controlType,
|
||||
groupQueue: [],
|
||||
element: getLayoutSize()
|
||||
|
|
@ -309,7 +309,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
const layoutControlType = sharer.getSharedStorage(keyLayoutControlType);
|
||||
const data = sharer.getActiveStorage('data');
|
||||
if (data && layoutActionType === 'resize' && layoutControlType) {
|
||||
eventHub.trigger(eventChange, {
|
||||
eventHub.trigger(coreEventKeys.CHANGE, {
|
||||
type: 'changeLayout',
|
||||
data
|
||||
});
|
||||
|
|
|
|||
60
packages/core/src/middleware/pointer/index.ts
Normal file
60
packages/core/src/middleware/pointer/index.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import type { BoardMiddleware, CoreEventMap } from '@idraw/types';
|
||||
import type { DeepPointerSharedStorage } from './types';
|
||||
import { keySelectedElementList } from '../selector';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
export const MiddlewarePointer: BoardMiddleware<DeepPointerSharedStorage, CoreEventMap> = (opts) => {
|
||||
const { boardContent, eventHub, sharer } = opts;
|
||||
const canvas = boardContent.boardContext.canvas;
|
||||
const container = opts.container || document.body;
|
||||
const id = `idraw-middleware-pointer-${Math.random().toString(26).substring(2)}`;
|
||||
|
||||
const getCanvasRect = () => {
|
||||
const clientRect = canvas.getBoundingClientRect() as DOMRect;
|
||||
const { left, top, width, height } = clientRect;
|
||||
return { left, top, width, height };
|
||||
};
|
||||
|
||||
const contextMenuPointer = document.createElement('div');
|
||||
contextMenuPointer.setAttribute('id', id);
|
||||
contextMenuPointer.style.position = 'fixed';
|
||||
contextMenuPointer.style.top = '0';
|
||||
contextMenuPointer.style.bottom = 'unset';
|
||||
contextMenuPointer.style.left = '0';
|
||||
contextMenuPointer.style.right = 'unset';
|
||||
|
||||
// // TODO
|
||||
// contextMenuPointer.style.width = '10px';
|
||||
// contextMenuPointer.style.height = '10px';
|
||||
// contextMenuPointer.style.background = 'red';
|
||||
|
||||
container.appendChild(contextMenuPointer);
|
||||
|
||||
return {
|
||||
name: '@middleware/pointer',
|
||||
use() {
|
||||
// TODO
|
||||
},
|
||||
disuse() {
|
||||
// TODO
|
||||
},
|
||||
pointStart(e) {
|
||||
// TODO
|
||||
},
|
||||
pointEnd() {
|
||||
// TODO
|
||||
},
|
||||
contextMenu(e) {
|
||||
const { point } = e;
|
||||
const { left, top } = getCanvasRect();
|
||||
contextMenuPointer.style.left = `${left + point.x}px`;
|
||||
contextMenuPointer.style.top = `${top + point.y}px`;
|
||||
|
||||
const selectedElements = sharer.getSharedStorage(keySelectedElementList);
|
||||
eventHub.trigger(coreEventKeys.CONTEXT_MENU, {
|
||||
pointerContainer: contextMenuPointer,
|
||||
selectedElements: selectedElements || []
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
4
packages/core/src/middleware/pointer/types.ts
Normal file
4
packages/core/src/middleware/pointer/types.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { keySelectedElementList } from '../selector';
|
||||
import type { DeepSelectorSharedStorage } from '../selector';
|
||||
|
||||
export type DeepPointerSharedStorage = Pick<DeepSelectorSharedStorage, typeof keySelectedElementList>;
|
||||
|
|
@ -3,8 +3,7 @@ import { getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from '@idra
|
|||
import { drawRulerBackground, drawXRuler, drawYRuler, calcXRulerScaleList, calcYRulerScaleList, drawGrid, drawScrollerSelectedArea } from './util';
|
||||
import type { DeepRulerSharedStorage } from './types';
|
||||
import { defaultStyle } from './config';
|
||||
|
||||
export const middlewareEventRuler = '@middleware/show-ruler';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
export const MiddlewareRuler: BoardMiddleware<DeepRulerSharedStorage, CoreEventMap, MiddlewareRulerConfig> = (opts, config) => {
|
||||
const { boardContent, viewer, eventHub, calculator } = opts;
|
||||
|
|
@ -43,10 +42,10 @@ export const MiddlewareRuler: BoardMiddleware<DeepRulerSharedStorage, CoreEventM
|
|||
return {
|
||||
name: '@middleware/ruler',
|
||||
use() {
|
||||
eventHub.on(middlewareEventRuler, rulerCallback);
|
||||
eventHub.on(coreEventKeys.RULER, rulerCallback);
|
||||
},
|
||||
disuse() {
|
||||
eventHub.off(middlewareEventRuler, rulerCallback);
|
||||
eventHub.off(coreEventKeys.RULER, rulerCallback);
|
||||
},
|
||||
beforeDrawFrame: ({ snapshot }) => {
|
||||
if (show === true) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type { BoardMiddleware, CoreEventMap } from '@idraw/types';
|
||||
import { formatNumber } from '@idraw/util';
|
||||
|
||||
export const middlewareEventScale = '@middleware/scale';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
export const MiddlewareScaler: BoardMiddleware<Record<string, any>, CoreEventMap> = (opts) => {
|
||||
const { viewer, sharer, eventHub } = opts;
|
||||
|
|
@ -27,7 +26,7 @@ export const MiddlewareScaler: BoardMiddleware<Record<string, any>, CoreEventMap
|
|||
viewer.scroll({ moveX, moveY });
|
||||
viewer.drawFrame();
|
||||
const scaleNum = formatNumber(scale);
|
||||
eventHub.trigger(middlewareEventScale, { scale: scaleNum });
|
||||
eventHub.trigger(coreEventKeys.SCALE, { scale: scaleNum });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { drawScroller, isPointInScrollThumb } from './util';
|
|||
// import type { ScrollbarThumbType } from './util';
|
||||
import { keyXThumbRect, keyYThumbRect, keyPrevPoint, keyActivePoint, keyActiveThumbType, keyHoverXThumbRect, keyHoverYThumbRect, defaultStyle } from './config';
|
||||
import type { DeepScrollerSharedStorage } from './types';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
export const MiddlewareScroller: BoardMiddleware<DeepScrollerSharedStorage, any, MiddlewareScrollerConfig> = (opts, config) => {
|
||||
const { viewer, boardContent, sharer, eventHub } = opts;
|
||||
|
|
@ -98,7 +99,7 @@ export const MiddlewareScroller: BoardMiddleware<DeepScrollerSharedStorage, any,
|
|||
sharer.setSharedStorage(keyHoverXThumbRect, false);
|
||||
sharer.setSharedStorage(keyHoverYThumbRect, true);
|
||||
}
|
||||
eventHub.trigger('cursor', { type: 'default' });
|
||||
eventHub.trigger(coreEventKeys.CURSOR, { type: 'default' });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,11 +42,3 @@ export const defaultStyle: MiddlewareSelectorStyle = {
|
|||
lockedColor,
|
||||
referenceColor
|
||||
};
|
||||
|
||||
export const middlewareEventSelect: string = '@middleware/select';
|
||||
|
||||
export const middlewareEventSelectClear: string = '@middleware/select-clear';
|
||||
|
||||
export const middlewareEventSelectInGroup: string = '@middleware/select-in-group';
|
||||
|
||||
export const middlewareEventSnapToGrid: string = '@middleware/snap-to-grid';
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import type {
|
|||
Data,
|
||||
ViewRectVertexes,
|
||||
CoreEventMap,
|
||||
ElementPosition,
|
||||
ViewScaleInfo,
|
||||
ViewSizeInfo,
|
||||
ElementSizeController,
|
||||
|
|
@ -56,10 +55,6 @@ import {
|
|||
calcMoveInGroup
|
||||
} from './util';
|
||||
import {
|
||||
middlewareEventSelect,
|
||||
middlewareEventSelectClear,
|
||||
middlewareEventSelectInGroup,
|
||||
middlewareEventSnapToGrid,
|
||||
keyActionType,
|
||||
keyResizeType,
|
||||
keyAreaStart,
|
||||
|
|
@ -85,15 +80,12 @@ import {
|
|||
// keyDebugStartVertical
|
||||
} from './config';
|
||||
import { calcReferenceInfo } from './reference';
|
||||
import { middlewareEventTextEdit } from '../text-editor';
|
||||
import { eventChange } from '../../config';
|
||||
import { coreEventKeys } from '../../config';
|
||||
import { keyLayoutIsSelected } from '../layout-selector';
|
||||
|
||||
export { keySelectedElementList, keyHoverElement, keyActionType, keyResizeType, keyGroupQueue };
|
||||
export type { DeepSelectorSharedStorage, ActionType };
|
||||
|
||||
export { middlewareEventSelect, middlewareEventSelectClear, middlewareEventSelectInGroup, middlewareEventSnapToGrid };
|
||||
|
||||
export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, CoreEventMap, MiddlewareSelectorConfig> = (opts, config) => {
|
||||
const innerConfig = {
|
||||
...defaultStyle,
|
||||
|
|
@ -162,7 +154,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
}
|
||||
|
||||
if (opts?.triggerEvent === true) {
|
||||
eventHub.trigger(middlewareEventSelect, { uuids: list.map((elem) => elem.uuid) });
|
||||
eventHub.trigger(coreEventKeys.SELECT, { uuids: list.map((elem) => elem.uuid), positions: [] });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -199,7 +191,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
|
||||
clear();
|
||||
|
||||
const selectCallback = ({ uuids, positions }: { uuids: string[]; positions: ElementPosition[] }) => {
|
||||
const selectCallback = ({ uuids = [], positions }: CoreEventMap[typeof coreEventKeys.SELECT]) => {
|
||||
let elements: Element[] = [];
|
||||
const actionType = sharer.getSharedStorage(keyActionType);
|
||||
const data = sharer.getActiveStorage('data');
|
||||
|
|
@ -244,17 +236,17 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
return {
|
||||
name: '@middleware/selector',
|
||||
use() {
|
||||
eventHub.on(middlewareEventSelect, selectCallback);
|
||||
eventHub.on(middlewareEventSelectClear, selectClearCallback);
|
||||
eventHub.on(middlewareEventSelectInGroup, selectInGroupCallback);
|
||||
eventHub.on(middlewareEventSnapToGrid, setSnapToSnapCallback);
|
||||
eventHub.on(coreEventKeys.SELECT, selectCallback);
|
||||
eventHub.on(coreEventKeys.CLEAR_SELECT, selectClearCallback);
|
||||
eventHub.on(coreEventKeys.SELECT_IN_GROUP, selectInGroupCallback);
|
||||
eventHub.on(coreEventKeys.SNAP_TO_GRID, setSnapToSnapCallback);
|
||||
},
|
||||
|
||||
disuse() {
|
||||
eventHub.off(middlewareEventSelect, selectCallback);
|
||||
eventHub.off(middlewareEventSelectClear, selectClearCallback);
|
||||
eventHub.off(middlewareEventSelectInGroup, selectInGroupCallback);
|
||||
eventHub.off(middlewareEventSnapToGrid, setSnapToSnapCallback);
|
||||
eventHub.off(coreEventKeys.SELECT, selectCallback);
|
||||
eventHub.off(coreEventKeys.CLEAR_SELECT, selectClearCallback);
|
||||
eventHub.off(coreEventKeys.SELECT_IN_GROUP, selectInGroupCallback);
|
||||
eventHub.off(coreEventKeys.SNAP_TO_GRID, setSnapToSnapCallback);
|
||||
},
|
||||
|
||||
hover: (e: PointWatcherEvent) => {
|
||||
|
|
@ -269,7 +261,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
}
|
||||
const cursor: string | null = target.type;
|
||||
if (inBusyMode === null) {
|
||||
eventHub.trigger('cursor', {
|
||||
eventHub.trigger(coreEventKeys.CURSOR, {
|
||||
type: cursor,
|
||||
groupQueue: target.groupQueue,
|
||||
element: target.elements[0]
|
||||
|
|
@ -388,17 +380,20 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
})
|
||||
) {
|
||||
const target = getPointTarget(e.point, pointTargetBaseOptions());
|
||||
if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked === true) {
|
||||
return;
|
||||
} else {
|
||||
updateHoverElement(null);
|
||||
}
|
||||
const isLockedElement = target?.elements?.length === 1 && target.elements[0]?.operations?.locked === true;
|
||||
|
||||
// if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked === true) {
|
||||
// return;
|
||||
// } else {
|
||||
updateHoverElement(null);
|
||||
// }
|
||||
|
||||
if (target?.elements?.length === 1) {
|
||||
moveOriginalStartElementSize = getElementSize(target?.elements[0]);
|
||||
}
|
||||
|
||||
if (target.type === 'over-element' && target?.elements?.length === 1) {
|
||||
if (isLockedElement === true) {
|
||||
clear();
|
||||
} else if (target.type === 'over-element' && target?.elements?.length === 1) {
|
||||
updateSelectedElementList([target.elements[0]], { triggerEvent: true });
|
||||
sharer.setSharedStorage(keyActionType, 'drag');
|
||||
} else if (target.type?.startsWith('resize-')) {
|
||||
|
|
@ -426,30 +421,29 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
areaSize: listAreaSize,
|
||||
groupQueue: []
|
||||
});
|
||||
|
||||
const isLockedElement = target?.elements?.length === 1 && target.elements[0]?.operations?.locked === true;
|
||||
if (!isLockedElement) {
|
||||
updateHoverElement(null);
|
||||
}
|
||||
// if (!isLockedElement) {
|
||||
updateHoverElement(null);
|
||||
// }
|
||||
|
||||
if (target?.elements?.length === 1) {
|
||||
moveOriginalStartElementSize = getElementSize(target?.elements[0]);
|
||||
}
|
||||
|
||||
if (!isLockedElement) {
|
||||
if (target.type === 'list-area') {
|
||||
sharer.setSharedStorage(keyActionType, 'drag-list');
|
||||
} else if (target.type === 'over-element' && target?.elements?.length === 1) {
|
||||
updateSelectedElementList([target.elements[0]], { triggerEvent: true });
|
||||
sharer.setSharedStorage(keyActionType, 'drag');
|
||||
} else if (target.type?.startsWith('resize-')) {
|
||||
sharer.setSharedStorage(keyResizeType, target.type as ResizeType);
|
||||
sharer.setSharedStorage(keyActionType, 'resize');
|
||||
} else {
|
||||
clear();
|
||||
sharer.setSharedStorage(keyActionType, 'area');
|
||||
sharer.setSharedStorage(keyAreaStart, e.point);
|
||||
updateSelectedElementList([], { triggerEvent: true });
|
||||
}
|
||||
if (isLockedElement === true) {
|
||||
clear();
|
||||
sharer.setSharedStorage(keyActionType, 'area');
|
||||
sharer.setSharedStorage(keyAreaStart, e.point);
|
||||
updateSelectedElementList([], { triggerEvent: true });
|
||||
} else if (target.type === 'list-area') {
|
||||
sharer.setSharedStorage(keyActionType, 'drag-list');
|
||||
} else if (target.type === 'over-element' && target?.elements?.length === 1) {
|
||||
updateSelectedElementList([target.elements[0]], { triggerEvent: true });
|
||||
sharer.setSharedStorage(keyActionType, 'drag');
|
||||
} else if (target.type?.startsWith('resize-')) {
|
||||
sharer.setSharedStorage(keyResizeType, target.type as ResizeType);
|
||||
sharer.setSharedStorage(keyActionType, 'resize');
|
||||
} else {
|
||||
clear();
|
||||
sharer.setSharedStorage(keyActionType, 'area');
|
||||
|
|
@ -702,11 +696,11 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
}
|
||||
|
||||
if (data && (['drag', 'drag-list', 'drag-list-end', 'resize'] as ActionType[]).includes(actionType)) {
|
||||
let type = 'dragElement';
|
||||
let type: any = 'dragElement';
|
||||
if (type === 'resize') {
|
||||
type = 'resizeElement';
|
||||
}
|
||||
eventHub.trigger(eventChange, { data, type, selectedElements, hoverElement });
|
||||
eventHub.trigger(coreEventKeys.CHANGE, { data, type, selectedElements, hoverElement });
|
||||
}
|
||||
viewer.drawFrame();
|
||||
};
|
||||
|
|
@ -743,8 +737,8 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
return;
|
||||
}
|
||||
} else if (target.elements.length === 1 && target.elements[0]?.type === 'text' && !target.elements[0]?.operations?.invisible) {
|
||||
eventHub.trigger(middlewareEventTextEdit, {
|
||||
element: target.elements[0],
|
||||
eventHub.trigger(coreEventKeys.TEXT_EDIT, {
|
||||
element: target.elements[0] as Element<'text'>,
|
||||
groupQueue: sharer.getSharedStorage(keyGroupQueue) || [],
|
||||
position: getElementPositionFromList(target.elements[0]?.uuid, sharer.getActiveStorage('data')?.elements || []),
|
||||
viewScaleInfo: sharer.getActiveViewScaleInfo()
|
||||
|
|
@ -753,6 +747,53 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
sharer.setSharedStorage(keyActionType, null);
|
||||
},
|
||||
|
||||
contextMenu: (e: PointWatcherEvent) => {
|
||||
const groupQueue = sharer.getSharedStorage(keyGroupQueue);
|
||||
|
||||
if (groupQueue?.length > 0) {
|
||||
if (
|
||||
isPointInViewActiveGroup(e.point, {
|
||||
ctx: overlayContext,
|
||||
viewScaleInfo: sharer.getActiveViewScaleInfo(),
|
||||
viewSizeInfo: sharer.getActiveViewSizeInfo(),
|
||||
groupQueue
|
||||
})
|
||||
) {
|
||||
const target = getPointTarget(e.point, pointTargetBaseOptions());
|
||||
if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked !== true) {
|
||||
clear();
|
||||
updateSelectedElementList([target.elements[0]], { triggerEvent: true });
|
||||
viewer.drawFrame();
|
||||
} else if (!target?.elements?.length) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// not in group
|
||||
const listAreaSize = calcSelectedElementsArea(getActiveElements(), {
|
||||
viewScaleInfo: sharer.getActiveViewScaleInfo(),
|
||||
viewSizeInfo: sharer.getActiveViewSizeInfo(),
|
||||
calculator
|
||||
});
|
||||
const target = getPointTarget(e.point, {
|
||||
...pointTargetBaseOptions(),
|
||||
areaSize: listAreaSize,
|
||||
groupQueue: []
|
||||
});
|
||||
|
||||
if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked !== true) {
|
||||
clear();
|
||||
updateSelectedElementList([target.elements[0]], { triggerEvent: true });
|
||||
viewer.drawFrame();
|
||||
return;
|
||||
} else if (!target?.elements?.length) {
|
||||
clear();
|
||||
}
|
||||
},
|
||||
|
||||
beforeDrawFrame({ snapshot }) {
|
||||
const { activeStore, sharedStore } = snapshot;
|
||||
const { scale, offsetLeft, offsetTop, offsetRight, offsetBottom, width, height, contextHeight, contextWidth, devicePixelRatio } = activeStore;
|
||||
|
|
@ -784,13 +825,13 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
})
|
||||
: null;
|
||||
|
||||
const isLocked: boolean = !!hoverElement?.operations?.locked;
|
||||
const isHoverLocked: boolean = !!hoverElement?.operations?.locked;
|
||||
|
||||
if (groupQueue?.length > 0) {
|
||||
// in group
|
||||
drawGroupQueueVertexesWrappers(overlayContext, groupQueueVertexesList, drawBaseOpts);
|
||||
if (hoverElement && actionType !== 'drag') {
|
||||
if (isLocked) {
|
||||
if (isHoverLocked) {
|
||||
drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, {
|
||||
...drawBaseOpts,
|
||||
controller: calcElementSizeController(hoverElement, {
|
||||
|
|
@ -804,7 +845,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
drawHoverVertexesWrapper(overlayContext, hoverElementVertexes, drawBaseOpts);
|
||||
}
|
||||
}
|
||||
if (!isLocked && elem && (['select', 'drag', 'resize'] as ActionType[]).includes(actionType)) {
|
||||
if (elem && (['select', 'drag', 'resize'] as ActionType[]).includes(actionType)) {
|
||||
drawSelectedElementControllersVertexes(overlayContext, selectedElementController, {
|
||||
...drawBaseOpts,
|
||||
element: elem,
|
||||
|
|
@ -837,7 +878,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
} else {
|
||||
// in root
|
||||
if (hoverElement && actionType !== 'drag') {
|
||||
if (isLocked) {
|
||||
if (isHoverLocked) {
|
||||
drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, {
|
||||
...drawBaseOpts,
|
||||
controller: calcElementSizeController(hoverElement, {
|
||||
|
|
@ -851,7 +892,7 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
drawHoverVertexesWrapper(overlayContext, hoverElementVertexes, drawBaseOpts);
|
||||
}
|
||||
}
|
||||
if (!isLocked && elem && (['select', 'drag', 'resize'] as ActionType[]).includes(actionType)) {
|
||||
if (elem && (['select', 'drag', 'resize'] as ActionType[]).includes(actionType)) {
|
||||
drawSelectedElementControllersVertexes(overlayContext, selectedElementController, {
|
||||
...drawBaseOpts,
|
||||
element: elem,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type { BoardMiddleware, CoreEventMap, Element, ElementSize, ViewScaleInfo, ElementPosition } from '@idraw/types';
|
||||
import { limitAngle, getDefaultElementDetailConfig, enhanceFontFamliy } from '@idraw/util';
|
||||
export const middlewareEventTextEdit = '@middleware/text-edit';
|
||||
export const middlewareEventTextChange = '@middleware/text-change';
|
||||
import { coreEventKeys } from '../../config';
|
||||
|
||||
type TextEditEvent = {
|
||||
element: Element<'text'>;
|
||||
|
|
@ -20,7 +19,7 @@ type TextChangeEvent = {
|
|||
position: ElementPosition;
|
||||
};
|
||||
|
||||
type ExtendEventMap = Record<typeof middlewareEventTextEdit, TextEditEvent> & Record<typeof middlewareEventTextChange, TextChangeEvent>;
|
||||
type ExtendEventMap = Record<typeof coreEventKeys.TEXT_EDIT, TextEditEvent> & Record<typeof coreEventKeys.TEXT_CHANGE, TextChangeEvent>;
|
||||
|
||||
const defaultElementDetail = getDefaultElementDetailConfig();
|
||||
|
||||
|
|
@ -35,7 +34,8 @@ export const MiddlewareTextEditor: BoardMiddleware<ExtendEventMap, CoreEventMap
|
|||
const mask = document.createElement('div');
|
||||
let activeElem: Element<'text'> | null = null;
|
||||
let activePosition: ElementPosition = [];
|
||||
|
||||
const id = `idraw-middleware-text-editor-${Math.random().toString(26).substring(2)}`;
|
||||
mask.setAttribute('id', id);
|
||||
canvasWrapper.appendChild(textarea);
|
||||
|
||||
canvasWrapper.style.position = 'absolute';
|
||||
|
|
@ -211,7 +211,7 @@ export const MiddlewareTextEditor: BoardMiddleware<ExtendEventMap, CoreEventMap
|
|||
if (activeElem && activePosition) {
|
||||
// activeElem.detail.text = (e.target as any).value || '';
|
||||
activeElem.detail.text = textarea.innerText || '';
|
||||
eventHub.trigger(middlewareEventTextChange, {
|
||||
eventHub.trigger(coreEventKeys.TEXT_CHANGE, {
|
||||
element: {
|
||||
uuid: activeElem.uuid,
|
||||
detail: {
|
||||
|
|
@ -225,7 +225,7 @@ export const MiddlewareTextEditor: BoardMiddleware<ExtendEventMap, CoreEventMap
|
|||
});
|
||||
textarea.addEventListener('blur', () => {
|
||||
if (activeElem && activePosition) {
|
||||
eventHub.trigger(middlewareEventTextChange, {
|
||||
eventHub.trigger(coreEventKeys.TEXT_CHANGE, {
|
||||
element: {
|
||||
uuid: activeElem.uuid,
|
||||
detail: {
|
||||
|
|
@ -263,10 +263,10 @@ export const MiddlewareTextEditor: BoardMiddleware<ExtendEventMap, CoreEventMap
|
|||
return {
|
||||
name: '@middleware/text-editor',
|
||||
use() {
|
||||
eventHub.on(middlewareEventTextEdit, textEditCallback);
|
||||
eventHub.on(coreEventKeys.TEXT_EDIT, textEditCallback);
|
||||
},
|
||||
disuse() {
|
||||
eventHub.off(middlewareEventTextEdit, textEditCallback);
|
||||
eventHub.off(coreEventKeys.TEXT_EDIT, textEditCallback);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,61 +1,9 @@
|
|||
import type { CoreEventMap, Data } from '@idraw/types';
|
||||
import { eventChange } from '@idraw/core';
|
||||
import type { CoreEventMap } from '@idraw/types';
|
||||
import { coreEventKeys } from '@idraw/core';
|
||||
import type { CoreEventKeys } from '@idraw/core';
|
||||
|
||||
import {
|
||||
middlewareEventRuler,
|
||||
middlewareEventScale,
|
||||
middlewareEventSelect,
|
||||
middlewareEventSelectClear,
|
||||
middlewareEventTextEdit,
|
||||
middlewareEventTextChange
|
||||
} from '@idraw/core';
|
||||
export type IDrawEventKeys = CoreEventKeys; // TODO
|
||||
|
||||
const idrawEventChange = eventChange;
|
||||
export type IDrawEvent = CoreEventMap;
|
||||
|
||||
export type IDrawEvent = CoreEventMap & {
|
||||
[idrawEventChange]: {
|
||||
data: Data;
|
||||
type:
|
||||
| 'updateElement'
|
||||
| 'deleteElement'
|
||||
| 'moveElement'
|
||||
| 'addElement'
|
||||
| 'dragElement'
|
||||
| 'resizeElement'
|
||||
| 'setData'
|
||||
| 'undo'
|
||||
| 'redo'
|
||||
| 'changeLayout' // TODO
|
||||
| 'other';
|
||||
};
|
||||
};
|
||||
|
||||
export interface IDrawEventKeys {
|
||||
change: typeof idrawEventChange;
|
||||
ruler: typeof middlewareEventRuler;
|
||||
scale: typeof middlewareEventScale;
|
||||
select: typeof middlewareEventSelect;
|
||||
clearSelect: typeof middlewareEventSelectClear;
|
||||
textEdit: typeof middlewareEventTextEdit;
|
||||
textChange: typeof middlewareEventTextChange;
|
||||
}
|
||||
|
||||
const innerEventKeys: IDrawEventKeys = {
|
||||
change: idrawEventChange,
|
||||
ruler: middlewareEventRuler,
|
||||
scale: middlewareEventScale,
|
||||
select: middlewareEventSelect,
|
||||
clearSelect: middlewareEventSelectClear,
|
||||
textEdit: middlewareEventTextEdit,
|
||||
textChange: middlewareEventTextChange
|
||||
};
|
||||
|
||||
const eventKeys = {} as IDrawEventKeys;
|
||||
Object.keys(innerEventKeys).forEach((keyName: string) => {
|
||||
Object.defineProperty(eventKeys, keyName, {
|
||||
value: innerEventKeys[keyName as keyof IDrawEventKeys],
|
||||
writable: false
|
||||
});
|
||||
});
|
||||
|
||||
export { eventKeys };
|
||||
export const eventKeys = coreEventKeys; // TODO
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Core, middlewareEventSelectInGroup, middlewareEventSnapToGrid } from '@idraw/core';
|
||||
import { Core, coreEventKeys } from '@idraw/core';
|
||||
import type {
|
||||
PointSize,
|
||||
IDrawOptions,
|
||||
|
|
@ -14,7 +14,6 @@ import type {
|
|||
ElementPosition,
|
||||
IDrawStorage
|
||||
} from '@idraw/types';
|
||||
import type { IDrawEvent } from './event';
|
||||
import {
|
||||
createElement,
|
||||
insertElementToListByPosition,
|
||||
|
|
@ -31,7 +30,7 @@ import {
|
|||
import { defaultSettings, getDefaultStorage, defaultMode, parseStyles } from './config';
|
||||
import { exportImageFileBlobURL } from './file';
|
||||
import type { ExportImageFileBaseOptions, ExportImageFileResult } from './file';
|
||||
import { eventKeys } from './event';
|
||||
import type { IDrawEvent } from './event';
|
||||
import { changeMode, runMiddlewares } from './mode';
|
||||
|
||||
export class iDraw {
|
||||
|
|
@ -70,11 +69,11 @@ export class iDraw {
|
|||
runMiddlewares(this.#core, store);
|
||||
this.#core.refresh();
|
||||
} else if (feat === 'selectInGroup') {
|
||||
this.#core.trigger(middlewareEventSelectInGroup, {
|
||||
this.#core.trigger(coreEventKeys.SELECT_IN_GROUP, {
|
||||
enable: !!status
|
||||
});
|
||||
} else if (feat === 'snapToGrid') {
|
||||
this.#core.trigger(middlewareEventSnapToGrid, {
|
||||
this.#core.trigger(coreEventKeys.SNAP_TO_GRID, {
|
||||
enable: !!status
|
||||
});
|
||||
}
|
||||
|
|
@ -110,7 +109,7 @@ export class iDraw {
|
|||
setData(data: Data) {
|
||||
const core = this.#core;
|
||||
core.setData(data);
|
||||
core.trigger(eventKeys.change, { data, type: 'setData' });
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'setData' });
|
||||
}
|
||||
|
||||
getData(opts?: { compact?: boolean }): Data | null {
|
||||
|
|
@ -162,7 +161,7 @@ export class iDraw {
|
|||
}
|
||||
|
||||
trigger<T extends keyof IDrawEvent>(name: T, e?: IDrawEvent[T]) {
|
||||
this.#core.trigger(name, e);
|
||||
this.#core.trigger(name, e as IDrawEvent[T]);
|
||||
}
|
||||
|
||||
selectElement(uuid: string) {
|
||||
|
|
@ -170,7 +169,7 @@ export class iDraw {
|
|||
}
|
||||
|
||||
selectElements(uuids: string[]) {
|
||||
this.trigger(eventKeys.select, { uuids });
|
||||
this.trigger(coreEventKeys.SELECT, { uuids });
|
||||
}
|
||||
|
||||
selectElementByPosition(position: ElementPosition) {
|
||||
|
|
@ -178,11 +177,11 @@ export class iDraw {
|
|||
}
|
||||
|
||||
selectElementsByPositions(positions: ElementPosition[]) {
|
||||
this.trigger(eventKeys.select, { positions });
|
||||
this.trigger(coreEventKeys.SELECT, { positions });
|
||||
}
|
||||
|
||||
cancelElements() {
|
||||
this.trigger(eventKeys.clearSelect, { uuids: [] });
|
||||
this.trigger(coreEventKeys.CLEAR_SELECT, { uuids: [] });
|
||||
}
|
||||
|
||||
createElement<T extends ElementType>(
|
||||
|
|
@ -211,7 +210,7 @@ export class iDraw {
|
|||
updateElementInList(element.uuid, element, data.elements);
|
||||
core.setData(data);
|
||||
core.refresh();
|
||||
core.trigger(eventKeys.change, { data, type: 'updateElement' });
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'updateElement' });
|
||||
}
|
||||
|
||||
addElement(
|
||||
|
|
@ -230,7 +229,7 @@ export class iDraw {
|
|||
}
|
||||
core.setData(data);
|
||||
core.refresh();
|
||||
core.trigger(eventKeys.change, { data, type: 'addElement' });
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'addElement' });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +239,7 @@ export class iDraw {
|
|||
deleteElementInList(uuid, data.elements);
|
||||
core.setData(data);
|
||||
core.refresh();
|
||||
core.trigger(eventKeys.change, { data, type: 'deleteElement' });
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'deleteElement' });
|
||||
}
|
||||
|
||||
moveElement(uuid: string, to: ElementPosition) {
|
||||
|
|
@ -251,7 +250,7 @@ export class iDraw {
|
|||
data.elements = list;
|
||||
core.setData(data);
|
||||
core.refresh();
|
||||
core.trigger(eventKeys.change, { data, type: 'moveElement' });
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'moveElement' });
|
||||
}
|
||||
|
||||
async getImageBlobURL(opts?: ExportImageFileBaseOptions): Promise<ExportImageFileResult> {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,5 @@
|
|||
export type * from '@idraw/types';
|
||||
export {
|
||||
Core,
|
||||
MiddlewareSelector,
|
||||
middlewareEventSelect,
|
||||
middlewareEventSelectClear,
|
||||
MiddlewareScroller,
|
||||
MiddlewareScaler,
|
||||
middlewareEventScale,
|
||||
MiddlewareRuler,
|
||||
middlewareEventRuler,
|
||||
MiddlewareTextEditor
|
||||
} from '@idraw/core';
|
||||
export { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler, MiddlewareRuler, MiddlewareTextEditor, coreEventKeys } from '@idraw/core';
|
||||
export { Sharer, Calculator } from '@idraw/board';
|
||||
export { Renderer } from '@idraw/renderer';
|
||||
export {
|
||||
|
|
|
|||
|
|
@ -9,15 +9,16 @@ import {
|
|||
MiddlewareRuler,
|
||||
MiddlewareTextEditor,
|
||||
MiddlewareDragger,
|
||||
MiddlewareInfo
|
||||
MiddlewareInfo,
|
||||
MiddlewarePointer
|
||||
} from '@idraw/core';
|
||||
import { IDrawEvent } from './event';
|
||||
import { InnerEvent } from './event';
|
||||
|
||||
function isValidMode(mode: string | IDrawMode) {
|
||||
return ['select', 'drag', 'readOnly'].includes(mode);
|
||||
}
|
||||
|
||||
export function runMiddlewares(core: Core<IDrawEvent>, store: Store<IDrawStorage>) {
|
||||
export function runMiddlewares(core: Core<InnerEvent>, store: Store<IDrawStorage>) {
|
||||
const { enableRuler, enableScale, enableScroll, enableSelect, enableTextEdit, enableDrag, enableInfo } = store.getSnapshot();
|
||||
const styles = store.get('middlewareStyles');
|
||||
if (enableScroll === true) {
|
||||
|
|
@ -63,9 +64,11 @@ export function runMiddlewares(core: Core<IDrawEvent>, store: Store<IDrawStorage
|
|||
} else if (enableInfo === false) {
|
||||
core.disuse(MiddlewareInfo);
|
||||
}
|
||||
|
||||
core.use(MiddlewarePointer);
|
||||
}
|
||||
|
||||
export function changeMode(mode: IDrawMode, core: Core<IDrawEvent>, store: Store<IDrawStorage>) {
|
||||
export function changeMode(mode: IDrawMode, core: Core<InnerEvent>, store: Store<IDrawStorage>) {
|
||||
let enableScale: boolean = false;
|
||||
let enableScroll: boolean = false;
|
||||
let enableSelect: boolean = false;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export interface BoardWatcherEventMap<S extends Record<any | symbol, any> = any>
|
|||
pointEnd: BoardWatcherPointEvent;
|
||||
pointLeave: BoardWatcherPointEvent;
|
||||
doubleClick: BoardWatcherPointEvent;
|
||||
contextMenu: BoardWatcherPointEvent;
|
||||
wheel: BoardWatherWheelEvent;
|
||||
wheelScale: BoardWatherWheelScaleEvent;
|
||||
scrollX: BoardWatherScrollXEvent;
|
||||
|
|
@ -70,12 +71,10 @@ export interface BoardMiddlewareObject<S extends Record<any | symbol, any> = any
|
|||
pointEnd?: (e: BoardWatcherEventMap<S>['pointEnd']) => void | boolean;
|
||||
pointLeave?: (e: BoardWatcherEventMap<S>['pointLeave']) => void | boolean;
|
||||
doubleClick?: (e: BoardWatcherEventMap<S>['doubleClick']) => void | boolean;
|
||||
// wheelX?: (e: BoardWatcherEventMap<S>['wheelX']) => void | boolean;
|
||||
// wheelY?: (e: BoardWatcherEventMap<S>['wheelY']) => void | boolean;
|
||||
contextMenu?: (e: BoardWatcherEventMap<S>['contextMenu']) => void | boolean;
|
||||
wheel?: (e: BoardWatcherEventMap<S>['wheel']) => void | boolean;
|
||||
wheelScale?: (e: BoardWatcherEventMap<S>['wheelScale']) => void | boolean;
|
||||
|
||||
// scale?: (e: BoardWatcherEventMap<S>['scale']) => void | boolean;
|
||||
scrollX?: (e: BoardWatcherEventMap<S>['scrollX']) => void | boolean;
|
||||
scrollY?: (e: BoardWatcherEventMap<S>['scrollY']) => void | boolean;
|
||||
resize?: (e: BoardWatcherEventMap<S>['resize']) => void | boolean;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { Element, ElementType } from './element';
|
||||
import type { Element, ElementSize, ElementType, ElementPosition } from './element';
|
||||
import type { ViewScaleInfo } from './view';
|
||||
import type { Data } from './data';
|
||||
import type { ViewContext2D } from './context2d';
|
||||
import type { BoardBaseEventMap } from './board';
|
||||
|
|
@ -24,18 +25,29 @@ export type CursorType =
|
|||
| 'default';
|
||||
|
||||
export interface CoreEventCursor {
|
||||
type: CursorType | string | null;
|
||||
type?: CursorType | string | null;
|
||||
groupQueue?: Element<'group'>[];
|
||||
element?: Element<ElementType>;
|
||||
element?: Element<ElementType> | ElementSize | null;
|
||||
}
|
||||
|
||||
export interface CoreEventSelect {
|
||||
uuids: string[];
|
||||
positions?: Array<Array<number>>;
|
||||
}
|
||||
// export interface CoreEventSelect {
|
||||
// uuids: string[];
|
||||
// positions?: Array<Array<number>>;
|
||||
// }
|
||||
export interface CoreEventChange {
|
||||
type: string;
|
||||
data: Data;
|
||||
type:
|
||||
| 'updateElement'
|
||||
| 'deleteElement'
|
||||
| 'moveElement'
|
||||
| 'addElement'
|
||||
| 'dragElement'
|
||||
| 'resizeElement'
|
||||
| 'setData'
|
||||
| 'undo'
|
||||
| 'redo'
|
||||
| 'changeLayout' // TODO
|
||||
| 'other';
|
||||
selectedElements?: Element[] | null;
|
||||
hoverElement?: Element | null;
|
||||
}
|
||||
|
|
@ -43,8 +55,38 @@ export interface CoreEventScale {
|
|||
scale: number;
|
||||
}
|
||||
|
||||
type CoreEventTextEdit = {
|
||||
element: Element<'text'>;
|
||||
position: ElementPosition;
|
||||
groupQueue: Element<'group'>[];
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
};
|
||||
|
||||
type CoreEventTextChange = {
|
||||
element: {
|
||||
uuid: string;
|
||||
detail: {
|
||||
text: string;
|
||||
};
|
||||
};
|
||||
position: ElementPosition;
|
||||
};
|
||||
|
||||
type CoreEventContextMenu = {
|
||||
pointerContainer: HTMLDivElement;
|
||||
selectedElements: Element[];
|
||||
};
|
||||
|
||||
export type CoreEventMap = BoardBaseEventMap & {
|
||||
cursor: CoreEventCursor;
|
||||
change: CoreEventChange;
|
||||
[key: string]: any;
|
||||
ruler: { show: boolean; showGrid: boolean };
|
||||
scale: { scale: number };
|
||||
select: { uuids?: string[]; positions?: ElementPosition[] };
|
||||
clearSelect: { uuids?: string[] } | void;
|
||||
textEdit: CoreEventTextEdit;
|
||||
textChange: CoreEventTextChange;
|
||||
contextMenu: CoreEventContextMenu;
|
||||
selectInGroup: { enable: boolean };
|
||||
snapToGrid: { enable: boolean };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export interface UtilEventEmitter<T extends Record<string, any>> {
|
||||
on<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
|
||||
off<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
|
||||
trigger<K extends keyof T>(eventKey: K, e: T[K]): void;
|
||||
trigger<K extends keyof T>(eventKey: K, e?: T[K]): void;
|
||||
has<K extends keyof T>(name: K | string): boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue