Skip to content

Commit

Permalink
Merge pull request #299 from idrawjs/dev-v0.4
Browse files Browse the repository at this point in the history
feat: add reference lines for middleware select
  • Loading branch information
chenshenhai authored Mar 16, 2024
2 parents 4676588 + 66843c1 commit 9e92d17
Show file tree
Hide file tree
Showing 36 changed files with 1,146 additions and 199 deletions.
54 changes: 44 additions & 10 deletions packages/board/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import type {
ViewSizeInfo,
PointSize,
BoardExtendEventMap,
UtilEventEmitter
UtilEventEmitter,
ModifyOptions
} from '@idraw/types';
import { Calculator } from './lib/calculator';
import { BoardWatcher } from './lib/watcher';
Expand Down Expand Up @@ -288,16 +289,41 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
return this.#renderer;
}

setData(data: Data): { viewSizeInfo: ViewSizeInfo } {
setData(
data: Data,
opts?: {
modifiedOptions?: ModifyOptions; // TODO
}
): { viewSizeInfo: ViewSizeInfo } {
const { modifiedOptions } = opts || {};
const sharer = this.#sharer;
this.#sharer.setActiveStorage('data', data);
const viewSizeInfo = sharer.getActiveViewSizeInfo();
const viewScaleInfo = sharer.getActiveViewScaleInfo();
// const currentScaleInfo = sharer.getActiveViewScaleInfo();
const newViewContextSize = calcElementsContextSize(data.elements, {
viewWidth: viewSizeInfo.width,
viewHeight: viewSizeInfo.height,
extend: true
});
if (modifiedOptions) {
// TODO
// this.#viewer.modifyViewVisibleInfoMap(data, {
// viewSizeInfo,
// viewScaleInfo,
// modifyOptions: modifiedOptions
// });
this.#viewer.resetViewVisibleInfoMap(data, {
viewSizeInfo,
viewScaleInfo
});
} else {
this.#viewer.resetViewVisibleInfoMap(data, {
viewSizeInfo,
viewScaleInfo
});
}

this.#viewer.drawFrame();
const newViewSizeInfo = {
...viewSizeInfo,
Expand Down Expand Up @@ -352,22 +378,30 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
}
}

scale(opts: { scale: number; point: PointSize }) {
scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }) {
const viewer = this.#viewer;
const { moveX, moveY } = viewer.scale(opts);
viewer.scroll({ moveX, moveY });
const { ignoreUpdateVisibleStatus } = opts;
const { moveX, moveY } = viewer.scale({
...opts,
...{
ignoreUpdateVisibleStatus: true
}
});
viewer.scroll({ moveX, moveY, ignoreUpdateVisibleStatus });
}

