Skip to content

Commit

Permalink
feat: add middleware texteditor and enhance middlewares
Browse files Browse the repository at this point in the history
  • Loading branch information
chenshenhai committed Nov 25, 2023
1 parent 69e49f2 commit 532f604
Show file tree
Hide file tree
Showing 15 changed files with 324 additions and 61 deletions.
4 changes: 2 additions & 2 deletions packages/board/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
45 changes: 26 additions & 19 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -34,35 +36,40 @@ export class Core {
contextWidth: width,
contextHeight: height
});
this._board = board;
this.#board = board;
this.resize(sharer.getActiveViewSizeInfo());
const eventHub = board.getEventHub();
new Cursor(container, {
eventHub
});
}

#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({
Expand All @@ -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);
}
}
1 change: 0 additions & 1 deletion packages/core/src/lib/cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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-')) {
Expand Down
29 changes: 19 additions & 10 deletions packages/core/src/middleware/ruler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ 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();
}
});
return {
mode: key,
isDefault: true,
beforeDrawFrame: ({ snapshot }) => {
if (showRuler === true) {
if (show === true) {
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
const viewSizeInfo = getViewSizeInfoFromSnapshot(snapshot);
drawRulerBackground(helperContext, { viewScaleInfo, viewSizeInfo });
Expand All @@ -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
});
}
}
}
};
Expand Down
15 changes: 11 additions & 4 deletions packages/core/src/middleware/ruler/util.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -181,6 +186,8 @@ export function drawRulerBackground(
ctx.closePath();
ctx.fillStyle = background;
ctx.fill();
ctx.lineWidth = lineSize;
ctx.setLineDash([]);
ctx.strokeStyle = borderColor;
ctx.stroke();
}
Expand All @@ -206,9 +213,9 @@ export function drawUnderGrid(
} else {
ctx.strokeStyle = gridColor;
}

ctx.lineWidth = 1;
ctx.closePath();
ctx.lineWidth = lineSize;
ctx.setLineDash([]);
ctx.stroke();
}

Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/middleware/scaler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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();
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/middleware/scroller/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -246,6 +246,7 @@ function drawScrollerInfo(helperContext: ViewContext2D, opts: { viewScaleInfo: V
});

ctx.globalAlpha = 1;

return {
xThumbRect,
yThumbRect
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/middleware/selector/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
// keyDebugStartHorizontal,
// keyDebugStartVertical
} from './config';
import { middlewareEventTextEdit } from '../text-editor';

export const middlewareEventSelect: string = '@middleware/select';

Expand Down Expand Up @@ -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);
},
Expand Down
Loading

0 comments on commit 532f604

Please sign in to comment.