|
@@ -3,13 +3,13 @@
|
|
|
* SPDX-License-Identifier: MIT
|
|
* SPDX-License-Identifier: MIT
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-import { debounce } from 'lodash-es';
|
|
|
|
|
|
|
+import { throttle } from 'lodash-es';
|
|
|
import { inject, injectable } from 'inversify';
|
|
import { inject, injectable } from 'inversify';
|
|
|
import { Disposable, DisposableCollection, IPoint, Rectangle } from '@flowgram.ai/utils';
|
|
import { Disposable, DisposableCollection, IPoint, Rectangle } from '@flowgram.ai/utils';
|
|
|
-import { FlowNodeEntity, FlowNodeTransformData } from '@flowgram.ai/document';
|
|
|
|
|
|
|
+import { FlowNodeTransformData } from '@flowgram.ai/document';
|
|
|
import { FlowNodeBaseType } from '@flowgram.ai/document';
|
|
import { FlowNodeBaseType } from '@flowgram.ai/document';
|
|
|
import { FlowDocument } from '@flowgram.ai/document';
|
|
import { FlowDocument } from '@flowgram.ai/document';
|
|
|
-import { EntityManager, MouseTouchEvent, PlaygroundConfigEntity } from '@flowgram.ai/core';
|
|
|
|
|
|
|
+import { MouseTouchEvent, PlaygroundConfigEntity } from '@flowgram.ai/core';
|
|
|
|
|
|
|
|
import type { MinimapRenderContext, MinimapServiceOptions, MinimapCanvasStyle } from './type';
|
|
import type { MinimapRenderContext, MinimapServiceOptions, MinimapCanvasStyle } from './type';
|
|
|
import { MinimapDraw } from './draw';
|
|
import { MinimapDraw } from './draw';
|
|
@@ -19,8 +19,6 @@ import { MinimapDefaultCanvasStyle, MinimapDefaultOptions } from './constant';
|
|
|
export class FlowMinimapService {
|
|
export class FlowMinimapService {
|
|
|
@inject(FlowDocument) private readonly document: FlowDocument;
|
|
@inject(FlowDocument) private readonly document: FlowDocument;
|
|
|
|
|
|
|
|
- @inject(EntityManager) private readonly entityManager: EntityManager;
|
|
|
|
|
-
|
|
|
|
|
@inject(PlaygroundConfigEntity)
|
|
@inject(PlaygroundConfigEntity)
|
|
|
private readonly playgroundConfig: PlaygroundConfigEntity;
|
|
private readonly playgroundConfig: PlaygroundConfigEntity;
|
|
|
|
|
|
|
@@ -38,6 +36,8 @@ export class FlowMinimapService {
|
|
|
|
|
|
|
|
private initialized;
|
|
private initialized;
|
|
|
|
|
|
|
|
|
|
+ private visible: boolean = false;
|
|
|
|
|
+
|
|
|
private isDragging;
|
|
private isDragging;
|
|
|
|
|
|
|
|
private style: MinimapCanvasStyle;
|
|
private style: MinimapCanvasStyle;
|
|
@@ -58,12 +58,8 @@ export class FlowMinimapService {
|
|
|
public init(options?: Partial<MinimapServiceOptions>) {
|
|
public init(options?: Partial<MinimapServiceOptions>) {
|
|
|
this.options = MinimapDefaultOptions;
|
|
this.options = MinimapDefaultOptions;
|
|
|
Object.assign(this.options, options);
|
|
Object.assign(this.options, options);
|
|
|
- this.setDebounce({
|
|
|
|
|
- enableDebounce: this.options.enableInactiveDebounce,
|
|
|
|
|
- debounceTime: this.options.inactiveDebounceTime,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ this.setThrottle(this.options.inactiveThrottleTime);
|
|
|
this.initStyle();
|
|
this.initStyle();
|
|
|
- this.mountListener();
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public dispose(): void {
|
|
public dispose(): void {
|
|
@@ -73,6 +69,10 @@ export class FlowMinimapService {
|
|
|
this.removeEventListeners();
|
|
this.removeEventListeners();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ setVisible(visible: boolean) {
|
|
|
|
|
+ this.visible = visible;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public setActivate(activate: boolean): void {
|
|
public setActivate(activate: boolean): void {
|
|
|
if (activate === this.activated) {
|
|
if (activate === this.activated) {
|
|
|
return;
|
|
return;
|
|
@@ -83,16 +83,10 @@ export class FlowMinimapService {
|
|
|
}
|
|
}
|
|
|
this.activated = activate;
|
|
this.activated = activate;
|
|
|
if (activate) {
|
|
if (activate) {
|
|
|
- this.setDebounce({
|
|
|
|
|
- enableDebounce: this.options.enableActiveDebounce,
|
|
|
|
|
- debounceTime: this.options.activeDebounceTime,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ this.setThrottle(this.options.activeThrottleTime);
|
|
|
this.addEventListeners();
|
|
this.addEventListeners();
|
|
|
} else {
|
|
} else {
|
|
|
- this.setDebounce({
|
|
|
|
|
- enableDebounce: this.options.enableInactiveDebounce,
|
|
|
|
|
- debounceTime: this.options.inactiveDebounceTime,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ this.setThrottle(this.options.inactiveThrottleTime);
|
|
|
this.removeEventListeners();
|
|
this.removeEventListeners();
|
|
|
}
|
|
}
|
|
|
this.render();
|
|
this.render();
|
|
@@ -125,22 +119,17 @@ export class FlowMinimapService {
|
|
|
: 'unset';
|
|
: 'unset';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private setDebounce(params: { enableDebounce: boolean; debounceTime: number }) {
|
|
|
|
|
- const { enableDebounce, debounceTime } = params;
|
|
|
|
|
- if (enableDebounce) {
|
|
|
|
|
- this.render = debounce(this._render, debounceTime);
|
|
|
|
|
- } else {
|
|
|
|
|
- this.render = this._render;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ private setThrottle(throttleTime: number) {
|
|
|
|
|
+ this.render = throttle(this._render, throttleTime);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 触发渲染
|
|
* 触发渲染
|
|
|
*/
|
|
*/
|
|
|
- private render: () => void = this._render;
|
|
|
|
|
|
|
+ public render: () => void = this._render;
|
|
|
|
|
|
|
|
private _render(): void {
|
|
private _render(): void {
|
|
|
- if (!this.initialized) {
|
|
|
|
|
|
|
+ if (!this.initialized || !this.visible) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
const renderContext = this.createRenderContext();
|
|
const renderContext = this.createRenderContext();
|
|
@@ -148,8 +137,8 @@ export class FlowMinimapService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private createRenderContext(): MinimapRenderContext {
|
|
private createRenderContext(): MinimapRenderContext {
|
|
|
- const { canvas, context2D, nodes } = this;
|
|
|
|
|
- const nodeTransforms: FlowNodeTransformData[] = this.nodeTransforms(nodes);
|
|
|
|
|
|
|
+ const { canvas, context2D } = this;
|
|
|
|
|
+ const nodeTransforms: FlowNodeTransformData[] = this.transformVisibles;
|
|
|
const nodeRects: Rectangle[] = nodeTransforms.map((transform) => transform.bounds);
|
|
const nodeRects: Rectangle[] = nodeTransforms.map((transform) => transform.bounds);
|
|
|
const viewRect: Rectangle = this.viewRect();
|
|
const viewRect: Rectangle = this.viewRect();
|
|
|
const renderRect: Rectangle = this.renderRect(nodeRects).withPadding({
|
|
const renderRect: Rectangle = this.renderRect(nodeRects).withPadding({
|
|
@@ -258,8 +247,13 @@ export class FlowMinimapService {
|
|
|
return { scale, offset };
|
|
return { scale, offset };
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private get nodes(): FlowNodeEntity[] {
|
|
|
|
|
- return this.document.getAllNodes().filter((node) => {
|
|
|
|
|
|
|
+ private get transformVisibles(): FlowNodeTransformData[] {
|
|
|
|
|
+ const transformVisible = this.document.getRenderDatas<FlowNodeTransformData>(
|
|
|
|
|
+ FlowNodeTransformData,
|
|
|
|
|
+ false
|
|
|
|
|
+ );
|
|
|
|
|
+ return transformVisible.filter((transform) => {
|
|
|
|
|
+ const node = transform.entity;
|
|
|
// 去除不可见节点
|
|
// 去除不可见节点
|
|
|
if (node.hidden) return false;
|
|
if (node.hidden) return false;
|
|
|
// 去除根节点
|
|
// 去除根节点
|
|
@@ -275,10 +269,6 @@ export class FlowMinimapService {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private nodeTransforms(nodes: FlowNodeEntity[]): FlowNodeTransformData[] {
|
|
|
|
|
- return nodes.map((node) => node.getData(FlowNodeTransformData)).filter(Boolean);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private renderRect(rects: Rectangle[]): Rectangle {
|
|
private renderRect(rects: Rectangle[]): Rectangle {
|
|
|
return Rectangle.enlarge(rects);
|
|
return Rectangle.enlarge(rects);
|
|
|
}
|
|
}
|
|
@@ -288,11 +278,6 @@ export class FlowMinimapService {
|
|
|
return new Rectangle(scrollX / zoom, scrollY / zoom, width / zoom, height / zoom);
|
|
return new Rectangle(scrollX / zoom, scrollY / zoom, width / zoom, height / zoom);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private mountListener(): void {
|
|
|
|
|
- const entityManagerDisposer = this.entityManager.onEntityChange(() => this.render());
|
|
|
|
|
- this.toDispose.push(entityManagerDisposer);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/** 计算画布坐标系下的矩形 */
|
|
/** 计算画布坐标系下的矩形 */
|
|
|
private rectOnCanvas(params: { rect: Rectangle; scale: number; offset: IPoint }): Rectangle {
|
|
private rectOnCanvas(params: { rect: Rectangle; scale: number; offset: IPoint }): Rectangle {
|
|
|
const { rect, scale, offset } = params;
|
|
const { rect, scale, offset } = params;
|