From a1f5af883ce29aced31662dacb7641f7156a4b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=B1=AA=E7=8F=A3?= <519367854@qq.com> Date: Wed, 3 Apr 2024 15:49:36 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96hook=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../container/simulator.component.ts | 1 - .../container/viewport.component.ts | 6 +- .../components/panels/view-panel.component.ts | 7 +- .../widgets/aux-tool/aux-tool.widget.ts | 9 ++- .../widgets/aux-tool/helpers.widget.ts | 22 ++---- .../widgets/aux-tool/selection.widget.ts | 34 +++++++--- .../component-tree/component-tree.widget.ts | 10 ++- .../components/widgets/empty/empty.widget.ts | 10 ++- src/app/services/hook.service.ts | 68 +++++++++++++++++++ 9 files changed, 121 insertions(+), 46 deletions(-) create mode 100644 src/app/services/hook.service.ts diff --git a/src/app/components/container/simulator.component.ts b/src/app/components/container/simulator.component.ts index 25590a3..9c5df85 100644 --- a/src/app/components/container/simulator.component.ts +++ b/src/app/components/container/simulator.component.ts @@ -47,7 +47,6 @@ export class SimulatorComponent implements AfterViewInit { } ngAfterViewInit(): void { - console.log('template>>>', this.template); this.responsiveService.subscribe(() => this.cdr.detectChanges()); } diff --git a/src/app/components/container/viewport.component.ts b/src/app/components/container/viewport.component.ts index f569711..4e31360 100644 --- a/src/app/components/container/viewport.component.ts +++ b/src/app/components/container/viewport.component.ts @@ -3,9 +3,9 @@ import { SharedModule } from '../../shared/shared.module'; import { usePrefix } from '../../utils'; import { AuxToolWidget } from '@/app/components/widgets/aux-tool/aux-tool.widget'; import { EmptyWidget } from '@/app/components/widgets/empty/empty.widget'; -import { Engine } from '@/app/core/models'; import { globalThisPolyfill } from '@/app/shared/globalThisPolyfill'; import { Viewport } from '@/app/core/models/viewport'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-viewport', @@ -28,10 +28,10 @@ export class ViewportComponent implements AfterViewInit, OnDestroy { viewport: Viewport; - constructor(private designer: Engine) {} + constructor(private hookService: HookService) {} ngAfterViewInit(): void { - this.viewport = this.designer.workbench.currentWorkspace.viewport; + this.viewport = this.hookService.useViewport(); this.viewport.onMount(this.container.nativeElement, globalThisPolyfill); } diff --git a/src/app/components/panels/view-panel.component.ts b/src/app/components/panels/view-panel.component.ts index ac8e87c..67730e1 100644 --- a/src/app/components/panels/view-panel.component.ts +++ b/src/app/components/panels/view-panel.component.ts @@ -3,6 +3,7 @@ import { WorkspacePanelItemComponent } from '@/app/components/panels/workspace-p import { WorkbenchTypes } from '@/app/core/types'; import { Workbench } from '@/app/core/models/workbench'; import { ViewportComponent } from '@/app/components/container/viewport.component'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-view-panel', @@ -29,7 +30,7 @@ export class ViewPanelComponent implements OnChanges { @Input() dragTipsDirection?: 'left' | 'right'; - workbench: Workbench = { type: 'DESIGNABLE' } as any; + workbench: Workbench; defaultStyle = signal({ overflow: 'overlay', @@ -38,6 +39,10 @@ export class ViewPanelComponent implements OnChanges { userSelect: 'text' }); + constructor(private hookService: HookService) { + this.workbench = this.hookService.useWorkbench(); + } + ngOnChanges(changes: SimpleChanges): void { if (changes.scrollable) { this.defaultStyle.set({ diff --git a/src/app/components/widgets/aux-tool/aux-tool.widget.ts b/src/app/components/widgets/aux-tool/aux-tool.widget.ts index b299d0e..27e5d8c 100644 --- a/src/app/components/widgets/aux-tool/aux-tool.widget.ts +++ b/src/app/components/widgets/aux-tool/aux-tool.widget.ts @@ -2,6 +2,7 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, ViewChil import { usePrefix } from '@/app/utils'; import { Engine } from '@/app/core/models'; import { SelectionWidget } from './selection.widget'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-aux-tool-widget', @@ -20,12 +21,14 @@ export class AuxToolWidget implements AfterViewInit { @ViewChild('ref') ref: ElementRef; - constructor(private engine: Engine) {} + constructor( + private engine: Engine, + private hookService: HookService + ) {} ngAfterViewInit(): void { const element = this.ref.nativeElement; - const viewport = this.engine.workbench.currentWorkspace.viewport; - + const viewport = this.hookService.useViewport(); this.engine.subscribeWith('viewport:scroll', () => { if (viewport.isIframe && element) { element.style.transform = `perspective(1px) translate3d(${-viewport.scrollX}px,${-viewport.scrollY}px,0)`; diff --git a/src/app/components/widgets/aux-tool/helpers.widget.ts b/src/app/components/widgets/aux-tool/helpers.widget.ts index 8e20e18..51436f4 100644 --- a/src/app/components/widgets/aux-tool/helpers.widget.ts +++ b/src/app/components/widgets/aux-tool/helpers.widget.ts @@ -12,6 +12,7 @@ import { Engine, TreeNode } from '@/app/core/models'; import { usePrefix } from '@/app/utils'; import { SelectorWidget } from '@/app/components/widgets/aux-tool/selector.widget'; import { Viewport } from '@/app/core/models/viewport'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-helpers-widget', @@ -42,32 +43,21 @@ export class HelpersWidget implements OnChanges { viewport: Viewport; - promise: Promise; - - resolve: () => void; - - reject: (error) => void; - constructor( private designer: Engine, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private hookService: HookService ) { - this.viewport = this.designer.workbench.currentWorkspace.viewport; - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve; - this.reject = reject; - }); + this.viewport = this.hookService.useViewport(); } ngOnChanges(changes: SimpleChanges): void { if (changes.nodeRect && changes.nodeRect.currentValue) { - this.update(); - this.resolve(); + setTimeout(() => this.update()); } } - async update() { - await this.promise; + update() { const helpersRect = this.container?.nativeElement?.getBoundingClientRect(); if (!helpersRect || !this.nodeRect) return; this.position = diff --git a/src/app/components/widgets/aux-tool/selection.widget.ts b/src/app/components/widgets/aux-tool/selection.widget.ts index b1dc97e..c5a158a 100644 --- a/src/app/components/widgets/aux-tool/selection.widget.ts +++ b/src/app/components/widgets/aux-tool/selection.widget.ts @@ -1,4 +1,12 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + Input, + OnChanges, + SimpleChanges +} from '@angular/core'; import { usePrefix } from '@/app/utils'; import { Engine, TreeNode } from '@/app/core/models'; import { Selection } from '@/app/core/models/selection'; @@ -6,6 +14,8 @@ import { Cursor } from '@/app/core/models/cursor'; import { MoveHelper } from '@/app/core/models/move-helper'; import { AttributeDirective } from '@/app/directive'; import { HelpersWidget } from '@/app/components/widgets/aux-tool/helpers.widget'; +import { fromEvent } from 'rxjs'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-selection-box-widget', @@ -22,7 +32,7 @@ import { HelpersWidget } from '@/app/components/widgets/aux-tool/helpers.widget' imports: [AttributeDirective, HelpersWidget], changeDetection: ChangeDetectionStrategy.Default }) -export class SelectionBoxWidget implements OnChanges { +export class SelectionBoxWidget implements OnChanges, AfterViewInit { @Input() node: TreeNode; @Input() showHelpers: boolean; @@ -52,9 +62,14 @@ export class SelectionBoxWidget implements OnChanges { }; constructor( private designer: Engine, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private hookService: HookService ) {} + ngAfterViewInit(): void { + fromEvent(window, 'resize').subscribe(() => this.update()); + } + ngOnChanges(changes: SimpleChanges): void { if (changes.node && changes.node.currentValue) { setTimeout(() => this.update()); @@ -62,7 +77,7 @@ export class SelectionBoxWidget implements OnChanges { } update() { - this.nodeRect = this.designer.workbench.currentWorkspace.viewport.getValidNodeOffsetRect(this.node) as any; + this.nodeRect = this.hookService.useViewport().getValidNodeOffsetRect(this.node) as any; this.attributes = { [this.designer.props?.nodeSelectionIdAttrName]: this.node.id }; @@ -97,11 +112,10 @@ export class SelectionWidget { tree: TreeNode; - constructor(private designer: Engine) { - const operation = this.designer.workbench.currentWorkspace.operation; - this.selection = operation.selection; - this.viewportMoveHelper = operation.moveHelper; - this.tree = operation.tree; - this.cursor = this.designer.cursor; + constructor(private hookService: HookService) { + this.selection = this.hookService.useSelection(); + this.viewportMoveHelper = this.hookService.useMoveHelper(); + this.tree = this.hookService.useTree(); + this.cursor = this.hookService.useCursor(); } } diff --git a/src/app/components/widgets/component-tree/component-tree.widget.ts b/src/app/components/widgets/component-tree/component-tree.widget.ts index a8e9ffa..ba99f0a 100644 --- a/src/app/components/widgets/component-tree/component-tree.widget.ts +++ b/src/app/components/widgets/component-tree/component-tree.widget.ts @@ -13,6 +13,7 @@ import { IDesignerComponents } from '../../types'; import { GlobalRegistry } from '@/app/core/registry'; import { Engine, TreeNode } from '@/app/core/models'; import { AttributeDirective } from '@/app/directive'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-component-tree-widget', @@ -41,7 +42,8 @@ export class ComponentTreeWidget implements OnChanges, AfterViewInit { constructor( private designer: Engine, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private hookService: HookService ) {} ngOnChanges(changes: SimpleChanges): void { @@ -51,7 +53,7 @@ export class ComponentTreeWidget implements OnChanges, AfterViewInit { } ngAfterViewInit(): void { - this.tree = this.useTree(); + this.tree = this.hookService.useTree(); this.attributes = { [this.designer?.props?.nodeIdAttrName]: this.tree.id }; @@ -61,8 +63,4 @@ export class ComponentTreeWidget implements OnChanges, AfterViewInit { registerDesignerBehaviors() { GlobalRegistry.registerDesignerBehaviors(this.components); } - - useTree() { - return this.designer.workbench.currentWorkspace.operation.tree; - } } diff --git a/src/app/components/widgets/empty/empty.widget.ts b/src/app/components/widgets/empty/empty.widget.ts index 823f510..e4ed82d 100644 --- a/src/app/components/widgets/empty/empty.widget.ts +++ b/src/app/components/widgets/empty/empty.widget.ts @@ -2,6 +2,7 @@ import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, I import { usePrefix } from '@/app/utils'; import { IconWidget } from '../icon/icon.widget'; import { Engine, TreeNode } from '@/app/core/models'; +import { HookService } from '@/app/services/hook.service'; @Component({ selector: 'app-empty-widget', @@ -41,18 +42,15 @@ export class EmptyWidget implements AfterViewInit { tree: TreeNode; constructor( private designer: Engine, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private hookService: HookService ) {} ngAfterViewInit(): void { - this.tree = this.useTree(); + this.tree = this.hookService.useTree(); setInterval(() => { this.cdr.markForCheck(); }, 1000); } - - useTree() { - return this.designer.workbench.currentWorkspace.operation.tree; - } } diff --git a/src/app/services/hook.service.ts b/src/app/services/hook.service.ts new file mode 100644 index 0000000..45eda14 --- /dev/null +++ b/src/app/services/hook.service.ts @@ -0,0 +1,68 @@ +import { Injectable } from '@angular/core'; +import { Engine } from '../core/models'; + +@Injectable({ + providedIn: 'root' +}) +export class HookService { + constructor(private designer: Engine) {} + + useDesigner() { + return this.designer; + } + + useCursor() { + return this.designer.cursor; + } + + useWorkbench() { + return this.designer.workbench; + } + + useScreen() { + return this.designer.screen; + } + + useWorkspace(workspaceId?: string) { + if (workspaceId) { + return this.designer.workbench.findWorkspaceById(workspaceId); + } else { + return this.designer.workbench.currentWorkspace; + } + } + + useOperation(workspaceId?: string) { + const workspace = this.useWorkspace(workspaceId); + return workspace?.operation; + } + + useSelection(workspaceId?: string) { + const operation = this.useOperation(workspaceId); + return operation?.selection; + } + + useTree(workspaceId?: string) { + const operation = this.useOperation(workspaceId); + return operation?.tree; + } + + useTransformHelper(workspaceId?: string) { + const operation = this.useOperation(workspaceId); + return operation?.transformHelper; + } + + useMoveHelper(workspaceId?: string) { + const operation = this.useOperation(workspaceId); + return operation?.moveHelper; + } + + useViewport(workspaceId?: string) { + const workspace = this.useWorkspace(workspaceId); + return workspace?.viewport; + } + + useOutline(workspaceId?: string) { + const workspace = this.useWorkspace(workspaceId); + return workspace?.outline; + } +}