mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 01:58:27 +00:00
feat: add middleware texteditor and enhance middlewares
This commit is contained in:
parent
69e49f2dbe
commit
532f604389
15 changed files with 324 additions and 61 deletions
|
|
@ -307,9 +307,9 @@ export class Board<T extends BoardExtendEvent = BoardExtendEvent> {
|
|||
}
|
||||
|
||||
use(middleware: BoardMiddleware<any, any>) {
|
||||
const { viewContent } = this._opts;
|
||||
const { viewContent, container } = this._opts;
|
||||
const { _sharer: sharer, _viewer: viewer, _calculator: calculator, _eventHub: eventHub } = this;
|
||||
const obj = middleware({ viewContent, sharer, viewer, calculator, eventHub: eventHub as UtilEventEmitter<any> });
|
||||
const obj = middleware({ viewContent, sharer, viewer, calculator, eventHub: eventHub as UtilEventEmitter<any>, container });
|
||||
this._middlewares.push(middleware);
|
||||
this._activeMiddlewareObjs.push(obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,24 +8,26 @@ export { MiddlewareSelector, middlewareEventSelect } from './middleware/selector
|
|||
export { MiddlewareScroller } from './middleware/scroller';
|
||||
export { MiddlewareScaler, middlewareEventScale } from './middleware/scaler';
|
||||
export { MiddlewareRuler, middlewareEventRuler } from './middleware/ruler';
|
||||
export { MiddlewareTextEditor, middlewareEventTextEdit } from './middleware/text-editor';
|
||||
|
||||
export class Core {
|
||||
private _board: Board<CoreEvent>;
|
||||
private _opts: CoreOptions;
|
||||
private _container: HTMLDivElement;
|
||||
private _canvas: HTMLCanvasElement;
|
||||
#board: Board<CoreEvent>;
|
||||
// #opts: CoreOptions;
|
||||
// #canvas: HTMLCanvasElement;
|
||||
#container: HTMLDivElement;
|
||||
constructor(container: HTMLDivElement, opts: CoreOptions) {
|
||||
const { devicePixelRatio = 1, width, height } = opts;
|
||||
|
||||
this._opts = opts;
|
||||
this._container = container;
|
||||
// this.#opts = opts;
|
||||
// this.#canvas = canvas;
|
||||
this.#container = container;
|
||||
const canvas = document.createElement('canvas');
|
||||
this._canvas = canvas;
|
||||
this.#initContainer();
|
||||
container.appendChild(canvas);
|
||||
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const viewContent = createBoardContexts(ctx, { devicePixelRatio });
|
||||
const board = new Board<CoreEvent>({ viewContent });
|
||||
const board = new Board<CoreEvent>({ viewContent, container });
|
||||
const sharer = board.getSharer();
|
||||
sharer.setActiveViewSizeInfo({
|
||||
width,
|
||||
|
|
@ -34,7 +36,7 @@ export class Core {
|
|||
contextWidth: width,
|
||||
contextHeight: height
|
||||
});
|
||||
this._board = board;
|
||||
this.#board = board;
|
||||
this.resize(sharer.getActiveViewSizeInfo());
|
||||
const eventHub = board.getEventHub();
|
||||
new Cursor(container, {
|
||||
|
|
@ -42,27 +44,32 @@ export class Core {
|
|||
});
|
||||
}
|
||||
|
||||
#initContainer() {
|
||||
const container = this.#container;
|
||||
container.style.position = 'relative';
|
||||
}
|
||||
|
||||
use(middleware: BoardMiddleware<any, any>) {
|
||||
this._board.use(middleware);
|
||||
this.#board.use(middleware);
|
||||
}
|
||||
|
||||
setData(data: Data) {
|
||||
validateElements(data?.elements || []);
|
||||
this._board.setData(data);
|
||||
this.#board.setData(data);
|
||||
}
|
||||
|
||||
getData(): Data | null {
|
||||
return this._board.getData();
|
||||
return this.#board.getData();
|
||||
}
|
||||
|
||||
scale(opts: { scale: number; point: PointSize }) {
|
||||
this._board.scale(opts);
|
||||
const viewer = this._board.getViewer();
|
||||
this.#board.scale(opts);
|
||||
const viewer = this.#board.getViewer();
|
||||
viewer.drawFrame();
|
||||
}
|
||||
|
||||
resize(newViewSize: Partial<ViewSizeInfo>) {
|
||||
const { _board: board } = this;
|
||||
const board = this.#board;
|
||||
const sharer = board.getSharer();
|
||||
const viewSizeInfo = sharer.getActiveViewSizeInfo();
|
||||
board.resize({
|
||||
|
|
@ -72,21 +79,21 @@ export class Core {
|
|||
}
|
||||
|
||||
clear() {
|
||||
this._board.clear();
|
||||
this.#board.clear();
|
||||
}
|
||||
|
||||
on<T extends keyof CoreEvent>(name: T, callback: (e: CoreEvent[T]) => void) {
|
||||
const eventHub = this._board.getEventHub();
|
||||
const eventHub = this.#board.getEventHub();
|
||||
eventHub.on(name, callback);
|
||||
}
|
||||
|
||||
off<T extends keyof CoreEvent>(name: T, callback: (e: CoreEvent[T]) => void) {
|
||||
const eventHub = this._board.getEventHub();
|
||||
const eventHub = this.#board.getEventHub();
|
||||
eventHub.off(name, callback);
|
||||
}
|
||||
|
||||
trigger<T extends keyof CoreEvent>(name: T, e: CoreEvent[T]) {
|
||||
const eventHub = this._board.getEventHub();
|
||||
const eventHub = this.#board.getEventHub();
|
||||
eventHub.trigger(name, e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ export class Cursor {
|
|||
const { _eventHub: eventHub } = this;
|
||||
this._resetCursor('auto');
|
||||
eventHub.on('cursor', (e) => {
|
||||
// console.log('e ======= ', e);
|
||||
if (e.type === 'over-element' || !e.type) {
|
||||
this._resetCursor('auto');
|
||||
} else if (typeof e.type === 'string' && e.type?.startsWith('resize-')) {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,18 @@ export const MiddlewareRuler: BoardMiddleware<Record<string, any>, CoreEvent> =
|
|||
const key = 'RULE';
|
||||
const { viewContent, viewer, eventHub } = opts;
|
||||
const { helperContext, underContext } = viewContent;
|
||||
let showRuler: boolean = true;
|
||||
let show: boolean = true;
|
||||
let showGrid: boolean = true;
|
||||
|
||||
eventHub.on(middlewareEventRuler, (e: { show: boolean }) => {
|
||||
eventHub.on(middlewareEventRuler, (e: { show: boolean; showGrid: boolean }) => {
|
||||
if (typeof e?.show === 'boolean') {
|
||||
showRuler = e.show;
|
||||
show = e.show;
|
||||
}
|
||||
if (typeof e?.showGrid === 'boolean') {
|
||||
showGrid = e.showGrid;
|
||||
}
|
||||
|
||||
if (typeof e?.show === 'boolean' || typeof e?.showGrid === 'boolean') {
|
||||
viewer.drawFrame();
|
||||
}
|
||||
});
|
||||
|
|
@ -20,7 +27,7 @@ export const MiddlewareRuler: BoardMiddleware<Record<string, any>, CoreEvent> =
|
|||
mode: key,
|
||||
isDefault: true,
|
||||
beforeDrawFrame: ({ snapshot }) => {
|
||||
if (showRuler === true) {
|
||||
if (show === true) {
|
||||
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
|
||||
const viewSizeInfo = getViewSizeInfoFromSnapshot(snapshot);
|
||||
drawRulerBackground(helperContext, { viewScaleInfo, viewSizeInfo });
|
||||
|
|
@ -31,12 +38,14 @@ export const MiddlewareRuler: BoardMiddleware<Record<string, any>, CoreEvent> =
|
|||
const yList = calcYRulerScaleList({ viewScaleInfo, viewSizeInfo });
|
||||
drawYRuler(helperContext, { scaleList: yList });
|
||||
|
||||
drawUnderGrid(underContext, {
|
||||
xList,
|
||||
yList,
|
||||
viewScaleInfo,
|
||||
viewSizeInfo
|
||||
});
|
||||
if (showGrid === true) {
|
||||
drawUnderGrid(underContext, {
|
||||
xList,
|
||||
yList,
|
||||
viewScaleInfo,
|
||||
viewSizeInfo
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ViewScaleInfo, ViewSizeInfo, ViewContext2D } from '@idraw/types';
|
||||
import { Context2D, formatNumber, rotateByCenter } from '@idraw/util';
|
||||
import { formatNumber, rotateByCenter } from '@idraw/util';
|
||||
|
||||
const rulerSize = 16;
|
||||
const background = '#FFFFFFA8';
|
||||
|
|
@ -11,6 +11,7 @@ const fontSize = 10;
|
|||
const fontWeight = 100;
|
||||
const gridColor = '#AAAAAA30';
|
||||
const gridKeyColor = '#AAAAAA70';
|
||||
const lineSize = 1;
|
||||
|
||||
// const rulerUnit = 10;
|
||||
// const rulerKeyUnit = 100;
|
||||
|
|
@ -30,7 +31,7 @@ function calcRulerScaleList(opts: { axis: 'X' | 'Y'; scale: number; viewLength:
|
|||
let rulerUnit = 10;
|
||||
|
||||
rulerUnit = formatNumber(rulerUnit / scale, { decimalPlaces: 0 });
|
||||
rulerUnit = Math.max(1, Math.min(rulerUnit, 1000));
|
||||
rulerUnit = Math.max(10, Math.min(rulerUnit, 1000));
|
||||
|
||||
const rulerKeyUnit = rulerUnit * 10;
|
||||
const rulerSubKeyUnit = rulerUnit * 5;
|
||||
|
|
@ -104,6 +105,8 @@ export function drawXRuler(
|
|||
ctx.moveTo(item.position, scaleDrawStart);
|
||||
ctx.lineTo(item.position, item.isKeyNum ? keyScaleDrawEnd : item.isSubKeyNum ? subKeyScaleDrawEnd : scaleDrawEnd);
|
||||
ctx.closePath();
|
||||
ctx.lineWidth = lineSize;
|
||||
ctx.setLineDash([]);
|
||||
ctx.fillStyle = scaleColor;
|
||||
ctx.stroke();
|
||||
if (item.isKeyNum) {
|
||||
|
|
@ -141,6 +144,8 @@ export function drawYRuler(
|
|||
ctx.lineTo(item.isKeyNum ? keyScaleDrawEnd : item.isSubKeyNum ? subKeyScaleDrawEnd : scaleDrawEnd, item.position);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = scaleColor;
|
||||
ctx.lineWidth = lineSize;
|
||||
ctx.setLineDash([]);
|
||||
ctx.stroke();
|
||||
if (item.showNum === true) {
|
||||
const textX = fontStart;
|
||||
|
|
@ -181,6 +186,8 @@ export function drawRulerBackground(
|
|||
ctx.closePath();
|
||||
ctx.fillStyle = background;
|
||||
ctx.fill();
|
||||
ctx.lineWidth = lineSize;
|
||||
ctx.setLineDash([]);
|
||||
ctx.strokeStyle = borderColor;
|
||||
ctx.stroke();
|
||||
}
|
||||
|
|
@ -206,9 +213,9 @@ export function drawUnderGrid(
|
|||
} else {
|
||||
ctx.strokeStyle = gridColor;
|
||||
}
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.closePath();
|
||||
ctx.lineWidth = lineSize;
|
||||
ctx.setLineDash([]);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ export const middlewareEventScale = '@middleware/scale';
|
|||
export const MiddlewareScaler: BoardMiddleware<Record<string, any>, CoreEvent> = (opts) => {
|
||||
const key = 'SCALE';
|
||||
const { viewer, sharer, eventHub } = opts;
|
||||
const maxScale = 50;
|
||||
const minScale = 0.05;
|
||||
|
||||
return {
|
||||
mode: key,
|
||||
|
|
@ -19,6 +21,10 @@ export const MiddlewareScaler: BoardMiddleware<Record<string, any>, CoreEvent> =
|
|||
} else if (deltaY > 0) {
|
||||
newScaleNum = scale * 0.9;
|
||||
}
|
||||
if (newScaleNum < minScale || newScaleNum > maxScale) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { moveX, moveY } = viewer.scale({ scale: newScaleNum, point });
|
||||
viewer.scroll({ moveX, moveY });
|
||||
viewer.drawFrame();
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ function calcScrollerInfo(viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeIn
|
|||
|
||||
let xSize = 0;
|
||||
let ySize = 0;
|
||||
xSize = Math.max(sliderMinSize, width - (Math.abs(offsetLeft) + Math.abs(offsetRight)));
|
||||
xSize = Math.max(sliderMinSize, width - lineSize * 2 - (Math.abs(offsetLeft) + Math.abs(offsetRight)));
|
||||
if (xSize >= width) {
|
||||
xSize = width;
|
||||
}
|
||||
ySize = Math.max(sliderMinSize, height - (Math.abs(offsetTop) + Math.abs(offsetBottom)));
|
||||
ySize = Math.max(sliderMinSize, height - lineSize * 2 - (Math.abs(offsetTop) + Math.abs(offsetBottom)));
|
||||
if (ySize >= height) {
|
||||
ySize = height;
|
||||
}
|
||||
|
|
@ -246,6 +246,7 @@ function drawScrollerInfo(helperContext: ViewContext2D, opts: { viewScaleInfo: V
|
|||
});
|
||||
|
||||
ctx.globalAlpha = 1;
|
||||
|
||||
return {
|
||||
xThumbRect,
|
||||
yThumbRect
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import {
|
|||
// keyDebugStartHorizontal,
|
||||
// keyDebugStartVertical
|
||||
} from './config';
|
||||
import { middlewareEventTextEdit } from '../text-editor';
|
||||
|
||||
export const middlewareEventSelect: string = '@middleware/select';
|
||||
|
||||
|
|
@ -486,6 +487,12 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
viewer.drawFrame();
|
||||
return;
|
||||
}
|
||||
} else if (target.elements.length === 1 && target.elements[0]?.type === 'text') {
|
||||
eventHub.trigger(middlewareEventTextEdit, {
|
||||
element: target.elements[0],
|
||||
groupQueue: sharer.getSharedStorage(keyGroupQueue) || [],
|
||||
viewScaleInfo: sharer.getActiveViewScaleInfo()
|
||||
});
|
||||
}
|
||||
sharer.setSharedStorage(keyActionType, null);
|
||||
},
|
||||
|
|
|
|||
160
packages/core/src/middleware/text-editor/index.ts
Normal file
160
packages/core/src/middleware/text-editor/index.ts
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
import type { BoardMiddleware, CoreEvent, Element, ElementSize, ViewScaleInfo } from '@idraw/types';
|
||||
import { limitAngle, getDefaultElementDetailConfig } from '@idraw/util';
|
||||
export const middlewareEventTextEdit = '@middleware/text-edit';
|
||||
|
||||
type TextEditEvent = {
|
||||
element: Element<'text'>;
|
||||
groupQueue: Element<'group'>[];
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
};
|
||||
|
||||
const defaultElementDetail = getDefaultElementDetailConfig();
|
||||
|
||||
export const MiddlewareTextEditor: BoardMiddleware<Record<string, any>, CoreEvent> = (opts) => {
|
||||
const key = 'SELECT';
|
||||
|
||||
const { eventHub, viewContent, viewer } = opts;
|
||||
const canvas = viewContent.boardContext.canvas;
|
||||
const textarea = document.createElement('textarea');
|
||||
const canvasWrapper = document.createElement('div');
|
||||
const container = opts.container || document.body;
|
||||
const mask = document.createElement('div');
|
||||
let activeElem: Element<'text'> | null = null;
|
||||
|
||||
canvasWrapper.appendChild(textarea);
|
||||
|
||||
canvasWrapper.style.position = 'absolute';
|
||||
mask.appendChild(canvasWrapper);
|
||||
|
||||
mask.style.position = 'fixed';
|
||||
mask.style.top = '0';
|
||||
mask.style.bottom = '0';
|
||||
mask.style.left = '0';
|
||||
mask.style.right = '0';
|
||||
mask.style.display = 'none';
|
||||
container.appendChild(mask);
|
||||
|
||||
const showTextArea = (e: TextEditEvent) => {
|
||||
resetCanvasWrapper();
|
||||
resetTextArea(e);
|
||||
mask.style.display = 'block';
|
||||
};
|
||||
|
||||
const hideTextArea = () => {
|
||||
mask.style.display = 'none';
|
||||
activeElem = null;
|
||||
};
|
||||
|
||||
const getCanvasRect = () => {
|
||||
const clientRect = canvas.getBoundingClientRect() as DOMRect;
|
||||
const { left, top, width, height } = clientRect;
|
||||
return { left, top, width, height };
|
||||
};
|
||||
|
||||
const createBox = (opts: { size: ElementSize; parent: HTMLDivElement }) => {
|
||||
const { size, parent } = opts;
|
||||
const div = document.createElement('div');
|
||||
const { x, y, w, h } = size;
|
||||
const angle = limitAngle(size.angle || 0);
|
||||
div.style.position = 'absolute';
|
||||
div.style.left = `${x}px`;
|
||||
div.style.top = `${y}px`;
|
||||
div.style.width = `${w}px`;
|
||||
div.style.height = `${h}px`;
|
||||
div.style.transform = `rotate(${angle}deg)`;
|
||||
parent.appendChild(div);
|
||||
return div;
|
||||
};
|
||||
|
||||
const resetTextArea = (e: TextEditEvent) => {
|
||||
const { viewScaleInfo, element, groupQueue } = e;
|
||||
const { scale, offsetTop, offsetLeft } = viewScaleInfo;
|
||||
|
||||
if (canvasWrapper.children) {
|
||||
Array.from(canvasWrapper.children).forEach((child) => {
|
||||
child.remove();
|
||||
});
|
||||
}
|
||||
let parent = canvasWrapper;
|
||||
for (let i = 0; i < groupQueue.length; i++) {
|
||||
const group = groupQueue[i];
|
||||
const { x, y, w, h } = group;
|
||||
const angle = limitAngle(group.angle || 0);
|
||||
const size = {
|
||||
x: x * scale,
|
||||
y: y * scale,
|
||||
w: w * scale,
|
||||
h: h * scale,
|
||||
angle
|
||||
};
|
||||
if (i === 0) {
|
||||
size.x += offsetLeft;
|
||||
size.y += offsetTop;
|
||||
}
|
||||
parent = createBox({ size, parent });
|
||||
}
|
||||
|
||||
const detail = {
|
||||
...defaultElementDetail,
|
||||
...element.detail
|
||||
};
|
||||
|
||||
textarea.style.position = 'absolute';
|
||||
textarea.style.left = `${element.x * scale}px`;
|
||||
textarea.style.top = `${element.y * scale}px`;
|
||||
textarea.style.width = `${element.w * scale}px`;
|
||||
textarea.style.height = `${element.h * scale}px`;
|
||||
textarea.style.transform = `rotate(${limitAngle(element.angle || 0)}deg)`;
|
||||
textarea.style.border = 'none';
|
||||
textarea.style.resize = 'none';
|
||||
textarea.style.overflow = 'hidden';
|
||||
textarea.style.wordBreak = 'break-all';
|
||||
textarea.style.background = '#FFFFFF';
|
||||
textarea.style.color = '#333333';
|
||||
textarea.style.fontSize = `${detail.fontSize * scale}px`;
|
||||
textarea.style.lineHeight = `${detail.lineHeight * scale}px`;
|
||||
textarea.style.fontFamily = detail.fontFamily;
|
||||
textarea.style.fontWeight = `${detail.fontWeight}`;
|
||||
textarea.value = detail.text || '';
|
||||
parent.appendChild(textarea);
|
||||
};
|
||||
|
||||
const resetCanvasWrapper = () => {
|
||||
const { left, top, width, height } = getCanvasRect();
|
||||
canvasWrapper.style.position = 'absolute';
|
||||
canvasWrapper.style.overflow = 'hidden';
|
||||
canvasWrapper.style.top = `${top}px`;
|
||||
canvasWrapper.style.left = `${left}px`;
|
||||
canvasWrapper.style.width = `${width}px`;
|
||||
canvasWrapper.style.height = `${height}px`;
|
||||
// canvasWrapper.style.background = '#000000';
|
||||
};
|
||||
|
||||
mask.addEventListener('click', () => {
|
||||
hideTextArea();
|
||||
});
|
||||
textarea.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
textarea.addEventListener('input', (e) => {
|
||||
if (activeElem) {
|
||||
activeElem.detail.text = (e.target as any).value || '';
|
||||
viewer.drawFrame();
|
||||
}
|
||||
});
|
||||
textarea.addEventListener('blur', () => {
|
||||
hideTextArea();
|
||||
});
|
||||
|
||||
eventHub.on(middlewareEventTextEdit, (e: TextEditEvent) => {
|
||||
if (e?.element && e?.element?.type === 'text') {
|
||||
activeElem = e.element;
|
||||
}
|
||||
showTextArea(e);
|
||||
});
|
||||
|
||||
return {
|
||||
mode: key,
|
||||
isDefault: true
|
||||
};
|
||||
};
|
||||
|
|
@ -203,6 +203,28 @@ const data: Data = {
|
|||
detail: {
|
||||
background: '#cddc39'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'text-002',
|
||||
name: 'text-002',
|
||||
x: 50,
|
||||
y: 200,
|
||||
w: 100,
|
||||
h: 50,
|
||||
// angle: 30,
|
||||
type: 'text',
|
||||
detail: {
|
||||
fontSize: 16,
|
||||
// text: 'Hello Text Hello Text Hello Text Hello Text Hello Text Hello Text',
|
||||
text: 'Hello Text',
|
||||
fontWeight: 'bold',
|
||||
color: '#000000',
|
||||
borderRadius: 30,
|
||||
borderWidth: 2,
|
||||
borderColor: '#ff5722',
|
||||
textAlign: 'center',
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
|||
29
packages/idraw/src/event.ts
Normal file
29
packages/idraw/src/event.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { middlewareEventScale, middlewareEventSelect } from '@idraw/core';
|
||||
import type { CoreEvent } from '@idraw/types';
|
||||
|
||||
export interface IDrawEventKeys {
|
||||
select: typeof middlewareEventSelect;
|
||||
scale: typeof middlewareEventScale;
|
||||
change: 'change';
|
||||
}
|
||||
|
||||
export type IDrawEvent = CoreEvent & {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
// TODO
|
||||
const EventKeys = {} as {
|
||||
select: typeof middlewareEventSelect;
|
||||
scale: typeof middlewareEventScale;
|
||||
change: 'change';
|
||||
};
|
||||
Object.defineProperty(EventKeys, 'select', {
|
||||
value: middlewareEventSelect,
|
||||
writable: false
|
||||
});
|
||||
Object.defineProperty(EventKeys, 'scale', {
|
||||
value: middlewareEventScale,
|
||||
writable: false
|
||||
});
|
||||
|
||||
export { EventKeys };
|
||||
|
|
@ -1,43 +1,45 @@
|
|||
import { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler, MiddlewareRuler } from '@idraw/core';
|
||||
import type { PointSize, IDrawOptions, Data, ViewSizeInfo, IDrawEvent } from '@idraw/types';
|
||||
import { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler, MiddlewareRuler, MiddlewareTextEditor, middlewareEventSelect } from '@idraw/core';
|
||||
import type { PointSize, IDrawOptions, Data, ViewSizeInfo } from '@idraw/types';
|
||||
import type { IDrawEvent } from './event';
|
||||
|
||||
export class iDraw {
|
||||
private _core: Core;
|
||||
private _opts: IDrawOptions;
|
||||
#core: Core;
|
||||
// private #opts: IDrawOptions;
|
||||
|
||||
constructor(mount: HTMLDivElement, opts: IDrawOptions) {
|
||||
const core = new Core(mount, opts);
|
||||
this._core = core;
|
||||
this._opts = opts;
|
||||
this.#core = core;
|
||||
// this.#opts = opts;
|
||||
core.use(MiddlewareScroller);
|
||||
core.use(MiddlewareSelector);
|
||||
core.use(MiddlewareScaler);
|
||||
core.use(MiddlewareRuler);
|
||||
core.use(MiddlewareTextEditor);
|
||||
}
|
||||
|
||||
setData(data: Data) {
|
||||
this._core.setData(data);
|
||||
this.#core.setData(data);
|
||||
}
|
||||
|
||||
getData(): Data | null {
|
||||
return this._core.getData();
|
||||
return this.#core.getData();
|
||||
}
|
||||
|
||||
selectElement() {
|
||||
// TODO
|
||||
selectElements(uuids: string[]) {
|
||||
this.trigger(middlewareEventSelect, { uuids });
|
||||
}
|
||||
|
||||
selectElementByIndex() {
|
||||
// TODO
|
||||
}
|
||||
// selectElementByIndex() {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
cancelElement() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
cancelElementByIndex() {
|
||||
// TODO
|
||||
}
|
||||
// cancelElementByIndex() {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
updateElement() {
|
||||
// TODO
|
||||
|
|
@ -76,23 +78,23 @@ export class iDraw {
|
|||
}
|
||||
|
||||
scale(opts: { scale: number; point: PointSize }) {
|
||||
this._core.scale(opts);
|
||||
this.#core.scale(opts);
|
||||
}
|
||||
|
||||
resize(opts: Partial<ViewSizeInfo>) {
|
||||
this._core.resize(opts);
|
||||
this.#core.resize(opts);
|
||||
}
|
||||
|
||||
on<T extends keyof IDrawEvent>(name: T, callback: (e: IDrawEvent[T]) => void) {
|
||||
this._core.on(name, callback);
|
||||
this.#core.on(name, callback);
|
||||
}
|
||||
|
||||
off<T extends keyof IDrawEvent>(name: T, callback: (e: IDrawEvent[T]) => void) {
|
||||
this._core.off(name, callback);
|
||||
this.#core.off(name, callback);
|
||||
}
|
||||
|
||||
trigger<T extends keyof IDrawEvent>(name: T, e: IDrawEvent[T]) {
|
||||
this._core.trigger(name, e);
|
||||
this.#core.trigger(name, e);
|
||||
}
|
||||
|
||||
// scrollLeft() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
export { iDraw } from './idraw';
|
||||
export type { IDrawEvent, IDrawEventKeys } from './event';
|
||||
export type * from '@idraw/types';
|
||||
export { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler } from '@idraw/core';
|
||||
export {
|
||||
Core,
|
||||
MiddlewareSelector,
|
||||
middlewareEventSelect,
|
||||
MiddlewareScroller,
|
||||
MiddlewareScaler,
|
||||
middlewareEventScale,
|
||||
MiddlewareRuler,
|
||||
middlewareEventRuler,
|
||||
MiddlewareTextEditor
|
||||
} from '@idraw/core';
|
||||
export { Renderer } from '@idraw/renderer';
|
||||
export {
|
||||
delay,
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ export interface BoardMiddlewareOptions<S extends Record<any | symbol, any> = Re
|
|||
viewer: BoardViewer;
|
||||
calculator: ViewCalculator;
|
||||
eventHub: UtilEventEmitter<E>;
|
||||
container?: HTMLDivElement;
|
||||
canvas?: HTMLCanvasElement;
|
||||
}
|
||||
|
||||
export type BoardMiddleware<S extends Record<any | symbol, any> = any, E extends BoardExtendEvent = Record<string, any>> = (
|
||||
|
|
@ -93,6 +95,7 @@ export type BoardMiddleware<S extends Record<any | symbol, any> = any, E extends
|
|||
|
||||
export interface BoardOptions {
|
||||
viewContent: ViewContent;
|
||||
container?: HTMLDivElement;
|
||||
}
|
||||
|
||||
export interface BoardViewerFrameSnapshot<S extends Record<any | symbol, any> = any> {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { DefaultElementDetailConfig } from '@idraw/types';
|
|||
|
||||
export function getDefaultElementDetailConfig(): DefaultElementDetailConfig {
|
||||
const config: DefaultElementDetailConfig = {
|
||||
boxSizing: 'border-box',
|
||||
boxSizing: 'center-line',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000000',
|
||||
shadowColor: '#000000',
|
||||
|
|
|
|||
Loading…
Reference in a new issue