@visactor/vrender-core 1.1.0-alpha.16 → 1.1.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/core/stage.d.ts +4 -1
- package/cjs/core/stage.js +23 -11
- package/cjs/core/stage.js.map +1 -1
- package/cjs/graphic/graphic-service/graphic-service.d.ts +4 -0
- package/cjs/graphic/graphic-service/graphic-service.js +6 -5
- package/cjs/graphic/graphic-service/graphic-service.js.map +1 -1
- package/cjs/graphic/graphic.d.ts +41 -8
- package/cjs/graphic/graphic.js +383 -146
- package/cjs/graphic/graphic.js.map +1 -1
- package/cjs/graphic/group.d.ts +5 -1
- package/cjs/graphic/group.js +37 -18
- package/cjs/graphic/group.js.map +1 -1
- package/cjs/graphic/state/shared-state-refresh.js +3 -3
- package/cjs/graphic/state/shared-state-refresh.js.map +1 -1
- package/cjs/graphic/state/shared-state-scope.js +1 -1
- package/cjs/graphic/state/shared-state-scope.js.map +1 -1
- package/cjs/graphic/state/state-engine.js +2 -2
- package/cjs/graphic/state/state-engine.js.map +1 -1
- package/cjs/graphic/state/state-perf-monitor.d.ts +1 -0
- package/cjs/graphic/state/state-perf-monitor.js +9 -2
- package/cjs/graphic/state/state-perf-monitor.js.map +1 -1
- package/cjs/graphic/state/state-style-resolver.d.ts +0 -9
- package/cjs/graphic/state/state-style-resolver.js +0 -23
- package/cjs/graphic/state/state-style-resolver.js.map +1 -1
- package/cjs/interface/graphic.d.ts +2 -0
- package/cjs/interface/graphic.js.map +1 -1
- package/cjs/interface/node-tree.js.map +1 -1
- package/cjs/plugins/builtin-plugin/dirty-bounds-plugin.d.ts +4 -1
- package/cjs/plugins/builtin-plugin/dirty-bounds-plugin.js +20 -10
- package/cjs/plugins/builtin-plugin/dirty-bounds-plugin.js.map +1 -1
- package/cjs/plugins/builtin-plugin/flex-layout-plugin.js +3 -2
- package/cjs/plugins/builtin-plugin/flex-layout-plugin.js.map +1 -1
- package/cjs/render/contributions/render/base-render.js +8 -7
- package/cjs/render/contributions/render/base-render.js.map +1 -1
- package/dist/index.es.js +806 -263
- package/es/core/stage.d.ts +4 -1
- package/es/core/stage.js +21 -10
- package/es/core/stage.js.map +1 -1
- package/es/graphic/graphic-service/graphic-service.d.ts +4 -0
- package/es/graphic/graphic-service/graphic-service.js +6 -5
- package/es/graphic/graphic-service/graphic-service.js.map +1 -1
- package/es/graphic/graphic.d.ts +41 -8
- package/es/graphic/graphic.js +379 -139
- package/es/graphic/graphic.js.map +1 -1
- package/es/graphic/group.d.ts +5 -1
- package/es/graphic/group.js +36 -18
- package/es/graphic/group.js.map +1 -1
- package/es/graphic/state/shared-state-refresh.js +4 -4
- package/es/graphic/state/shared-state-refresh.js.map +1 -1
- package/es/graphic/state/shared-state-scope.js +2 -2
- package/es/graphic/state/shared-state-scope.js.map +1 -1
- package/es/graphic/state/state-engine.js +3 -3
- package/es/graphic/state/state-engine.js.map +1 -1
- package/es/graphic/state/state-perf-monitor.d.ts +1 -0
- package/es/graphic/state/state-perf-monitor.js +7 -0
- package/es/graphic/state/state-perf-monitor.js.map +1 -1
- package/es/graphic/state/state-style-resolver.d.ts +0 -9
- package/es/graphic/state/state-style-resolver.js +0 -23
- package/es/graphic/state/state-style-resolver.js.map +1 -1
- package/es/interface/graphic.d.ts +2 -0
- package/es/interface/graphic.js.map +1 -1
- package/es/interface/node-tree.js.map +1 -1
- package/es/plugins/builtin-plugin/dirty-bounds-plugin.d.ts +4 -1
- package/es/plugins/builtin-plugin/dirty-bounds-plugin.js +20 -10
- package/es/plugins/builtin-plugin/dirty-bounds-plugin.js.map +1 -1
- package/es/plugins/builtin-plugin/flex-layout-plugin.js +3 -2
- package/es/plugins/builtin-plugin/flex-layout-plugin.js.map +1 -1
- package/es/render/contributions/render/base-render.js +8 -6
- package/es/render/contributions/render/base-render.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphic/state/state-perf-monitor.ts"],"names":[],"mappings":"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","file":"state-perf-monitor.js","sourcesContent":["import type { IGroup, ILayer, IStage } from '../../interface';\nimport { UpdateCategory } from './attribute-update-classifier';\n\nexport type DeferredIneligibleReason =\n | 'config_disabled'\n | 'context_disabled'\n | 'non_batch_operation'\n | 'mixed_update_category'\n | 'resolver_unstable_keys'\n | 'graphic_unavailable';\n\nexport interface IStatePerfConfig {\n enabled?: boolean;\n recordEvents?: boolean;\n maxEventRecords?: number;\n}\n\nexport interface IDeferredStateConfig {\n enabled?: boolean;\n frameBudget?: number;\n maxGraphicsPerFrame?: number;\n}\n\nexport interface IDeferredStateContextConfig {\n deferred?: IDeferredStateConfig;\n priority?: number;\n localEnabled?: boolean;\n}\n\nexport type IDeferredStateOwnerConfig = IDeferredStateConfig | IDeferredStateContextConfig;\n\nexport type IStatePerfEventType =\n | 'state-commit'\n | 'shared-refresh-flush'\n | 'deferred-job-start'\n | 'deferred-job-yield'\n | 'deferred-job-cancel'\n | 'deferred-job-complete'\n | 'deferred-ineligible';\n\nexport interface IStatePerfEventRecord {\n type: IStatePerfEventType;\n at: number;\n detail?: Record<string, unknown>;\n}\n\nexport interface IStatePerfSnapshot {\n counters: {\n stateCommits: number;\n sharedRefreshCommits: number;\n deferredJobsCreated: number;\n deferredJobsCompleted: number;\n deferredJobsCancelled: number;\n deferredJobsCoalesced: number;\n deferredGraphicsCommitted: number;\n deferredBudgetYields: number;\n deferredIneligibleGraphics: number;\n };\n deferredIneligibleByReason: Record<DeferredIneligibleReason, number>;\n categoryBreakdown: {\n paint: number;\n transform: number;\n shape: number;\n bounds: number;\n layout: number;\n pick: number;\n };\n refresh: {\n queuedGraphics: number;\n flushedGraphics: number;\n ensureFreshCalls: number;\n renderScheduled: number;\n };\n resolver: {\n cacheHits: number;\n cacheMisses: number;\n invalidations: number;\n };\n cost: {\n resolverTotalMs: number;\n resolverMaxMs: number;\n patchTotalMs: number;\n patchMaxMs: number;\n sharedRefreshTotalMs: number;\n sharedRefreshMaxMs: number;\n batchSliceTotalMs: number;\n batchSliceMaxMs: number;\n };\n allocationHints: {\n patchObjectsCreated: number;\n batchEntriesCreated: number;\n refreshQueuePushes: number;\n };\n batch: {\n pendingJobs: number;\n maxPendingJobs: number;\n maxGraphicsInJob: number;\n maxFrameSliceCost: number;\n };\n events?: IStatePerfEventRecord[];\n}\n\ntype SnapshotCounterKey = keyof IStatePerfSnapshot['counters'];\ntype SnapshotRefreshKey = keyof IStatePerfSnapshot['refresh'];\ntype SnapshotResolverKey = keyof IStatePerfSnapshot['resolver'];\ntype SnapshotAllocationKey = keyof IStatePerfSnapshot['allocationHints'];\ntype SnapshotCostKind = 'resolver' | 'patch' | 'sharedRefresh' | 'batchSlice';\n\nexport interface IResolvedDeferredContext {\n contextOwner: IStage | ILayer | IGroup;\n contextOwnerId: number;\n config: Required<IDeferredStateConfig>;\n configFingerprint: string;\n}\n\nconst DEFAULT_MAX_EVENT_RECORDS = 100;\nconst STAGE_PERF_MONITOR = Symbol('vrender.statePerfMonitor');\n\nfunction createReasonBreakdown(): Record<DeferredIneligibleReason, number> {\n return {\n config_disabled: 0,\n context_disabled: 0,\n non_batch_operation: 0,\n mixed_update_category: 0,\n resolver_unstable_keys: 0,\n graphic_unavailable: 0\n };\n}\n\nexport function createEmptyStatePerfSnapshot(): IStatePerfSnapshot {\n return {\n counters: {\n stateCommits: 0,\n sharedRefreshCommits: 0,\n deferredJobsCreated: 0,\n deferredJobsCompleted: 0,\n deferredJobsCancelled: 0,\n deferredJobsCoalesced: 0,\n deferredGraphicsCommitted: 0,\n deferredBudgetYields: 0,\n deferredIneligibleGraphics: 0\n },\n deferredIneligibleByReason: createReasonBreakdown(),\n categoryBreakdown: {\n paint: 0,\n transform: 0,\n shape: 0,\n bounds: 0,\n layout: 0,\n pick: 0\n },\n refresh: {\n queuedGraphics: 0,\n flushedGraphics: 0,\n ensureFreshCalls: 0,\n renderScheduled: 0\n },\n resolver: {\n cacheHits: 0,\n cacheMisses: 0,\n invalidations: 0\n },\n cost: {\n resolverTotalMs: 0,\n resolverMaxMs: 0,\n patchTotalMs: 0,\n patchMaxMs: 0,\n sharedRefreshTotalMs: 0,\n sharedRefreshMaxMs: 0,\n batchSliceTotalMs: 0,\n batchSliceMaxMs: 0\n },\n allocationHints: {\n patchObjectsCreated: 0,\n batchEntriesCreated: 0,\n refreshQueuePushes: 0\n },\n batch: {\n pendingJobs: 0,\n maxPendingJobs: 0,\n maxGraphicsInJob: 0,\n maxFrameSliceCost: 0\n },\n events: []\n };\n}\n\nfunction cloneSnapshot(snapshot: IStatePerfSnapshot): IStatePerfSnapshot {\n return {\n counters: { ...snapshot.counters },\n deferredIneligibleByReason: { ...snapshot.deferredIneligibleByReason },\n categoryBreakdown: { ...snapshot.categoryBreakdown },\n refresh: { ...snapshot.refresh },\n resolver: { ...snapshot.resolver },\n cost: { ...snapshot.cost },\n allocationHints: { ...snapshot.allocationHints },\n batch: { ...snapshot.batch },\n events: snapshot.events ? snapshot.events.slice() : []\n };\n}\n\nfunction isDeferredStateContextConfig(\n value: IDeferredStateOwnerConfig | undefined\n): value is IDeferredStateContextConfig {\n return (\n !!value &&\n (Object.prototype.hasOwnProperty.call(value, 'deferred') ||\n Object.prototype.hasOwnProperty.call(value, 'localEnabled'))\n );\n}\n\nexport function normalizeDeferredStateOwnerConfig(\n value?: IDeferredStateOwnerConfig\n): IDeferredStateContextConfig | undefined {\n if (!value) {\n return undefined;\n }\n\n if (isDeferredStateContextConfig(value)) {\n return value;\n }\n\n return {\n deferred: value\n };\n}\n\nexport function normalizeDeferredStateConfig(config?: IDeferredStateConfig): Required<IDeferredStateConfig> {\n return {\n enabled: config?.enabled ?? false,\n frameBudget: config?.frameBudget ?? 8,\n maxGraphicsPerFrame: config?.maxGraphicsPerFrame ?? 100\n };\n}\n\nexport function fingerprintDeferredStateConfig(config: Required<IDeferredStateConfig>): string {\n return `${config.enabled ? 1 : 0}:${config.frameBudget}:${config.maxGraphicsPerFrame}`;\n}\n\nexport class StatePerfMonitor {\n private readonly snapshot = createEmptyStatePerfSnapshot();\n\n constructor(private configSource?: IStatePerfConfig | (() => IStatePerfConfig | undefined)) {}\n\n setConfig(config?: IStatePerfConfig): void {\n this.configSource = config;\n }\n\n getSnapshot(): IStatePerfSnapshot {\n return cloneSnapshot(this.snapshot);\n }\n\n reset(): void {\n const next = createEmptyStatePerfSnapshot();\n Object.assign(this.snapshot.counters, next.counters);\n Object.assign(this.snapshot.deferredIneligibleByReason, next.deferredIneligibleByReason);\n Object.assign(this.snapshot.categoryBreakdown, next.categoryBreakdown);\n Object.assign(this.snapshot.refresh, next.refresh);\n Object.assign(this.snapshot.resolver, next.resolver);\n Object.assign(this.snapshot.cost, next.cost);\n Object.assign(this.snapshot.allocationHints, next.allocationHints);\n Object.assign(this.snapshot.batch, next.batch);\n this.snapshot.events = [];\n }\n\n incrementCounter(key: SnapshotCounterKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.counters[key] += delta;\n }\n\n recordDeferredIneligible(reason: DeferredIneligibleReason, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.deferredIneligibleByReason[reason] += delta;\n this.snapshot.counters.deferredIneligibleGraphics += delta;\n this.recordEvent('deferred-ineligible', { reason, count: delta });\n }\n\n recordCategory(category: UpdateCategory): void {\n if (!this.isEnabled()) {\n return;\n }\n if (category & UpdateCategory.PAINT) {\n this.snapshot.categoryBreakdown.paint += 1;\n }\n if (category & UpdateCategory.TRANSFORM) {\n this.snapshot.categoryBreakdown.transform += 1;\n }\n if (category & UpdateCategory.SHAPE) {\n this.snapshot.categoryBreakdown.shape += 1;\n }\n if (category & UpdateCategory.BOUNDS) {\n this.snapshot.categoryBreakdown.bounds += 1;\n }\n if (category & UpdateCategory.LAYOUT) {\n this.snapshot.categoryBreakdown.layout += 1;\n }\n if (category & UpdateCategory.PICK) {\n this.snapshot.categoryBreakdown.pick += 1;\n }\n }\n\n recordRefresh(key: SnapshotRefreshKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.refresh[key] += delta;\n }\n\n recordResolver(key: SnapshotResolverKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.resolver[key] += delta;\n }\n\n recordCost(kind: SnapshotCostKind, durationMs: number): void {\n if (!this.isEnabled()) {\n return;\n }\n if (kind === 'resolver') {\n this.snapshot.cost.resolverTotalMs += durationMs;\n this.snapshot.cost.resolverMaxMs = Math.max(this.snapshot.cost.resolverMaxMs, durationMs);\n return;\n }\n if (kind === 'patch') {\n this.snapshot.cost.patchTotalMs += durationMs;\n this.snapshot.cost.patchMaxMs = Math.max(this.snapshot.cost.patchMaxMs, durationMs);\n return;\n }\n if (kind === 'sharedRefresh') {\n this.snapshot.cost.sharedRefreshTotalMs += durationMs;\n this.snapshot.cost.sharedRefreshMaxMs = Math.max(this.snapshot.cost.sharedRefreshMaxMs, durationMs);\n return;\n }\n\n this.snapshot.cost.batchSliceTotalMs += durationMs;\n this.snapshot.cost.batchSliceMaxMs = Math.max(this.snapshot.cost.batchSliceMaxMs, durationMs);\n this.snapshot.batch.maxFrameSliceCost = Math.max(this.snapshot.batch.maxFrameSliceCost, durationMs);\n }\n\n recordAllocation(key: SnapshotAllocationKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.allocationHints[key] += delta;\n }\n\n updateBatchPending(pendingJobs: number): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.batch.pendingJobs = pendingJobs;\n this.snapshot.batch.maxPendingJobs = Math.max(this.snapshot.batch.maxPendingJobs, pendingJobs);\n }\n\n updateMaxGraphicsInJob(count: number): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.batch.maxGraphicsInJob = Math.max(this.snapshot.batch.maxGraphicsInJob, count);\n }\n\n recordEvent(type: IStatePerfEventType, detail?: Record<string, unknown>): void {\n if (!this.shouldRecordEvents()) {\n return;\n }\n const events = this.snapshot.events ?? (this.snapshot.events = []);\n events.push({\n type,\n at: Date.now(),\n detail\n });\n const max = this.getConfig()?.maxEventRecords ?? DEFAULT_MAX_EVENT_RECORDS;\n if (events.length > max) {\n events.splice(0, events.length - max);\n }\n }\n\n private isEnabled(): boolean {\n return this.getConfig()?.enabled === true;\n }\n\n private shouldRecordEvents(): boolean {\n const config = this.getConfig();\n return !!config?.enabled && !!config.recordEvents;\n }\n\n private getConfig(): IStatePerfConfig | undefined {\n return typeof this.configSource === 'function' ? this.configSource() : this.configSource;\n }\n}\n\nexport function ensureStageStatePerfMonitor(stage: IStage): StatePerfMonitor {\n const stageAny = stage as any;\n if (!stageAny[STAGE_PERF_MONITOR]) {\n stageAny[STAGE_PERF_MONITOR] = new StatePerfMonitor(() => (stage as any).statePerfConfig);\n }\n\n return stageAny[STAGE_PERF_MONITOR] as StatePerfMonitor;\n}\n\nexport function getStageStatePerfMonitor(stage?: IStage): StatePerfMonitor | undefined {\n if (!stage) {\n return undefined;\n }\n return (stage as any)[STAGE_PERF_MONITOR] as StatePerfMonitor | undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphic/state/state-perf-monitor.ts"],"names":[],"mappings":"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","file":"state-perf-monitor.js","sourcesContent":["import type { IGroup, ILayer, IStage } from '../../interface';\nimport { UpdateCategory } from './attribute-update-classifier';\n\nexport type DeferredIneligibleReason =\n | 'config_disabled'\n | 'context_disabled'\n | 'non_batch_operation'\n | 'mixed_update_category'\n | 'resolver_unstable_keys'\n | 'graphic_unavailable';\n\nexport interface IStatePerfConfig {\n enabled?: boolean;\n recordEvents?: boolean;\n maxEventRecords?: number;\n}\n\nexport interface IDeferredStateConfig {\n enabled?: boolean;\n frameBudget?: number;\n maxGraphicsPerFrame?: number;\n}\n\nexport interface IDeferredStateContextConfig {\n deferred?: IDeferredStateConfig;\n priority?: number;\n localEnabled?: boolean;\n}\n\nexport type IDeferredStateOwnerConfig = IDeferredStateConfig | IDeferredStateContextConfig;\n\nexport type IStatePerfEventType =\n | 'state-commit'\n | 'shared-refresh-flush'\n | 'deferred-job-start'\n | 'deferred-job-yield'\n | 'deferred-job-cancel'\n | 'deferred-job-complete'\n | 'deferred-ineligible';\n\nexport interface IStatePerfEventRecord {\n type: IStatePerfEventType;\n at: number;\n detail?: Record<string, unknown>;\n}\n\nexport interface IStatePerfSnapshot {\n counters: {\n stateCommits: number;\n sharedRefreshCommits: number;\n deferredJobsCreated: number;\n deferredJobsCompleted: number;\n deferredJobsCancelled: number;\n deferredJobsCoalesced: number;\n deferredGraphicsCommitted: number;\n deferredBudgetYields: number;\n deferredIneligibleGraphics: number;\n };\n deferredIneligibleByReason: Record<DeferredIneligibleReason, number>;\n categoryBreakdown: {\n paint: number;\n transform: number;\n shape: number;\n bounds: number;\n layout: number;\n pick: number;\n };\n refresh: {\n queuedGraphics: number;\n flushedGraphics: number;\n ensureFreshCalls: number;\n renderScheduled: number;\n };\n resolver: {\n cacheHits: number;\n cacheMisses: number;\n invalidations: number;\n };\n cost: {\n resolverTotalMs: number;\n resolverMaxMs: number;\n patchTotalMs: number;\n patchMaxMs: number;\n sharedRefreshTotalMs: number;\n sharedRefreshMaxMs: number;\n batchSliceTotalMs: number;\n batchSliceMaxMs: number;\n };\n allocationHints: {\n patchObjectsCreated: number;\n batchEntriesCreated: number;\n refreshQueuePushes: number;\n };\n batch: {\n pendingJobs: number;\n maxPendingJobs: number;\n maxGraphicsInJob: number;\n maxFrameSliceCost: number;\n };\n events?: IStatePerfEventRecord[];\n}\n\ntype SnapshotCounterKey = keyof IStatePerfSnapshot['counters'];\ntype SnapshotRefreshKey = keyof IStatePerfSnapshot['refresh'];\ntype SnapshotResolverKey = keyof IStatePerfSnapshot['resolver'];\ntype SnapshotAllocationKey = keyof IStatePerfSnapshot['allocationHints'];\ntype SnapshotCostKind = 'resolver' | 'patch' | 'sharedRefresh' | 'batchSlice';\n\nexport interface IResolvedDeferredContext {\n contextOwner: IStage | ILayer | IGroup;\n contextOwnerId: number;\n config: Required<IDeferredStateConfig>;\n configFingerprint: string;\n}\n\nconst DEFAULT_MAX_EVENT_RECORDS = 100;\nconst STAGE_PERF_MONITOR = Symbol('vrender.statePerfMonitor');\n\nfunction createReasonBreakdown(): Record<DeferredIneligibleReason, number> {\n return {\n config_disabled: 0,\n context_disabled: 0,\n non_batch_operation: 0,\n mixed_update_category: 0,\n resolver_unstable_keys: 0,\n graphic_unavailable: 0\n };\n}\n\nexport function createEmptyStatePerfSnapshot(): IStatePerfSnapshot {\n return {\n counters: {\n stateCommits: 0,\n sharedRefreshCommits: 0,\n deferredJobsCreated: 0,\n deferredJobsCompleted: 0,\n deferredJobsCancelled: 0,\n deferredJobsCoalesced: 0,\n deferredGraphicsCommitted: 0,\n deferredBudgetYields: 0,\n deferredIneligibleGraphics: 0\n },\n deferredIneligibleByReason: createReasonBreakdown(),\n categoryBreakdown: {\n paint: 0,\n transform: 0,\n shape: 0,\n bounds: 0,\n layout: 0,\n pick: 0\n },\n refresh: {\n queuedGraphics: 0,\n flushedGraphics: 0,\n ensureFreshCalls: 0,\n renderScheduled: 0\n },\n resolver: {\n cacheHits: 0,\n cacheMisses: 0,\n invalidations: 0\n },\n cost: {\n resolverTotalMs: 0,\n resolverMaxMs: 0,\n patchTotalMs: 0,\n patchMaxMs: 0,\n sharedRefreshTotalMs: 0,\n sharedRefreshMaxMs: 0,\n batchSliceTotalMs: 0,\n batchSliceMaxMs: 0\n },\n allocationHints: {\n patchObjectsCreated: 0,\n batchEntriesCreated: 0,\n refreshQueuePushes: 0\n },\n batch: {\n pendingJobs: 0,\n maxPendingJobs: 0,\n maxGraphicsInJob: 0,\n maxFrameSliceCost: 0\n },\n events: []\n };\n}\n\nfunction cloneSnapshot(snapshot: IStatePerfSnapshot): IStatePerfSnapshot {\n return {\n counters: { ...snapshot.counters },\n deferredIneligibleByReason: { ...snapshot.deferredIneligibleByReason },\n categoryBreakdown: { ...snapshot.categoryBreakdown },\n refresh: { ...snapshot.refresh },\n resolver: { ...snapshot.resolver },\n cost: { ...snapshot.cost },\n allocationHints: { ...snapshot.allocationHints },\n batch: { ...snapshot.batch },\n events: snapshot.events ? snapshot.events.slice() : []\n };\n}\n\nfunction isDeferredStateContextConfig(\n value: IDeferredStateOwnerConfig | undefined\n): value is IDeferredStateContextConfig {\n return (\n !!value &&\n (Object.prototype.hasOwnProperty.call(value, 'deferred') ||\n Object.prototype.hasOwnProperty.call(value, 'localEnabled'))\n );\n}\n\nexport function normalizeDeferredStateOwnerConfig(\n value?: IDeferredStateOwnerConfig\n): IDeferredStateContextConfig | undefined {\n if (!value) {\n return undefined;\n }\n\n if (isDeferredStateContextConfig(value)) {\n return value;\n }\n\n return {\n deferred: value\n };\n}\n\nexport function normalizeDeferredStateConfig(config?: IDeferredStateConfig): Required<IDeferredStateConfig> {\n return {\n enabled: config?.enabled ?? false,\n frameBudget: config?.frameBudget ?? 8,\n maxGraphicsPerFrame: config?.maxGraphicsPerFrame ?? 100\n };\n}\n\nexport function fingerprintDeferredStateConfig(config: Required<IDeferredStateConfig>): string {\n return `${config.enabled ? 1 : 0}:${config.frameBudget}:${config.maxGraphicsPerFrame}`;\n}\n\nexport class StatePerfMonitor {\n private readonly snapshot = createEmptyStatePerfSnapshot();\n\n constructor(private configSource?: IStatePerfConfig | (() => IStatePerfConfig | undefined)) {}\n\n setConfig(config?: IStatePerfConfig): void {\n this.configSource = config;\n }\n\n getSnapshot(): IStatePerfSnapshot {\n return cloneSnapshot(this.snapshot);\n }\n\n reset(): void {\n const next = createEmptyStatePerfSnapshot();\n Object.assign(this.snapshot.counters, next.counters);\n Object.assign(this.snapshot.deferredIneligibleByReason, next.deferredIneligibleByReason);\n Object.assign(this.snapshot.categoryBreakdown, next.categoryBreakdown);\n Object.assign(this.snapshot.refresh, next.refresh);\n Object.assign(this.snapshot.resolver, next.resolver);\n Object.assign(this.snapshot.cost, next.cost);\n Object.assign(this.snapshot.allocationHints, next.allocationHints);\n Object.assign(this.snapshot.batch, next.batch);\n this.snapshot.events = [];\n }\n\n incrementCounter(key: SnapshotCounterKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.counters[key] += delta;\n }\n\n recordDeferredIneligible(reason: DeferredIneligibleReason, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.deferredIneligibleByReason[reason] += delta;\n this.snapshot.counters.deferredIneligibleGraphics += delta;\n this.recordEvent('deferred-ineligible', { reason, count: delta });\n }\n\n recordCategory(category: UpdateCategory): void {\n if (!this.isEnabled()) {\n return;\n }\n if (category & UpdateCategory.PAINT) {\n this.snapshot.categoryBreakdown.paint += 1;\n }\n if (category & UpdateCategory.TRANSFORM) {\n this.snapshot.categoryBreakdown.transform += 1;\n }\n if (category & UpdateCategory.SHAPE) {\n this.snapshot.categoryBreakdown.shape += 1;\n }\n if (category & UpdateCategory.BOUNDS) {\n this.snapshot.categoryBreakdown.bounds += 1;\n }\n if (category & UpdateCategory.LAYOUT) {\n this.snapshot.categoryBreakdown.layout += 1;\n }\n if (category & UpdateCategory.PICK) {\n this.snapshot.categoryBreakdown.pick += 1;\n }\n }\n\n recordRefresh(key: SnapshotRefreshKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.refresh[key] += delta;\n }\n\n recordResolver(key: SnapshotResolverKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.resolver[key] += delta;\n }\n\n recordCost(kind: SnapshotCostKind, durationMs: number): void {\n if (!this.isEnabled()) {\n return;\n }\n if (kind === 'resolver') {\n this.snapshot.cost.resolverTotalMs += durationMs;\n this.snapshot.cost.resolverMaxMs = Math.max(this.snapshot.cost.resolverMaxMs, durationMs);\n return;\n }\n if (kind === 'patch') {\n this.snapshot.cost.patchTotalMs += durationMs;\n this.snapshot.cost.patchMaxMs = Math.max(this.snapshot.cost.patchMaxMs, durationMs);\n return;\n }\n if (kind === 'sharedRefresh') {\n this.snapshot.cost.sharedRefreshTotalMs += durationMs;\n this.snapshot.cost.sharedRefreshMaxMs = Math.max(this.snapshot.cost.sharedRefreshMaxMs, durationMs);\n return;\n }\n\n this.snapshot.cost.batchSliceTotalMs += durationMs;\n this.snapshot.cost.batchSliceMaxMs = Math.max(this.snapshot.cost.batchSliceMaxMs, durationMs);\n this.snapshot.batch.maxFrameSliceCost = Math.max(this.snapshot.batch.maxFrameSliceCost, durationMs);\n }\n\n recordAllocation(key: SnapshotAllocationKey, delta: number = 1): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.allocationHints[key] += delta;\n }\n\n updateBatchPending(pendingJobs: number): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.batch.pendingJobs = pendingJobs;\n this.snapshot.batch.maxPendingJobs = Math.max(this.snapshot.batch.maxPendingJobs, pendingJobs);\n }\n\n updateMaxGraphicsInJob(count: number): void {\n if (!this.isEnabled()) {\n return;\n }\n this.snapshot.batch.maxGraphicsInJob = Math.max(this.snapshot.batch.maxGraphicsInJob, count);\n }\n\n recordEvent(type: IStatePerfEventType, detail?: Record<string, unknown>): void {\n if (!this.shouldRecordEvents()) {\n return;\n }\n const events = this.snapshot.events ?? (this.snapshot.events = []);\n events.push({\n type,\n at: Date.now(),\n detail\n });\n const max = this.getConfig()?.maxEventRecords ?? DEFAULT_MAX_EVENT_RECORDS;\n if (events.length > max) {\n events.splice(0, events.length - max);\n }\n }\n\n private isEnabled(): boolean {\n return this.getConfig()?.enabled === true;\n }\n\n private shouldRecordEvents(): boolean {\n const config = this.getConfig();\n return !!config?.enabled && !!config.recordEvents;\n }\n\n private getConfig(): IStatePerfConfig | undefined {\n return typeof this.configSource === 'function' ? this.configSource() : this.configSource;\n }\n}\n\nexport function ensureStageStatePerfMonitor(stage: IStage): StatePerfMonitor {\n const stageAny = stage as any;\n if (!stageAny[STAGE_PERF_MONITOR]) {\n stageAny[STAGE_PERF_MONITOR] = new StatePerfMonitor(() => (stage as any).statePerfConfig);\n }\n\n return stageAny[STAGE_PERF_MONITOR] as StatePerfMonitor;\n}\n\nexport function getStageStatePerfMonitor(stage?: IStage): StatePerfMonitor | undefined {\n if (!stage) {\n return undefined;\n }\n return (stage as any)[STAGE_PERF_MONITOR] as StatePerfMonitor | undefined;\n}\n\nexport function getActiveStageStatePerfMonitor(stage?: IStage): StatePerfMonitor | undefined {\n if (!stage) {\n return undefined;\n }\n\n const current = getStageStatePerfMonitor(stage);\n if (current) {\n return current;\n }\n\n return (stage as any).statePerfConfig?.enabled === true ? ensureStageStatePerfMonitor(stage) : undefined;\n}\n"]}
|
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
import type { CompiledStateDefinition } from './state-definition';
|
|
2
1
|
import type { StateProxy, StateSort } from './state-model';
|
|
3
2
|
export type StateMergeMode = 'shallow' | 'deep';
|
|
4
3
|
export interface IStateStyleResolverOptions {
|
|
5
4
|
mergeMode?: StateMergeMode;
|
|
6
5
|
}
|
|
7
|
-
export interface IStateStyleBackupResult<T> {
|
|
8
|
-
attrs: Partial<T>;
|
|
9
|
-
normalAttrs: Partial<T>;
|
|
10
|
-
}
|
|
11
6
|
export interface IStateStyleResolver<T> {
|
|
12
7
|
resolve: (normalAttrs: Partial<T>, states: Record<string, Partial<T>> | undefined, stateProxy: StateProxy<T> | undefined, currentStates: string[], stateSort?: StateSort) => Partial<T>;
|
|
13
|
-
resolveWithCompiled: (normalAttrs: Partial<T>, compiledDefinitions: Map<string, CompiledStateDefinition<T>>, stateProxy: StateProxy<T> | undefined, effectiveStates: string[], resolvedPatch: Partial<T>) => Partial<T>;
|
|
14
|
-
computeNormalAttrsBackup: (normalAttrs: Partial<T> | null | undefined, targetAttrs: Partial<T>, finalAttribute: Record<string, any>) => IStateStyleBackupResult<T>;
|
|
15
8
|
}
|
|
16
9
|
export declare class StateStyleResolver<T extends Record<string, any> = Record<string, any>> implements IStateStyleResolver<T> {
|
|
17
10
|
private readonly options;
|
|
18
11
|
constructor(options?: IStateStyleResolverOptions);
|
|
19
12
|
resolve(normalAttrs: Partial<T>, states: Record<string, Partial<T>> | undefined, stateProxy: StateProxy<T> | undefined, currentStates: string[], stateSort?: StateSort): Partial<T>;
|
|
20
|
-
resolveWithCompiled(normalAttrs: Partial<T>, compiledDefinitions: Map<string, CompiledStateDefinition<T>>, stateProxy: StateProxy<T> | undefined, effectiveStates: string[], resolvedPatch: Partial<T>): Partial<T>;
|
|
21
|
-
computeNormalAttrsBackup(normalAttrs: Partial<T> | null | undefined, targetAttrs: Partial<T>, finalAttribute: Record<string, any>): IStateStyleBackupResult<T>;
|
|
22
13
|
}
|
|
@@ -44,29 +44,6 @@ class StateStyleResolver {
|
|
|
44
44
|
}
|
|
45
45
|
})), resolvedAttrs;
|
|
46
46
|
}
|
|
47
|
-
resolveWithCompiled(normalAttrs, compiledDefinitions, stateProxy, effectiveStates, resolvedPatch) {
|
|
48
|
-
var _a, _b;
|
|
49
|
-
const mergeMode = null !== (_a = this.options.mergeMode) && void 0 !== _a ? _a : "shallow", resolvedAttrs = null !== (_b = cloneValue(resolvedPatch)) && void 0 !== _b ? _b : {};
|
|
50
|
-
return effectiveStates.forEach((stateName => {
|
|
51
|
-
const proxyPatch = null == stateProxy ? void 0 : stateProxy(stateName, effectiveStates);
|
|
52
|
-
null != proxyPatch && Object.keys(proxyPatch).forEach((key => {
|
|
53
|
-
const nextValue = proxyPatch[key], hasCompiledDefinition = compiledDefinitions.has(stateName);
|
|
54
|
-
if ("deep" === mergeMode && isPlainObject(nextValue) && (isPlainObject(resolvedAttrs[key]) || !hasCompiledDefinition && isPlainObject(normalAttrs[key]))) {
|
|
55
|
-
const baseValue = isPlainObject(resolvedAttrs[key]) ? resolvedAttrs[key] : isPlainObject(normalAttrs[key]) ? normalAttrs[key] : {};
|
|
56
|
-
resolvedAttrs[key] = deepMerge(baseValue, nextValue);
|
|
57
|
-
} else resolvedAttrs[key] = cloneValue(nextValue);
|
|
58
|
-
}));
|
|
59
|
-
})), resolvedAttrs;
|
|
60
|
-
}
|
|
61
|
-
computeNormalAttrsBackup(normalAttrs, targetAttrs, finalAttribute) {
|
|
62
|
-
const nextNormalAttrs = {}, nextTargetAttrs = Object.assign({}, targetAttrs);
|
|
63
|
-
for (const key in targetAttrs) Object.prototype.hasOwnProperty.call(targetAttrs, key) && (nextNormalAttrs[key] = cloneValue(normalAttrs && key in normalAttrs ? normalAttrs[key] : finalAttribute[key]));
|
|
64
|
-
if (normalAttrs) for (const key in normalAttrs) Object.prototype.hasOwnProperty.call(normalAttrs, key) && !(key in targetAttrs) && (nextTargetAttrs[key] = cloneValue(normalAttrs[key]));
|
|
65
|
-
return {
|
|
66
|
-
attrs: nextTargetAttrs,
|
|
67
|
-
normalAttrs: nextNormalAttrs
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
47
|
}
|
|
71
48
|
|
|
72
49
|
exports.StateStyleResolver = StateStyleResolver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphic/state/state-style-resolver.ts"],"names":[],"mappings":"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","file":"state-style-resolver.js","sourcesContent":["import type { CompiledStateDefinition } from './state-definition';\nimport type { StateProxy, StateSort } from './state-model';\n\nexport type StateMergeMode = 'shallow' | 'deep';\n\nexport interface IStateStyleResolverOptions {\n mergeMode?: StateMergeMode;\n}\n\nexport interface IStateStyleBackupResult<T> {\n attrs: Partial<T>;\n normalAttrs: Partial<T>;\n}\n\nexport interface IStateStyleResolver<T> {\n resolve: (\n normalAttrs: Partial<T>,\n states: Record<string, Partial<T>> | undefined,\n stateProxy: StateProxy<T> | undefined,\n currentStates: string[],\n stateSort?: StateSort\n ) => Partial<T>;\n resolveWithCompiled: (\n normalAttrs: Partial<T>,\n compiledDefinitions: Map<string, CompiledStateDefinition<T>>,\n stateProxy: StateProxy<T> | undefined,\n effectiveStates: string[],\n resolvedPatch: Partial<T>\n ) => Partial<T>;\n computeNormalAttrsBackup: (\n normalAttrs: Partial<T> | null | undefined,\n targetAttrs: Partial<T>,\n finalAttribute: Record<string, any>\n ) => IStateStyleBackupResult<T>;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, any> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction cloneValue<T>(value: T): T {\n if (!isPlainObject(value)) {\n return value;\n }\n\n const clone: Record<string, any> = {};\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue;\n }\n clone[key] = cloneValue((value as Record<string, any>)[key]);\n }\n return clone as T;\n}\n\nfunction deepMerge(base: Record<string, any>, value: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = cloneValue(base) || {};\n\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue;\n }\n\n const nextValue = value[key];\n const previousValue = result[key];\n\n if (isPlainObject(previousValue) && isPlainObject(nextValue)) {\n result[key] = deepMerge(previousValue, nextValue);\n } else {\n result[key] = cloneValue(nextValue);\n }\n }\n\n return result;\n}\n\nexport class StateStyleResolver<T extends Record<string, any> = Record<string, any>> implements IStateStyleResolver<T> {\n constructor(private readonly options: IStateStyleResolverOptions = {}) {}\n\n resolve(\n normalAttrs: Partial<T>,\n states: Record<string, Partial<T>> | undefined,\n stateProxy: StateProxy<T> | undefined,\n currentStates: string[],\n stateSort?: StateSort\n ): Partial<T> {\n const mergeMode = this.options.mergeMode ?? 'shallow';\n const sortedStates = stateSort ? currentStates.slice().sort(stateSort) : currentStates.slice();\n const resolvedAttrs: Partial<T> = {};\n\n sortedStates.forEach(stateName => {\n const attrs = stateProxy ? stateProxy(stateName, sortedStates) : states?.[stateName];\n\n if (attrs == null) {\n return;\n }\n\n for (const key in attrs) {\n if (!Object.prototype.hasOwnProperty.call(attrs, key)) {\n continue;\n }\n\n const nextValue = attrs[key];\n\n if (\n mergeMode === 'deep' &&\n isPlainObject(nextValue) &&\n (isPlainObject((resolvedAttrs as Record<string, any>)[key]) ||\n isPlainObject((normalAttrs as Record<string, any>)[key]))\n ) {\n const baseValue = isPlainObject((resolvedAttrs as Record<string, any>)[key])\n ? (resolvedAttrs as Record<string, any>)[key]\n : isPlainObject((normalAttrs as Record<string, any>)[key])\n ? (normalAttrs as Record<string, any>)[key]\n : {};\n (resolvedAttrs as Record<string, any>)[key] = deepMerge(baseValue, nextValue);\n } else {\n (resolvedAttrs as Record<string, any>)[key] = cloneValue(nextValue);\n }\n }\n });\n\n return resolvedAttrs;\n }\n\n resolveWithCompiled(\n normalAttrs: Partial<T>,\n compiledDefinitions: Map<string, CompiledStateDefinition<T>>,\n stateProxy: StateProxy<T> | undefined,\n effectiveStates: string[],\n resolvedPatch: Partial<T>\n ): Partial<T> {\n const mergeMode = this.options.mergeMode ?? 'shallow';\n const resolvedAttrs = cloneValue(resolvedPatch) ?? {};\n\n effectiveStates.forEach(stateName => {\n const proxyPatch = stateProxy?.(stateName, effectiveStates);\n if (proxyPatch == null) {\n return;\n }\n\n Object.keys(proxyPatch).forEach(key => {\n const nextValue = (proxyPatch as Record<string, any>)[key];\n const hasCompiledDefinition = compiledDefinitions.has(stateName);\n\n if (\n mergeMode === 'deep' &&\n isPlainObject(nextValue) &&\n (isPlainObject((resolvedAttrs as Record<string, any>)[key]) ||\n (!hasCompiledDefinition && isPlainObject((normalAttrs as Record<string, any>)[key])))\n ) {\n const baseValue = isPlainObject((resolvedAttrs as Record<string, any>)[key])\n ? (resolvedAttrs as Record<string, any>)[key]\n : isPlainObject((normalAttrs as Record<string, any>)[key])\n ? (normalAttrs as Record<string, any>)[key]\n : {};\n (resolvedAttrs as Record<string, any>)[key] = deepMerge(baseValue, nextValue);\n return;\n }\n\n (resolvedAttrs as Record<string, any>)[key] = cloneValue(nextValue);\n });\n });\n\n return resolvedAttrs;\n }\n\n computeNormalAttrsBackup(\n normalAttrs: Partial<T> | null | undefined,\n targetAttrs: Partial<T>,\n finalAttribute: Record<string, any>\n ): IStateStyleBackupResult<T> {\n const nextNormalAttrs: Partial<T> = {};\n const nextTargetAttrs = { ...targetAttrs };\n\n for (const key in targetAttrs) {\n if (!Object.prototype.hasOwnProperty.call(targetAttrs, key)) {\n continue;\n }\n\n if (normalAttrs && key in normalAttrs) {\n (nextNormalAttrs as Record<string, any>)[key] = cloneValue((normalAttrs as Record<string, any>)[key]);\n } else {\n (nextNormalAttrs as Record<string, any>)[key] = cloneValue(finalAttribute[key]);\n }\n }\n\n if (normalAttrs) {\n for (const key in normalAttrs) {\n if (!Object.prototype.hasOwnProperty.call(normalAttrs, key) || key in targetAttrs) {\n continue;\n }\n (nextTargetAttrs as Record<string, any>)[key] = cloneValue((normalAttrs as Record<string, any>)[key]);\n }\n }\n\n return {\n attrs: nextTargetAttrs,\n normalAttrs: nextNormalAttrs\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphic/state/state-style-resolver.ts"],"names":[],"mappings":"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","file":"state-style-resolver.js","sourcesContent":["import type { StateProxy, StateSort } from './state-model';\n\nexport type StateMergeMode = 'shallow' | 'deep';\n\nexport interface IStateStyleResolverOptions {\n mergeMode?: StateMergeMode;\n}\n\nexport interface IStateStyleResolver<T> {\n resolve: (\n normalAttrs: Partial<T>,\n states: Record<string, Partial<T>> | undefined,\n stateProxy: StateProxy<T> | undefined,\n currentStates: string[],\n stateSort?: StateSort\n ) => Partial<T>;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, any> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction cloneValue<T>(value: T): T {\n if (!isPlainObject(value)) {\n return value;\n }\n\n const clone: Record<string, any> = {};\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue;\n }\n clone[key] = cloneValue((value as Record<string, any>)[key]);\n }\n return clone as T;\n}\n\nfunction deepMerge(base: Record<string, any>, value: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = cloneValue(base) || {};\n\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue;\n }\n\n const nextValue = value[key];\n const previousValue = result[key];\n\n if (isPlainObject(previousValue) && isPlainObject(nextValue)) {\n result[key] = deepMerge(previousValue, nextValue);\n } else {\n result[key] = cloneValue(nextValue);\n }\n }\n\n return result;\n}\n\nexport class StateStyleResolver<T extends Record<string, any> = Record<string, any>> implements IStateStyleResolver<T> {\n constructor(private readonly options: IStateStyleResolverOptions = {}) {}\n\n resolve(\n normalAttrs: Partial<T>,\n states: Record<string, Partial<T>> | undefined,\n stateProxy: StateProxy<T> | undefined,\n currentStates: string[],\n stateSort?: StateSort\n ): Partial<T> {\n const mergeMode = this.options.mergeMode ?? 'shallow';\n const sortedStates = stateSort ? currentStates.slice().sort(stateSort) : currentStates.slice();\n const resolvedAttrs: Partial<T> = {};\n\n sortedStates.forEach(stateName => {\n const attrs = stateProxy ? stateProxy(stateName, sortedStates) : states?.[stateName];\n\n if (attrs == null) {\n return;\n }\n\n for (const key in attrs) {\n if (!Object.prototype.hasOwnProperty.call(attrs, key)) {\n continue;\n }\n\n const nextValue = attrs[key];\n\n if (\n mergeMode === 'deep' &&\n isPlainObject(nextValue) &&\n (isPlainObject((resolvedAttrs as Record<string, any>)[key]) ||\n isPlainObject((normalAttrs as Record<string, any>)[key]))\n ) {\n const baseValue = isPlainObject((resolvedAttrs as Record<string, any>)[key])\n ? (resolvedAttrs as Record<string, any>)[key]\n : isPlainObject((normalAttrs as Record<string, any>)[key])\n ? (normalAttrs as Record<string, any>)[key]\n : {};\n (resolvedAttrs as Record<string, any>)[key] = deepMerge(baseValue, nextValue);\n } else {\n (resolvedAttrs as Record<string, any>)[key] = cloneValue(nextValue);\n }\n }\n });\n\n return resolvedAttrs;\n }\n}\n"]}
|
|
@@ -286,6 +286,7 @@ export interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphi
|
|
|
286
286
|
toggleState: (stateName: string, hasAnimation?: boolean) => void;
|
|
287
287
|
removeState: (stateName: string | string[], hasAnimation?: boolean) => void;
|
|
288
288
|
clearStates: (hasAnimation?: boolean) => void;
|
|
289
|
+
setStates: (states?: string[] | null, hasAnimation?: boolean) => void;
|
|
289
290
|
useStates: (states: string[], hasAnimation?: boolean) => void;
|
|
290
291
|
addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;
|
|
291
292
|
invalidateResolver: () => void;
|
|
@@ -327,6 +328,7 @@ export interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphi
|
|
|
327
328
|
initAttributes: (params: Partial<T>) => void;
|
|
328
329
|
setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;
|
|
329
330
|
setStage: (stage?: IStage, layer?: ILayer) => void;
|
|
331
|
+
detachStageForRelease: () => void;
|
|
330
332
|
onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;
|
|
331
333
|
shouldUpdateAABBBounds: () => boolean;
|
|
332
334
|
shouldSelfChangeUpdateAABBBounds: () => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IMatrix, IPointLike, IPoint, BoundsAnchorType, IOBBBounds } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget, ITimeline } from './animation';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\nimport type { ISymbolClass } from './graphic/symbol';\nimport type {\n CompiledStateDefinition,\n StateDefinition,\n StateDefinitionsInput\n} from '../graphic/state/state-definition';\nimport type { StateMergeMode } from '../graphic/state/state-style-resolver';\nimport type { SharedStateScope } from '../graphic/state/shared-state-scope';\n\ntype IStrokeSeg = {\n /**\n * 百分比\n */\n start: number;\n /**\n * 百分比\n * end和length二选一\n */\n end: number;\n /**\n * 像素长度\n */\n length: number;\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph'\n | string;\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n /**\n * x坐标\n */\n x: number;\n /**\n * y坐标\n */\n y: number;\n /**\n * z坐标\n */\n z: number;\n /**\n * x方向偏移量\n */\n dx: number;\n /**\n * y方向偏移量\n */\n dy: number;\n /**\n * z方向偏移量\n */\n dz: number;\n /**\n * x方向的滚动值\n */\n scrollX: number;\n /**\n * y方向的滚动值\n */\n scrollY: number;\n /**\n * x方向的缩放值\n */\n scaleX: number;\n /**\n * y方向的缩放值\n */\n scaleY: number;\n /**\n * z方向的缩放值\n */\n scaleZ: number;\n /**\n * 绕z轴的转角,即xy平面上的旋转角度\n */\n angle: number;\n /**\n * 绕x轴的转角\n */\n alpha: number;\n /**\n * 绕y轴的转角\n */\n beta: number;\n /**\n * 应用缩放的中心\n */\n scaleCenter: [number | string, number | string];\n /**\n * 基于AABB的锚点位置,用于简单的定位某些path\n */\n anchor: [number | string, number | string];\n /**\n * 3d的锚点位置\n */\n anchor3d: [number | string, number | string, number] | [number | string, number | string];\n /**\n * 处理矩阵,在正常计算完变换矩阵之后,会将该矩阵乘到变换矩阵上得到最终的变换矩阵\n */\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n /**\n * 图形的填充透明度\n */\n fillOpacity: number;\n /**\n * 图形模糊效果程度\n */\n shadowBlur: number;\n /**\n * 图形的阴影颜色\n */\n shadowColor: string;\n /**\n * 阴影水平偏移距离\n */\n shadowOffsetX: number;\n /**\n * 阴影垂直偏移距离\n */\n shadowOffsetY: number;\n /**\n * 图形的填充颜色\n */\n fill: IFillType;\n};\n\nexport type ILayout = {\n /**\n * 设置对齐方式\n */\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n /**\n * 边距离边缘的距离\n */\n distance: number | string;\n /**\n * 是否显示边框,默认是不显示的\n */\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n /**\n * 外部边框的样式配置,默认不展示外部边框\n */\n outerBorder: Partial<IBorderStyle>;\n /**\n * 内部边框的样式配置\n */\n innerBorder: Partial<IBorderStyle>;\n /**\n * 描边的透明度\n */\n strokeOpacity: number;\n /**\n * 设置线条虚线样式的属性,它通过定义实线和空白的交替长度来创建虚线效果\n */\n lineDash: number[];\n\n /**\n * 设置虚线样式的起始偏移量\n */\n lineDashOffset: number;\n\n /**\n * 设置线条的宽度\n */\n lineWidth: number;\n\n /**\n * 设置线条末端的样式\n */\n lineCap: CanvasLineCap;\n\n /**\n * 设置线条拐角的样式\n */\n lineJoin: CanvasLineJoin;\n\n /**\n * 设置线条拐角处的斜接限制\n */\n miterLimit: number;\n /**\n * 描边的boundsBuffer,用于控制bounds的buffer\n */\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n /**\n * 连接,取零或者断开\n */\n connectedType: 'connect' | 'none';\n /**\n * 连接线的样式配置\n */\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\nexport type BackgroundSizing = 'cover' | 'contain' | 'fill' | 'auto';\nexport type BackgroundRepeatMode = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';\nexport type BackgroundSizingShorthand = 'no-repeat-cover' | 'no-repeat-contain' | 'no-repeat-fill' | 'no-repeat-auto';\nexport type BackgroundMode = BackgroundRepeatMode | BackgroundSizingShorthand;\nexport type BackgroundPositionHorizontalKeyword = 'left' | 'center' | 'right';\nexport type BackgroundPositionVerticalKeyword = 'top' | 'center' | 'bottom';\nexport type BackgroundPositionKeyword = BackgroundPositionHorizontalKeyword | BackgroundPositionVerticalKeyword;\nexport type BackgroundPositionPercent = `${number}%`;\nexport type BackgroundPositionValue = number | BackgroundPositionKeyword | BackgroundPositionPercent;\nexport type BackgroundPositionPreset =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\nexport type BackgroundPosition =\n | BackgroundPositionKeyword\n | BackgroundPositionPreset\n | [BackgroundPositionValue, BackgroundPositionValue];\n\nexport type IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport interface SimpleDomStyleOptions {\n /**\n * 容器的宽度\n */\n width: number;\n /**\n * 容器的高度\n */\n height: number;\n /**\n * 容器的样式设置\n */\n style?:\n | string\n | Record<string, any>\n | ((\n pos: { top: number; left: number; width: number; height: number },\n graphic: IGraphic,\n wrapContainer: HTMLElement\n ) => Record<string, any>); // 容器的样式\n}\n\nexport interface CommonDomOptions {\n /**\n * 全局唯一的id\n */\n id?: string;\n /**\n * 容器元素的id或者dom元素\n */\n container: string | HTMLElement | null;\n /**\n * 是否显示\n */\n visible?: boolean;\n /**\n * 是否支持事件冒泡\n */\n pointerEvents?: boolean | string;\n /**\n * 可穿透的事件列表\n * @since 0.21.2\n */\n penetrateEventList?: string[];\n /**\n * 定位类型\n * 'position' - 根据挂载图形节点的坐标也就是x,y进行定位\n * 'boundsLeftTop' - 定位到挂载图形节点bounds的左上角\n * 'left' - 定位到挂载图形节点bounds 的左侧\n * 'right' - 定位到挂载图形节点bounds 的右侧\n * 'bottom' - 定位到挂载图形节点bounds 的底部\n * 'top' - 定位到挂载图形节点bounds 的顶部\n * 'center' - 定位到挂载图形节点bounds 的中心\n * 'top-left' - 定位到挂载图形节点bounds 的左上角\n * 'top-right' - 定位到挂载图形节点bounds 的右上角\n * 'bottom-left' - 定位到挂载图形节点bounds 的左下角\n * 'bottom-right' - 定位到挂载图形节点bounds 的右下角\n */\n anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType;\n}\n\nexport type IRoughStyle = {\n fillStyle: 'hachure' | 'solid' | 'zigzag' | 'cross-hatch' | 'dots' | 'sunburst' | 'dashed' | 'zigzag-line';\n roughness: number;\n bowing: number;\n};\n\nexport type IGraphicStyle = ILayout &\n IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n /**\n * 强制设置的bounds宽度,主要用于使用html或者react展示图形的时候,设置一个固定的宽度\n */\n forceBoundsWidth: number | (() => number) | undefined;\n /**\n * 强制设置的bounds高度,主要用于使用html或者react展示图形的时候,设置一个固定的高度\n */\n forceBoundsHeight: number | (() => number) | undefined;\n /**\n * 透明度,会同时影响填充和描边\n */\n opacity: number;\n /**\n * 影子节点\n */\n shadowGraphic?: IGraphic | undefined;\n /**\n * 背景填充模式(与具体图元有关)\n */\n backgroundMode: BackgroundMode;\n /**\n * 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n */\n backgroundFit: boolean;\n /**\n * 是否保持背景图的宽高比\n */\n backgroundKeepAspectRatio: boolean;\n /**\n * 背景图缩放,只在no-repeat的时候生效\n */\n backgroundScale: number;\n /**\n * 背景图偏移,只在no-repeat的时候生效\n */\n backgroundOffsetX: number;\n /**\n * 背景图偏移,只在no-repeat的时候生效\n */\n backgroundOffsetY: number;\n /**\n * 背景图锚定位置(类似 CSS background-position),仅在 no-repeat 的图片背景下生效。\n */\n backgroundPosition: BackgroundPosition;\n /**\n * 背景图是否裁切,是否调用clip避免绘制到图元外部\n */\n backgroundClip: boolean;\n /**\n * 背景圆角半径\n */\n backgroundCornerRadius: number | number[];\n /**\n * 背景透明度\n */\n backgroundOpacity: number;\n /**\n * 背景,支持颜色字符串、html image元素、html canvas元素\n */\n // 纹理是否自动做动画\n autoAnimateTexture: boolean;\n // 如果做动画的话,这里代表ratio\n textureRatio: number;\n textureOptions: any;\n background:\n | IBackgroundType\n | {\n /**\n * 背景,支持颜色字符串、html image元素、html canvas元素\n */\n background: IBackgroundType;\n /**\n * 背景的x方向偏移量\n */\n dx?: number;\n /**\n * 背景的y方向偏移量\n */\n dy?: number;\n /**\n * 背景宽度\n */\n width?: number;\n /**\n * 背景高度\n */\n height?: number;\n /**\n * 背景的x坐标\n */\n x?: number;\n /**\n * 背景的y坐标\n */\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n /**\n * 纹理的类型\n */\n texture: TextureType | string;\n /**\n * 纹理的颜色\n */\n textureColor: string;\n /**\n * 纹理的大小\n */\n textureSize: number;\n /**\n * 纹理的间隙\n */\n texturePadding: number;\n\n blur: number;\n /**\n * 设置图形对应的鼠标样式\n */\n cursor: Cursor | null;\n // @deprecated 用处少废弃,后续考虑新设计API\n filter: string;\n renderStyle?: 'default' | 'rough' | any;\n roughStyle?: IRoughStyle | null;\n /**\n * HTML的dom或者string\n */\n html:\n | ({\n /**\n * dom字符串或者dom\n */\n dom: string | HTMLElement;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n /**\n * 使用react元素渲染内容\n */\n react:\n | ({\n /**\n * react场景节点\n */\n element: any;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n /**\n * 使用vue组件渲染内容\n */\n vue:\n | ({\n /**\n * vue 虚拟节点\n */\n element: any;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n };\n\nexport type IPickStyle = {\n /**\n * 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n */\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n /**\n * 包围盒的padding\n */\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise' | 'empty';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n /**\n * 分组下的层级,层级越小越先绘制\n */\n zIndex: number;\n layout: any;\n /**\n * 是否隐藏元素(只是绘制的时候不绘制)\n */\n renderable: boolean;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n shadowPickMode?: 'full' | 'graphic';\n /**\n * 全局范围的层级,设置了这个属性的图形,会提取到交互层进行渲染\n */\n globalZIndex: number;\n /**\n * canvas 的合成方式\n */\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n /**\n * 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n */\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n /**\n * 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制\n */\n fillStrokeOrder: number;\n /**\n * @since 0.20.15\n * 保持stroke的scale,默认为false,为true的话stroke显示的宽度会随着scale变化\n */\n keepStrokeScale: boolean;\n\n /**\n * @since 0.22.2\n * 裁剪路径,用于裁剪图形,用于普通图元的裁剪\n * 由于一般情况下普通图元只需要一个形状即可,所以这里不需要配置具体的位置和大小,强制中心在图元中心,宽高和图元Bounds宽高一致\n * 不考虑其他复杂情况,否则配置项就非常多了,比如多路径,或者配置位置大小等,如果配置大小那还得用户自己去拿图元的大小,目前没有这种需求\n */\n clipConfig: {\n shape: string;\n } | null;\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n baseAttributes?: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n slience?: boolean;\n id?: number | string;\n timeline?: ITimeline;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n attachedThemeGraphic?: IGraphic<any>;\n /**\n * 保存语法上下文\n */\n context?: Record<string, any>;\n bindDom?: Map<\n string | HTMLElement,\n { container: HTMLElement | string; dom: HTMLElement | any; wrapGroup: HTMLDivElement | any; root?: any }\n >;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 不考虑transform的宽高,特殊情况下会使用到\n widthWithoutTransform?: number;\n heightWithoutTransform?: number;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: StateDefinitionsInput<T>;\n effectiveStates?: string[];\n resolvedStatePatch?: Partial<T>;\n normalAttrs?: Partial<T>;\n baseAttributes?: Partial<T>;\n boundSharedStateScope?: SharedStateScope<T>;\n boundSharedStateRevision?: number;\n sharedStateDirty?: boolean;\n registeredActiveScopes?: Set<SharedStateScope<T>>;\n localFallbackCompiledDefinitions?: Map<string, CompiledStateDefinition<T>>;\n localFallbackVersion?: number;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n stateMergeMode?: StateMergeMode;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string | string[], hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n invalidateResolver: () => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T> | StateDefinition<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (\n attrs: Partial<T>,\n stateNames: string[],\n hasAnimation?: boolean,\n isClear?: boolean,\n animateConfig?: IAnimateConfig\n ) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n getClipPath: () => ISymbolClass | null;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdatePaintTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate?: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n getGraphicTheme: () => T;\n\n getAttributes: (final?: boolean) => Partial<T>;\n\n pauseAnimation?: (deep?: boolean) => void;\n resumeAnimation?: (deep?: boolean) => void;\n stopAnimation?: (deep?: boolean) => void;\n reApplyAnimationState?: (state: string, deep?: boolean) => this;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n noAnimateAttrs?: string[] | Record<string, boolean | number>;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IMatrix, IPointLike, IPoint, BoundsAnchorType, IOBBBounds } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget, ITimeline } from './animation';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\nimport type { ISymbolClass } from './graphic/symbol';\nimport type {\n CompiledStateDefinition,\n StateDefinition,\n StateDefinitionsInput\n} from '../graphic/state/state-definition';\nimport type { StateMergeMode } from '../graphic/state/state-style-resolver';\nimport type { SharedStateScope } from '../graphic/state/shared-state-scope';\n\ntype IStrokeSeg = {\n /**\n * 百分比\n */\n start: number;\n /**\n * 百分比\n * end和length二选一\n */\n end: number;\n /**\n * 像素长度\n */\n length: number;\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph'\n | string;\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n /**\n * x坐标\n */\n x: number;\n /**\n * y坐标\n */\n y: number;\n /**\n * z坐标\n */\n z: number;\n /**\n * x方向偏移量\n */\n dx: number;\n /**\n * y方向偏移量\n */\n dy: number;\n /**\n * z方向偏移量\n */\n dz: number;\n /**\n * x方向的滚动值\n */\n scrollX: number;\n /**\n * y方向的滚动值\n */\n scrollY: number;\n /**\n * x方向的缩放值\n */\n scaleX: number;\n /**\n * y方向的缩放值\n */\n scaleY: number;\n /**\n * z方向的缩放值\n */\n scaleZ: number;\n /**\n * 绕z轴的转角,即xy平面上的旋转角度\n */\n angle: number;\n /**\n * 绕x轴的转角\n */\n alpha: number;\n /**\n * 绕y轴的转角\n */\n beta: number;\n /**\n * 应用缩放的中心\n */\n scaleCenter: [number | string, number | string];\n /**\n * 基于AABB的锚点位置,用于简单的定位某些path\n */\n anchor: [number | string, number | string];\n /**\n * 3d的锚点位置\n */\n anchor3d: [number | string, number | string, number] | [number | string, number | string];\n /**\n * 处理矩阵,在正常计算完变换矩阵之后,会将该矩阵乘到变换矩阵上得到最终的变换矩阵\n */\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n /**\n * 图形的填充透明度\n */\n fillOpacity: number;\n /**\n * 图形模糊效果程度\n */\n shadowBlur: number;\n /**\n * 图形的阴影颜色\n */\n shadowColor: string;\n /**\n * 阴影水平偏移距离\n */\n shadowOffsetX: number;\n /**\n * 阴影垂直偏移距离\n */\n shadowOffsetY: number;\n /**\n * 图形的填充颜色\n */\n fill: IFillType;\n};\n\nexport type ILayout = {\n /**\n * 设置对齐方式\n */\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n /**\n * 边距离边缘的距离\n */\n distance: number | string;\n /**\n * 是否显示边框,默认是不显示的\n */\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n /**\n * 外部边框的样式配置,默认不展示外部边框\n */\n outerBorder: Partial<IBorderStyle>;\n /**\n * 内部边框的样式配置\n */\n innerBorder: Partial<IBorderStyle>;\n /**\n * 描边的透明度\n */\n strokeOpacity: number;\n /**\n * 设置线条虚线样式的属性,它通过定义实线和空白的交替长度来创建虚线效果\n */\n lineDash: number[];\n\n /**\n * 设置虚线样式的起始偏移量\n */\n lineDashOffset: number;\n\n /**\n * 设置线条的宽度\n */\n lineWidth: number;\n\n /**\n * 设置线条末端的样式\n */\n lineCap: CanvasLineCap;\n\n /**\n * 设置线条拐角的样式\n */\n lineJoin: CanvasLineJoin;\n\n /**\n * 设置线条拐角处的斜接限制\n */\n miterLimit: number;\n /**\n * 描边的boundsBuffer,用于控制bounds的buffer\n */\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n /**\n * 连接,取零或者断开\n */\n connectedType: 'connect' | 'none';\n /**\n * 连接线的样式配置\n */\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\nexport type BackgroundSizing = 'cover' | 'contain' | 'fill' | 'auto';\nexport type BackgroundRepeatMode = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';\nexport type BackgroundSizingShorthand = 'no-repeat-cover' | 'no-repeat-contain' | 'no-repeat-fill' | 'no-repeat-auto';\nexport type BackgroundMode = BackgroundRepeatMode | BackgroundSizingShorthand;\nexport type BackgroundPositionHorizontalKeyword = 'left' | 'center' | 'right';\nexport type BackgroundPositionVerticalKeyword = 'top' | 'center' | 'bottom';\nexport type BackgroundPositionKeyword = BackgroundPositionHorizontalKeyword | BackgroundPositionVerticalKeyword;\nexport type BackgroundPositionPercent = `${number}%`;\nexport type BackgroundPositionValue = number | BackgroundPositionKeyword | BackgroundPositionPercent;\nexport type BackgroundPositionPreset =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\nexport type BackgroundPosition =\n | BackgroundPositionKeyword\n | BackgroundPositionPreset\n | [BackgroundPositionValue, BackgroundPositionValue];\n\nexport type IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport interface SimpleDomStyleOptions {\n /**\n * 容器的宽度\n */\n width: number;\n /**\n * 容器的高度\n */\n height: number;\n /**\n * 容器的样式设置\n */\n style?:\n | string\n | Record<string, any>\n | ((\n pos: { top: number; left: number; width: number; height: number },\n graphic: IGraphic,\n wrapContainer: HTMLElement\n ) => Record<string, any>); // 容器的样式\n}\n\nexport interface CommonDomOptions {\n /**\n * 全局唯一的id\n */\n id?: string;\n /**\n * 容器元素的id或者dom元素\n */\n container: string | HTMLElement | null;\n /**\n * 是否显示\n */\n visible?: boolean;\n /**\n * 是否支持事件冒泡\n */\n pointerEvents?: boolean | string;\n /**\n * 可穿透的事件列表\n * @since 0.21.2\n */\n penetrateEventList?: string[];\n /**\n * 定位类型\n * 'position' - 根据挂载图形节点的坐标也就是x,y进行定位\n * 'boundsLeftTop' - 定位到挂载图形节点bounds的左上角\n * 'left' - 定位到挂载图形节点bounds 的左侧\n * 'right' - 定位到挂载图形节点bounds 的右侧\n * 'bottom' - 定位到挂载图形节点bounds 的底部\n * 'top' - 定位到挂载图形节点bounds 的顶部\n * 'center' - 定位到挂载图形节点bounds 的中心\n * 'top-left' - 定位到挂载图形节点bounds 的左上角\n * 'top-right' - 定位到挂载图形节点bounds 的右上角\n * 'bottom-left' - 定位到挂载图形节点bounds 的左下角\n * 'bottom-right' - 定位到挂载图形节点bounds 的右下角\n */\n anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType;\n}\n\nexport type IRoughStyle = {\n fillStyle: 'hachure' | 'solid' | 'zigzag' | 'cross-hatch' | 'dots' | 'sunburst' | 'dashed' | 'zigzag-line';\n roughness: number;\n bowing: number;\n};\n\nexport type IGraphicStyle = ILayout &\n IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n /**\n * 强制设置的bounds宽度,主要用于使用html或者react展示图形的时候,设置一个固定的宽度\n */\n forceBoundsWidth: number | (() => number) | undefined;\n /**\n * 强制设置的bounds高度,主要用于使用html或者react展示图形的时候,设置一个固定的高度\n */\n forceBoundsHeight: number | (() => number) | undefined;\n /**\n * 透明度,会同时影响填充和描边\n */\n opacity: number;\n /**\n * 影子节点\n */\n shadowGraphic?: IGraphic | undefined;\n /**\n * 背景填充模式(与具体图元有关)\n */\n backgroundMode: BackgroundMode;\n /**\n * 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n */\n backgroundFit: boolean;\n /**\n * 是否保持背景图的宽高比\n */\n backgroundKeepAspectRatio: boolean;\n /**\n * 背景图缩放,只在no-repeat的时候生效\n */\n backgroundScale: number;\n /**\n * 背景图偏移,只在no-repeat的时候生效\n */\n backgroundOffsetX: number;\n /**\n * 背景图偏移,只在no-repeat的时候生效\n */\n backgroundOffsetY: number;\n /**\n * 背景图锚定位置(类似 CSS background-position),仅在 no-repeat 的图片背景下生效。\n */\n backgroundPosition: BackgroundPosition;\n /**\n * 背景图是否裁切,是否调用clip避免绘制到图元外部\n */\n backgroundClip: boolean;\n /**\n * 背景圆角半径\n */\n backgroundCornerRadius: number | number[];\n /**\n * 背景透明度\n */\n backgroundOpacity: number;\n /**\n * 背景,支持颜色字符串、html image元素、html canvas元素\n */\n // 纹理是否自动做动画\n autoAnimateTexture: boolean;\n // 如果做动画的话,这里代表ratio\n textureRatio: number;\n textureOptions: any;\n background:\n | IBackgroundType\n | {\n /**\n * 背景,支持颜色字符串、html image元素、html canvas元素\n */\n background: IBackgroundType;\n /**\n * 背景的x方向偏移量\n */\n dx?: number;\n /**\n * 背景的y方向偏移量\n */\n dy?: number;\n /**\n * 背景宽度\n */\n width?: number;\n /**\n * 背景高度\n */\n height?: number;\n /**\n * 背景的x坐标\n */\n x?: number;\n /**\n * 背景的y坐标\n */\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n /**\n * 纹理的类型\n */\n texture: TextureType | string;\n /**\n * 纹理的颜色\n */\n textureColor: string;\n /**\n * 纹理的大小\n */\n textureSize: number;\n /**\n * 纹理的间隙\n */\n texturePadding: number;\n\n blur: number;\n /**\n * 设置图形对应的鼠标样式\n */\n cursor: Cursor | null;\n // @deprecated 用处少废弃,后续考虑新设计API\n filter: string;\n renderStyle?: 'default' | 'rough' | any;\n roughStyle?: IRoughStyle | null;\n /**\n * HTML的dom或者string\n */\n html:\n | ({\n /**\n * dom字符串或者dom\n */\n dom: string | HTMLElement;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n /**\n * 使用react元素渲染内容\n */\n react:\n | ({\n /**\n * react场景节点\n */\n element: any;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n /**\n * 使用vue组件渲染内容\n */\n vue:\n | ({\n /**\n * vue 虚拟节点\n */\n element: any;\n } & SimpleDomStyleOptions &\n CommonDomOptions)\n | null;\n };\n\nexport type IPickStyle = {\n /**\n * 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n */\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n /**\n * 包围盒的padding\n */\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise' | 'empty';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n /**\n * 分组下的层级,层级越小越先绘制\n */\n zIndex: number;\n layout: any;\n /**\n * 是否隐藏元素(只是绘制的时候不绘制)\n */\n renderable: boolean;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n shadowPickMode?: 'full' | 'graphic';\n /**\n * 全局范围的层级,设置了这个属性的图形,会提取到交互层进行渲染\n */\n globalZIndex: number;\n /**\n * canvas 的合成方式\n */\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n /**\n * 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n */\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n /**\n * 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制\n */\n fillStrokeOrder: number;\n /**\n * @since 0.20.15\n * 保持stroke的scale,默认为false,为true的话stroke显示的宽度会随着scale变化\n */\n keepStrokeScale: boolean;\n\n /**\n * @since 0.22.2\n * 裁剪路径,用于裁剪图形,用于普通图元的裁剪\n * 由于一般情况下普通图元只需要一个形状即可,所以这里不需要配置具体的位置和大小,强制中心在图元中心,宽高和图元Bounds宽高一致\n * 不考虑其他复杂情况,否则配置项就非常多了,比如多路径,或者配置位置大小等,如果配置大小那还得用户自己去拿图元的大小,目前没有这种需求\n */\n clipConfig: {\n shape: string;\n } | null;\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n baseAttributes?: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n slience?: boolean;\n id?: number | string;\n timeline?: ITimeline;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n attachedThemeGraphic?: IGraphic<any>;\n /**\n * 保存语法上下文\n */\n context?: Record<string, any>;\n bindDom?: Map<\n string | HTMLElement,\n { container: HTMLElement | string; dom: HTMLElement | any; wrapGroup: HTMLDivElement | any; root?: any }\n >;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 不考虑transform的宽高,特殊情况下会使用到\n widthWithoutTransform?: number;\n heightWithoutTransform?: number;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: StateDefinitionsInput<T>;\n effectiveStates?: string[];\n resolvedStatePatch?: Partial<T>;\n normalAttrs?: Partial<T>;\n baseAttributes?: Partial<T>;\n boundSharedStateScope?: SharedStateScope<T>;\n boundSharedStateRevision?: number;\n sharedStateDirty?: boolean;\n registeredActiveScopes?: Set<SharedStateScope<T>>;\n localFallbackCompiledDefinitions?: Map<string, CompiledStateDefinition<T>>;\n localFallbackVersion?: number;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n stateMergeMode?: StateMergeMode;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string | string[], hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n setStates: (states?: string[] | null, hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n invalidateResolver: () => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T> | StateDefinition<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (\n attrs: Partial<T>,\n stateNames: string[],\n hasAnimation?: boolean,\n isClear?: boolean,\n animateConfig?: IAnimateConfig\n ) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n getClipPath: () => ISymbolClass | null;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdatePaintTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate?: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n detachStageForRelease: () => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n getGraphicTheme: () => T;\n\n getAttributes: (final?: boolean) => Partial<T>;\n\n pauseAnimation?: (deep?: boolean) => void;\n resumeAnimation?: (deep?: boolean) => void;\n stopAnimation?: (deep?: boolean) => void;\n reApplyAnimationState?: (state: string, deep?: boolean) => this;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n noAnimateAttrs?: string[] | Record<string, boolean | number>;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/node-tree.ts"],"names":[],"mappings":"","file":"node-tree.js","sourcesContent":["import type { IEventElement, Releaseable } from './common';\n\nexport interface INode extends Releaseable, IEventElement {\n _prev?: INode;\n _next?: INode;\n /**\n * 内部图形的唯一标识\n */\n _uid: number;\n\n /**\n * 用户配置的图形唯一标识\n */\n id?: number | string;\n /** 图形名称标识 */\n name?: string;\n /**\n * 图形类型\n */\n type?: string;\n parent: INode | null;\n // dirty: boolean; // 脏位,标记当前节点和子节点是否有修改\n count: number;\n childrenCount: number;\n firstChild: INode | null;\n lastChild: INode | null;\n /**\n * 获取子节点数组\n */\n getChildren: () => INode[];\n /**\n * 获取某个idx的节点\n */\n getChildAt: (idx: number) => INode | null;\n at: (idx: number) => INode | null;\n\n insertBefore: (newNode: INode, referenceNode: INode) => INode | null;\n insertAfter: (newNode: INode, referenceNode: INode) => INode | null;\n\n /**\n * 向某个位置插入\n */\n insertInto: (ele: INode, idx: number) => INode | null;\n\n insertIntoKeepIdx: (ele: INode, idx: number) => INode | null;\n /**\n * 遍历子节点\n * @param cb 返回true则停止遍历\n */\n forEachChildren: (cb: (n: INode, i: number) => void | boolean, reverse?: boolean) => void;\n forEachChildrenAsync: (\n cb: (n: INode, i: number) => Promise<void | boolean> | void | boolean,\n reverse?: boolean\n ) => Promise<void>;\n /**\n * 添加子节点\n * @param node\n * @param highPerformance 是否高性能模式(不检查是否合法)\n */\n appendChild: (node: INode, highPerformance?: boolean) => INode | null;\n /**\n * 添加子节点\n * @param node\n * @param highPerformance 是否高性能模式(不检查是否合法)\n */\n add: (node: INode, highPerformance?: boolean) => INode | null;\n /**\n * 从当前节点的父节点删除当前节点\n */\n delete: () => void;\n /**\n * 删除节点\n * @param node\n * @param highPerformance
|
|
1
|
+
{"version":3,"sources":["../src/interface/node-tree.ts"],"names":[],"mappings":"","file":"node-tree.js","sourcesContent":["import type { IEventElement, Releaseable } from './common';\n\nexport interface INode extends Releaseable, IEventElement {\n _prev?: INode;\n _next?: INode;\n /**\n * 内部图形的唯一标识\n */\n _uid: number;\n\n /**\n * 用户配置的图形唯一标识\n */\n id?: number | string;\n /** 图形名称标识 */\n name?: string;\n /**\n * 图形类型\n */\n type?: string;\n parent: INode | null;\n // dirty: boolean; // 脏位,标记当前节点和子节点是否有修改\n count: number;\n childrenCount: number;\n firstChild: INode | null;\n lastChild: INode | null;\n /**\n * 获取子节点数组\n */\n getChildren: () => INode[];\n /**\n * 获取某个idx的节点\n */\n getChildAt: (idx: number) => INode | null;\n at: (idx: number) => INode | null;\n\n insertBefore: (newNode: INode, referenceNode: INode) => INode | null;\n insertAfter: (newNode: INode, referenceNode: INode) => INode | null;\n\n /**\n * 向某个位置插入\n */\n insertInto: (ele: INode, idx: number) => INode | null;\n\n insertIntoKeepIdx: (ele: INode, idx: number) => INode | null;\n /**\n * 遍历子节点\n * @param cb 返回true则停止遍历\n */\n forEachChildren: (cb: (n: INode, i: number) => void | boolean, reverse?: boolean) => void;\n forEachChildrenAsync: (\n cb: (n: INode, i: number) => Promise<void | boolean> | void | boolean,\n reverse?: boolean\n ) => Promise<void>;\n /**\n * 添加子节点\n * @param node\n * @param highPerformance 是否高性能模式(不检查是否合法)\n */\n appendChild: (node: INode, highPerformance?: boolean) => INode | null;\n /**\n * 添加子节点\n * @param node\n * @param highPerformance 是否高性能模式(不检查是否合法)\n */\n add: (node: INode, highPerformance?: boolean) => INode | null;\n /**\n * 从当前节点的父节点删除当前节点\n */\n delete: () => void;\n /**\n * 删除节点\n * @param node\n * @param highPerformance 是否高性能模式;仅用于释放/批量清理,跳过更新和通知链路\n */\n removeChild: (node: INode, highPerformance?: boolean) => INode | null;\n /**\n * 移除所有节点\n */\n removeAllChild: (deep?: boolean) => void;\n /**\n * 判断该节点是否是node的子节点\n * @param node\n */\n isChildOf: (node: INode) => boolean;\n /**\n * 判断该节点是否是node的父节点\n * @param node\n */\n isParentOf: (node: INode) => boolean;\n /**\n * 判断节点是否是node的后代节点\n * @param node\n */\n isDescendantsOf: (node: INode) => boolean;\n /**\n * 判断节点是否是node的祖先节点\n * @param node\n */\n isAncestorsOf: (node: INode) => boolean;\n\n // 事件相关的别名\n /**\n * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\n * */\n dispatchEvent: (event: Event) => boolean;\n\n /**\n * 返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点。\n * @param node 判断是否包含的节点\n */\n containNode: (node: INode) => boolean;\n\n /**\n * 设置该节点的所有后代节点某个属性\n * @param propsName 属性名\n * @param propsValue 属性值\n */\n setAllDescendantsProps: (propsName: string, propsValue: any) => any;\n\n // 查找相关的接口\n /**\n * 根据自定义逻辑查找元素,返回单一图形元素\n * @param callback 自定义查找过滤器\n * @param deep 是否进行深度查找,默认为 false\n * @returns 返回匹配的图形元素\n */\n find: (callback: (node: INode, index: number) => boolean, deep: boolean) => INode | null;\n /**\n * 根据自定义逻辑查找元素,返回匹配的元素集合\n * @param callback 自定义查找过滤器\n * @param deep 是否进行深度查找,默认为 false\n * @returns 返回匹配的图形元素集合\n */\n findAll: (callback: (node: INode, index: number) => boolean, deep: boolean) => INode[];\n /**\n * 通过用户设置的 id 查找对应的图形元素\n * @param id 子节点的 id\n */\n getElementById: (id: string | number) => INode | null;\n /**\n * @alias getElementById\n * 通过用户设置的 id 查找对应的图形元素\n * @param id 子节点的 id\n */\n findChildById: (id: string | number) => INode | null;\n /**\n * 通过内部生成的节点 id:_uid 查找对应的图形元素\n * @param id 子节点的key\n */\n findChildByUid: (uid: number) => INode | null;\n /**\n * 根据用户传入的 name 查找元素,返回匹配的元素集合\n * @param name 用户设置的图形名称\n * @returns 匹配 name 的元素集合\n */\n getElementsByName: (name: string) => INode[];\n /**\n * @alias getElementsByName\n * 根据用户传入的 name 查找元素,返回匹配的元素集合\n * @param name 用户设置的图形名称\n * @returns 匹配 name 的元素集合\n */\n findChildrenByName: (name: string) => INode[];\n /**\n * 根据用户传入的 name 查找元素,返回匹配的元素集合\n * @param name 用户设置的图形名称\n * @returns 匹配 name 的元素集合\n */\n getElementsByType: (type: string) => INode[];\n // 其他不常用\n\n [key: string]: any;\n}\n"]}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { type IAABBBounds } from '@visactor/vutils';
|
|
2
|
-
import type { IGraphic, IPlugin, IPluginService } from '../../interface';
|
|
2
|
+
import type { IGraphic, IStage, IPlugin, IPluginService } from '../../interface';
|
|
3
3
|
export declare class DirtyBoundsPlugin implements IPlugin {
|
|
4
4
|
name: 'DirtyBoundsPlugin';
|
|
5
5
|
activeEvent: 'onRegister';
|
|
6
6
|
pluginService: IPluginService;
|
|
7
7
|
_uid: number;
|
|
8
8
|
key: string;
|
|
9
|
+
protected dirtyBoundsHooksRegistered: boolean;
|
|
9
10
|
protected ensurePaintDirtyBoundsCache(graphic: IGraphic): IAABBBounds;
|
|
11
|
+
protected getRemoveDirtyBounds(graphic: IGraphic): IAABBBounds | undefined;
|
|
10
12
|
protected handlePaintOnlyUpdate: (graphic: IGraphic) => void;
|
|
13
|
+
protected registerDirtyBoundsHooks(stage: IStage): void;
|
|
11
14
|
activate(context: IPluginService): void;
|
|
12
15
|
deactivate(context: IPluginService): void;
|
|
13
16
|
}
|
|
@@ -9,7 +9,7 @@ const vutils_1 = require("@visactor/vutils"), enums_1 = require("../../common/en
|
|
|
9
9
|
class DirtyBoundsPlugin {
|
|
10
10
|
constructor() {
|
|
11
11
|
this.name = "DirtyBoundsPlugin", this.activeEvent = "onRegister", this._uid = generator_1.Generator.GenAutoIncrementId(),
|
|
12
|
-
this.key = this.name + this._uid, this.handlePaintOnlyUpdate = graphic => {
|
|
12
|
+
this.key = this.name + this._uid, this.dirtyBoundsHooksRegistered = !1, this.handlePaintOnlyUpdate = graphic => {
|
|
13
13
|
var _a, _b, _c, _d;
|
|
14
14
|
const stage = this.pluginService.stage;
|
|
15
15
|
if (!stage || stage !== graphic.stage || !stage.renderCount) return;
|
|
@@ -30,12 +30,13 @@ class DirtyBoundsPlugin {
|
|
|
30
30
|
return owner._globalAABBBounds && "function" == typeof owner._globalAABBBounds.empty && !owner._globalAABBBounds.empty() || "function" != typeof owner.tryUpdateGlobalAABBBounds || owner.tryUpdateGlobalAABBBounds(),
|
|
31
31
|
null !== (_b = owner._globalAABBBounds) && void 0 !== _b ? _b : owner.globalAABBBounds;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
getRemoveDirtyBounds(graphic) {
|
|
34
|
+
var _a;
|
|
35
|
+
const cachedBounds = (null !== (_a = graphic.glyphHost) && void 0 !== _a ? _a : graphic)._globalAABBBounds;
|
|
36
|
+
if (cachedBounds && "function" == typeof cachedBounds.empty && !cachedBounds.empty()) return cachedBounds;
|
|
37
|
+
}
|
|
38
|
+
registerDirtyBoundsHooks(stage) {
|
|
39
|
+
this.dirtyBoundsHooksRegistered || (stage.graphicService.hooks.onAttributeUpdate.tap(this.key, this.handlePaintOnlyUpdate),
|
|
39
40
|
stage.graphicService.hooks.beforeUpdateAABBBounds.tap(this.key, ((graphic, stage, willUpdate, bounds) => {
|
|
40
41
|
graphic.glyphHost && (graphic = graphic.glyphHost), stage && stage === this.pluginService.stage && stage.renderCount && (graphic.isContainer && !graphic.shouldSelfChangeUpdateAABBBounds() || willUpdate && (globalBounds.setValue(bounds.x1, bounds.y1, bounds.x2, bounds.y2),
|
|
41
42
|
stage.dirty(globalBounds, graphic.parent && graphic.parent.globalTransMatrix)));
|
|
@@ -45,13 +46,22 @@ class DirtyBoundsPlugin {
|
|
|
45
46
|
stage && stage === this.pluginService.stage && stage.renderCount && stage && stage.dirty(bounds);
|
|
46
47
|
})), stage.graphicService.hooks.onRemove.tap(this.key, (graphic => {
|
|
47
48
|
const stage = graphic.stage;
|
|
48
|
-
stage
|
|
49
|
-
|
|
49
|
+
if (!stage || stage !== this.pluginService.stage || !stage.renderCount) return;
|
|
50
|
+
const bounds = this.getRemoveDirtyBounds(graphic);
|
|
51
|
+
bounds && !bounds.empty() && stage.dirty(bounds);
|
|
52
|
+
})), this.dirtyBoundsHooksRegistered = !0);
|
|
53
|
+
}
|
|
54
|
+
activate(context) {
|
|
55
|
+
this.pluginService = context, context.stage.hooks.afterRender.tap(this.key, (stage => {
|
|
56
|
+
stage && stage === this.pluginService.stage && (stage.dirtyBounds.clear(), this.registerDirtyBoundsHooks(stage));
|
|
57
|
+
}));
|
|
58
|
+
const stage = this.pluginService.stage;
|
|
59
|
+
stage && stage.renderCount && this.registerDirtyBoundsHooks(stage);
|
|
50
60
|
}
|
|
51
61
|
deactivate(context) {
|
|
52
62
|
const stage = this.pluginService.stage;
|
|
53
63
|
stage && (stage.graphicService.hooks.onAttributeUpdate.taps = stage.graphicService.hooks.onAttributeUpdate.taps.filter((item => item.name !== this.key)),
|
|
54
|
-
stage.graphicService.hooks.beforeUpdateAABBBounds.taps = stage.graphicService.hooks.beforeUpdateAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
64
|
+
this.dirtyBoundsHooksRegistered = !1, stage.graphicService.hooks.beforeUpdateAABBBounds.taps = stage.graphicService.hooks.beforeUpdateAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
55
65
|
stage.graphicService.hooks.afterUpdateAABBBounds.taps = stage.graphicService.hooks.afterUpdateAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
56
66
|
stage.graphicService.hooks.clearAABBBounds.taps = stage.graphicService.hooks.clearAABBBounds.taps.filter((item => item.name !== this.key)),
|
|
57
67
|
stage.hooks.afterRender.taps = stage.hooks.afterRender.taps.filter((item => item.name !== this.key)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugins/builtin-plugin/dirty-bounds-plugin.ts"],"names":[],"mappings":"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","file":"dirty-bounds-plugin.js","sourcesContent":["import { AABBBounds, type IAABBBounds } from '@visactor/vutils';\nimport { UpdateTag } from '../../common/enums';\nimport { Generator } from '../../common/generator';\nimport type { IGraphic, IStage, IPlugin, IPluginService } from '../../interface';\n\nconst globalBounds = new AABBBounds();\n\nexport class DirtyBoundsPlugin implements IPlugin {\n name: 'DirtyBoundsPlugin' = 'DirtyBoundsPlugin';\n activeEvent: 'onRegister' = 'onRegister';\n pluginService: IPluginService;\n _uid: number = Generator.GenAutoIncrementId();\n key: string = this.name + this._uid;\n\n protected ensurePaintDirtyBoundsCache(graphic: IGraphic): IAABBBounds {\n const owner = graphic as any;\n const hasLocalBounds =\n owner._AABBBounds && typeof owner._AABBBounds.empty === 'function' && !owner._AABBBounds.empty();\n if (!hasLocalBounds && typeof owner.doUpdateAABBBounds === 'function') {\n owner.doUpdateAABBBounds(owner.attribute?.boundsMode === 'imprecise');\n }\n\n const hasGlobalBounds =\n owner._globalAABBBounds &&\n typeof owner._globalAABBBounds.empty === 'function' &&\n !owner._globalAABBBounds.empty();\n if (!hasGlobalBounds && typeof owner.tryUpdateGlobalAABBBounds === 'function') {\n owner.tryUpdateGlobalAABBBounds();\n }\n\n return owner._globalAABBBounds ?? owner.globalAABBBounds;\n }\n\n protected handlePaintOnlyUpdate = (graphic: IGraphic) => {\n const stage = this.pluginService.stage;\n if (!(stage && stage === graphic.stage && stage.renderCount)) {\n return;\n }\n\n const owner = (graphic.glyphHost ?? graphic) as any;\n if (!(owner._updateTag & UpdateTag.UPDATE_PAINT) || owner._updateTag & UpdateTag.UPDATE_BOUNDS) {\n return;\n }\n\n const ownerBounds = this.ensurePaintDirtyBoundsCache(owner);\n if (ownerBounds && !ownerBounds.empty()) {\n stage.dirty(ownerBounds);\n }\n owner.clearUpdatePaintTag?.();\n\n const shadowRoot = owner.shadowRoot as IGraphic | undefined;\n if (!shadowRoot) {\n return;\n }\n\n const shadowBounds = this.ensurePaintDirtyBoundsCache(shadowRoot);\n if (shadowBounds && !shadowBounds.empty()) {\n stage.dirty(shadowBounds);\n }\n (shadowRoot as any).clearUpdatePaintTag?.();\n };\n\n activate(context: IPluginService): void {\n this.pluginService = context;\n context.stage.hooks.afterRender.tap(this.key, stage => {\n if (!(stage && stage === this.pluginService.stage)) {\n return;\n }\n stage.dirtyBounds.clear();\n });\n const stage = this.pluginService.stage;\n if (!stage) {\n return;\n }\n stage.graphicService.hooks.onAttributeUpdate.tap(this.key, this.handlePaintOnlyUpdate);\n stage.graphicService.hooks.beforeUpdateAABBBounds.tap(\n this.key,\n (graphic: IGraphic, stage: IStage, willUpdate: boolean, bounds: IAABBBounds) => {\n if (graphic.glyphHost) {\n graphic = graphic.glyphHost;\n }\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !graphic.shouldSelfChangeUpdateAABBBounds()) {\n return;\n }\n if (willUpdate) {\n globalBounds.setValue(bounds.x1, bounds.y1, bounds.x2, bounds.y2);\n stage.dirty(globalBounds, graphic.parent && graphic.parent.globalTransMatrix);\n }\n }\n );\n stage.graphicService.hooks.afterUpdateAABBBounds.tap(\n this.key,\n (\n graphic: IGraphic,\n stage: IStage,\n bounds: IAABBBounds,\n params: { globalAABBBounds: IAABBBounds },\n selfChange: boolean\n ) => {\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !selfChange) {\n return;\n }\n stage.dirty(params.globalAABBBounds);\n }\n );\n stage.graphicService.hooks.clearAABBBounds.tap(\n this.key,\n (graphic: IGraphic, stage: IStage, bounds: IAABBBounds) => {\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n if (stage) {\n stage.dirty(bounds);\n }\n }\n );\n stage.graphicService.hooks.onRemove.tap(this.key, (graphic: IGraphic) => {\n const stage = graphic.stage;\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n if (stage) {\n stage.dirty(graphic.globalAABBBounds);\n }\n });\n }\n deactivate(context: IPluginService): void {\n const stage = this.pluginService.stage;\n if (!stage) {\n return;\n }\n stage.graphicService.hooks.onAttributeUpdate.taps = stage.graphicService.hooks.onAttributeUpdate.taps.filter(\n item => {\n return item.name !== this.key;\n }\n );\n stage.graphicService.hooks.beforeUpdateAABBBounds.taps =\n stage.graphicService.hooks.beforeUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.afterUpdateAABBBounds.taps =\n stage.graphicService.hooks.afterUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.clearAABBBounds.taps = stage.graphicService.hooks.clearAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.hooks.afterRender.taps = stage.hooks.afterRender.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.onRemove.taps = stage.graphicService.hooks.onRemove.taps.filter(item => {\n return item.name !== this.key;\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugins/builtin-plugin/dirty-bounds-plugin.ts"],"names":[],"mappings":"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","file":"dirty-bounds-plugin.js","sourcesContent":["import { AABBBounds, type IAABBBounds } from '@visactor/vutils';\nimport { UpdateTag } from '../../common/enums';\nimport { Generator } from '../../common/generator';\nimport type { IGraphic, IStage, IPlugin, IPluginService } from '../../interface';\n\nconst globalBounds = new AABBBounds();\n\nexport class DirtyBoundsPlugin implements IPlugin {\n name: 'DirtyBoundsPlugin' = 'DirtyBoundsPlugin';\n activeEvent: 'onRegister' = 'onRegister';\n pluginService: IPluginService;\n _uid: number = Generator.GenAutoIncrementId();\n key: string = this.name + this._uid;\n protected dirtyBoundsHooksRegistered: boolean = false;\n\n protected ensurePaintDirtyBoundsCache(graphic: IGraphic): IAABBBounds {\n const owner = graphic as any;\n const hasLocalBounds =\n owner._AABBBounds && typeof owner._AABBBounds.empty === 'function' && !owner._AABBBounds.empty();\n if (!hasLocalBounds && typeof owner.doUpdateAABBBounds === 'function') {\n owner.doUpdateAABBBounds(owner.attribute?.boundsMode === 'imprecise');\n }\n\n const hasGlobalBounds =\n owner._globalAABBBounds &&\n typeof owner._globalAABBBounds.empty === 'function' &&\n !owner._globalAABBBounds.empty();\n if (!hasGlobalBounds && typeof owner.tryUpdateGlobalAABBBounds === 'function') {\n owner.tryUpdateGlobalAABBBounds();\n }\n\n return owner._globalAABBBounds ?? owner.globalAABBBounds;\n }\n\n protected getRemoveDirtyBounds(graphic: IGraphic): IAABBBounds | undefined {\n const owner = (graphic.glyphHost ?? graphic) as any;\n const cachedBounds = owner._globalAABBBounds as IAABBBounds | undefined;\n if (cachedBounds && typeof cachedBounds.empty === 'function' && !cachedBounds.empty()) {\n return cachedBounds;\n }\n }\n\n protected handlePaintOnlyUpdate = (graphic: IGraphic) => {\n const stage = this.pluginService.stage;\n if (!(stage && stage === graphic.stage && stage.renderCount)) {\n return;\n }\n\n const owner = (graphic.glyphHost ?? graphic) as any;\n if (!(owner._updateTag & UpdateTag.UPDATE_PAINT) || owner._updateTag & UpdateTag.UPDATE_BOUNDS) {\n return;\n }\n\n const ownerBounds = this.ensurePaintDirtyBoundsCache(owner);\n if (ownerBounds && !ownerBounds.empty()) {\n stage.dirty(ownerBounds);\n }\n owner.clearUpdatePaintTag?.();\n\n const shadowRoot = owner.shadowRoot as IGraphic | undefined;\n if (!shadowRoot) {\n return;\n }\n\n const shadowBounds = this.ensurePaintDirtyBoundsCache(shadowRoot);\n if (shadowBounds && !shadowBounds.empty()) {\n stage.dirty(shadowBounds);\n }\n (shadowRoot as any).clearUpdatePaintTag?.();\n };\n\n protected registerDirtyBoundsHooks(stage: IStage): void {\n if (this.dirtyBoundsHooksRegistered) {\n return;\n }\n stage.graphicService.hooks.onAttributeUpdate.tap(this.key, this.handlePaintOnlyUpdate);\n stage.graphicService.hooks.beforeUpdateAABBBounds.tap(\n this.key,\n (graphic: IGraphic, stage: IStage, willUpdate: boolean, bounds: IAABBBounds) => {\n if (graphic.glyphHost) {\n graphic = graphic.glyphHost;\n }\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !graphic.shouldSelfChangeUpdateAABBBounds()) {\n return;\n }\n if (willUpdate) {\n globalBounds.setValue(bounds.x1, bounds.y1, bounds.x2, bounds.y2);\n stage.dirty(globalBounds, graphic.parent && graphic.parent.globalTransMatrix);\n }\n }\n );\n stage.graphicService.hooks.afterUpdateAABBBounds.tap(\n this.key,\n (\n graphic: IGraphic,\n stage: IStage,\n bounds: IAABBBounds,\n params: { globalAABBBounds: IAABBBounds },\n selfChange: boolean\n ) => {\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n // group的子元素导致的bounds更新不用做dirtyBounds\n if (graphic.isContainer && !selfChange) {\n return;\n }\n stage.dirty(params.globalAABBBounds);\n }\n );\n stage.graphicService.hooks.clearAABBBounds.tap(\n this.key,\n (graphic: IGraphic, stage: IStage, bounds: IAABBBounds) => {\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n if (stage) {\n stage.dirty(bounds);\n }\n }\n );\n stage.graphicService.hooks.onRemove.tap(this.key, (graphic: IGraphic) => {\n const stage = graphic.stage;\n if (!(stage && stage === this.pluginService.stage && stage.renderCount)) {\n return;\n }\n const bounds = this.getRemoveDirtyBounds(graphic);\n if (bounds && !bounds.empty()) {\n stage.dirty(bounds);\n }\n });\n this.dirtyBoundsHooksRegistered = true;\n }\n\n activate(context: IPluginService): void {\n this.pluginService = context;\n context.stage.hooks.afterRender.tap(this.key, stage => {\n if (!(stage && stage === this.pluginService.stage)) {\n return;\n }\n stage.dirtyBounds.clear();\n this.registerDirtyBoundsHooks(stage);\n });\n const stage = this.pluginService.stage;\n if (!stage) {\n return;\n }\n if (stage.renderCount) {\n this.registerDirtyBoundsHooks(stage);\n }\n }\n deactivate(context: IPluginService): void {\n const stage = this.pluginService.stage;\n if (!stage) {\n return;\n }\n stage.graphicService.hooks.onAttributeUpdate.taps = stage.graphicService.hooks.onAttributeUpdate.taps.filter(\n item => {\n return item.name !== this.key;\n }\n );\n this.dirtyBoundsHooksRegistered = false;\n stage.graphicService.hooks.beforeUpdateAABBBounds.taps =\n stage.graphicService.hooks.beforeUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.afterUpdateAABBBounds.taps =\n stage.graphicService.hooks.afterUpdateAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.clearAABBBounds.taps = stage.graphicService.hooks.clearAABBBounds.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.hooks.afterRender.taps = stage.hooks.afterRender.taps.filter(item => {\n return item.name !== this.key;\n });\n stage.graphicService.hooks.onRemove.taps = stage.graphicService.hooks.onRemove.taps.filter(item => {\n return item.name !== this.key;\n });\n }\n}\n"]}
|
|
@@ -234,8 +234,9 @@ class FlexLayoutPlugin {
|
|
|
234
234
|
graphic.glyphHost && (graphic = graphic.glyphHost), stage && stage === this.pluginService.stage && graphic.isContainer && !this.skipBoundsTrigger && _tempBounds.copy(bounds);
|
|
235
235
|
})), stage.graphicService.hooks.afterUpdateAABBBounds.tap(this.key, ((graphic, stage, bounds, params, selfChange) => {
|
|
236
236
|
stage && stage === this.pluginService.stage && graphic.isContainer && !this.skipBoundsTrigger && (_tempBounds.equals(bounds) || this.tryLayout(graphic, !1));
|
|
237
|
-
})), stage.graphicService.hooks.onSetStage.tap(this.key, (graphic => {
|
|
238
|
-
graphic.glyphHost && (graphic = graphic.glyphHost),
|
|
237
|
+
})), stage.graphicService.hooks.onSetStage.tap(this.key, ((graphic, nextStage) => {
|
|
238
|
+
nextStage && nextStage === this.pluginService.stage && (graphic.glyphHost && (graphic = graphic.glyphHost),
|
|
239
|
+
this.tryLayout(graphic, !1));
|
|
239
240
|
})));
|
|
240
241
|
}
|
|
241
242
|
deactivate(context) {
|