scroll(opts: { moveX: number; moveY: number }) {
return this.#viewer.scroll(opts);
scroll(opts: { moveX: number; moveY: number; ignoreUpdateVisibleStatus?: boolean }) {
const result = this.#viewer.scroll(opts);
return result;
}

updateViewScaleInfo(opts: { scale: number; offsetX: number; offsetY: number }) {
return this.#viewer.updateViewScaleInfo(opts);
const result = this.#viewer.updateViewScaleInfo(opts);
return result;
}

resize(newViewSize: ViewSizeInfo) {
const viewSize = this.#viewer.resize(newViewSize);
resize(newViewSize: ViewSizeInfo, opts?: { ignoreUpdateVisibleStatus?: boolean }) {
const viewSize = this.#viewer.resize(newViewSize, opts);
const { width, height, devicePixelRatio } = newViewSize;
const { boardContent } = this.#opts;
boardContent.viewContext.$resize({ width, height, devicePixelRatio });
Expand Down
180 changes: 174 additions & 6 deletions packages/board/src/lib/calculator.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,56 @@
import type { Point, Data, Element, ElementType, ViewCalculator, ViewCalculatorOptions, ViewScaleInfo, ElementSize, ViewSizeInfo } from '@idraw/types';
import { calcViewElementSize, isViewPointInElement, getViewPointAtElement, isElementInView } from '@idraw/util';
import type {
Point,
Data,
Element,
ElementType,
ViewCalculator,
ViewCalculatorOptions,
ViewScaleInfo,
ElementSize,
ViewSizeInfo,
ViewCalculatorStorage,
ViewRectInfo,
ModifyOptions,
ViewVisibleInfo
} from '@idraw/types';
import {
is,
isViewPointInElement,
getViewPointAtElement,
isElementInView,
Store,
sortElementsViewVisiableInfoMap,
updateViewVisibleInfoMapStatus,
calcViewPointSize,
findElementFromListByPosition,
getGroupQueueByElementPosition,
calcElementOriginRectInfo,
originRectInfoToRangeRectInfo
} from '@idraw/util';

export class Calculator implements ViewCalculator {
#opts: ViewCalculatorOptions;
#store: Store<ViewCalculatorStorage>;

constructor(opts: ViewCalculatorOptions) {
this.#opts = opts;
this.#store = new Store<ViewCalculatorStorage>({
defaultStorage: {
viewVisibleInfoMap: {},
visibleCount: 0,
invisibleCount: 0
}
});
}

destroy() {
this.#opts = null as any;
toGridNum(num: number): number {
// TODO
// const gridUnitSize = 1; // px;
return Math.round(num);
}

elementSize(size: ElementSize, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): ElementSize {
return calcViewElementSize(size, { viewScaleInfo, viewSizeInfo });
destroy() {
this.#opts = null as any;
}

isElementInView(elem: ElementSize, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): boolean {
Expand All @@ -37,4 +74,135 @@ export class Calculator implements ViewCalculator {
const context2d = this.#opts.viewContext;
return getViewPointAtElement(p, { ...opts, ...{ context2d } });
}

resetViewVisibleInfoMap(
data: Data,
opts: {
viewScaleInfo: ViewScaleInfo;
viewSizeInfo: ViewSizeInfo;
}
): void {
if (data) {
const { viewVisibleInfoMap, invisibleCount, visibleCount } = sortElementsViewVisiableInfoMap(data.elements, opts);
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
this.#store.set('invisibleCount', invisibleCount);
this.#store.set('visibleCount', visibleCount);
}
}

updateVisiableStatus(opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }) {
const { viewVisibleInfoMap, invisibleCount, visibleCount } = updateViewVisibleInfoMapStatus(this.#store.get('viewVisibleInfoMap'), opts);
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
this.#store.set('invisibleCount', invisibleCount);
this.#store.set('visibleCount', visibleCount);
}

calcViewRectInfoFromOrigin(
uuid: string,
opts: {
checkVisible?: boolean;
viewScaleInfo: ViewScaleInfo;
viewSizeInfo: ViewSizeInfo;
}
): ViewRectInfo | null {
const infoData = this.#store.get('viewVisibleInfoMap')[uuid];
if (!infoData?.originRectInfo) {
return null;
}
const { checkVisible, viewScaleInfo, viewSizeInfo } = opts;
const { center, left, right, bottom, top, topLeft, topRight, bottomLeft, bottomRight } = infoData.originRectInfo;
if (checkVisible === true && infoData.isVisibleInView === false) {
return null;
}
const calcOpts = { viewScaleInfo, viewSizeInfo };

const viewRectInfo: ViewRectInfo = {
center: calcViewPointSize(center, calcOpts),
left: calcViewPointSize(left, calcOpts),
right: calcViewPointSize(right, calcOpts),
bottom: calcViewPointSize(bottom, calcOpts),
top: calcViewPointSize(top, calcOpts),
topLeft: calcViewPointSize(topLeft, calcOpts),
topRight: calcViewPointSize(topRight, calcOpts),
bottomLeft: calcViewPointSize(bottomLeft, calcOpts),
bottomRight: calcViewPointSize(bottomRight, calcOpts)
};

return viewRectInfo;
}

calcViewRectInfoFromRange(
uuid: string,
opts: {
checkVisible?: boolean;
viewScaleInfo: ViewScaleInfo;
viewSizeInfo: ViewSizeInfo;
}
): ViewRectInfo | null {
const infoData = this.#store.get('viewVisibleInfoMap')[uuid];
if (!infoData?.originRectInfo) {
return null;
}
const { checkVisible, viewScaleInfo, viewSizeInfo } = opts;
const { center, left, right, bottom, top, topLeft, topRight, bottomLeft, bottomRight } = infoData.rangeRectInfo;
if (checkVisible === true && infoData.isVisibleInView === false) {
return null;
}
const calcOpts = { viewScaleInfo, viewSizeInfo };

const viewRectInfo: ViewRectInfo = {
center: calcViewPointSize(center, calcOpts),
left: calcViewPointSize(left, calcOpts),
right: calcViewPointSize(right, calcOpts),
bottom: calcViewPointSize(bottom, calcOpts),
top: calcViewPointSize(top, calcOpts),
topLeft: calcViewPointSize(topLeft, calcOpts),
topRight: calcViewPointSize(topRight, calcOpts),
bottomLeft: calcViewPointSize(bottomLeft, calcOpts),
bottomRight: calcViewPointSize(bottomRight, calcOpts)
};

return viewRectInfo;
}

modifyViewVisibleInfoMap(
data: Data,
opts: {
modifyOptions: ModifyOptions; // TODO
viewScaleInfo: ViewScaleInfo;
viewSizeInfo: ViewSizeInfo;
}
): void {
const { modifyOptions, viewScaleInfo, viewSizeInfo } = opts;
const { type, content } = modifyOptions;
const list = data.elements;
const viewVisibleInfoMap = this.#store.get('viewVisibleInfoMap');
if (type === 'deleteElement') {
const { element } = content as ModifyOptions<'deleteElement'>['content'];
delete viewVisibleInfoMap[element.uuid];
} else if (type === 'addElement' || type === 'updateElement') {
const { position } = content as ModifyOptions<'addElement'>['content'];
const element = findElementFromListByPosition(position, data.elements);
const groupQueue = getGroupQueueByElementPosition(list, position);
if (element) {
const originRectInfo = calcElementOriginRectInfo(element, {
groupQueue: groupQueue || []
});
const newViewVisibleInfo: ViewVisibleInfo = {
originRectInfo,
rangeRectInfo: is.angle(element.angle) ? originRectInfoToRangeRectInfo(originRectInfo) : originRectInfo,
isVisibleInView: true,
isGroup: element?.type === 'group',
position: [...position]
};
viewVisibleInfoMap[element.uuid] = newViewVisibleInfo;
if (type === 'updateElement') {
this.updateVisiableStatus({ viewScaleInfo, viewSizeInfo });
}
}
} else if (type === 'moveElement') {
this.resetViewVisibleInfoMap(data, { viewScaleInfo, viewSizeInfo });
}
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
}
}
8 changes: 4 additions & 4 deletions packages/board/src/lib/sharer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export class Sharer implements StoreSharer<Record<string | number | symbol, any>
return this.#activeStore.set(key, storage);
}

getActiveStoreSnapshot(): ActiveStore {
return this.#activeStore.getSnapshot();
getActiveStoreSnapshot(opts?: { deepClone?: boolean }): ActiveStore {
return this.#activeStore.getSnapshot(opts);
}

getSharedStorage(key: string | number | symbol): any {
Expand All @@ -52,8 +52,8 @@ export class Sharer implements StoreSharer<Record<string | number | symbol, any>
return this.#sharedStore.set(key, storage);
}

getSharedStoreSnapshot(): Record<string, any> {
return this.#sharedStore.getSnapshot();
getSharedStoreSnapshot(opts?: { deepClone?: boolean }): Record<string, any> {
return this.#sharedStore.getSnapshot(opts);
}

// get/set active info
Expand Down
Loading

0 comments on commit 9e92d17

Please sign in to comment.