UNPKG

@visactor/vrender-core

Version:

```typescript import { xxx } from '@visactor/vrender-core'; ```

893 lines (861 loc) 80.4 kB
import { AABBBounds, isArray, isEqual, max, Matrix, OBBBounds, normalTransform, Point, isNil, isString, isValidUrl, isBase64, isObject } from "@visactor/vutils"; import { Node } from "./node-tree"; import { EventTarget, CustomEvent } from "../event"; import { DefaultTransform } from "./config"; import { application } from "../application"; import { CustomPath2D } from "../common/custom-path2d"; import { ResourceLoader } from "../resource-loader/loader"; import { AttributeUpdateType, IContainPointMode, UpdateTag } from "../common/enums"; import { BoundsContext } from "../common/bounds-context"; import { renderCommandList } from "../common/render-command-list"; import { parsePadding } from "../common/utils"; import { builtinSymbolsMap, builtInSymbolStrMap, CustomSymbolClass } from "./builtin-symbol"; import { isSvg, XMLParser } from "../common/xml"; import { SVG_PARSE_ATTRIBUTE_MAP, SVG_PARSE_ATTRIBUTE_MAP_KEYS } from "./constants"; import { DefaultStateAnimateConfig } from "../animate/config"; import { EmptyContext2d } from "../canvas"; import { StateDefinitionCompiler } from "./state/state-definition-compiler"; import { StateEngine } from "./state/state-engine"; import { ATTRIBUTE_CATEGORY, UpdateCategory, classifyAttributeDelta } from "./state/attribute-update-classifier"; import { StateTransitionOrchestrator } from "./state/state-transition-orchestrator"; import { collectSharedStateScopeChain, ensureSharedStateScopeFresh } from "./state/shared-state-scope"; import { enqueueGraphicSharedStateRefresh, scheduleStageSharedStateRefresh } from "./state/shared-state-refresh"; const _tempBounds = new AABBBounds, loadShadowRootFactory = () => require("./shadow-root"), tempMatrix = new Matrix; export const PURE_STYLE_KEY = [ "stroke", "opacity", "strokeOpacity", "lineDash", "lineDashOffset", "lineCap", "lineJoin", "miterLimit", "fill", "fillOpacity" ]; export const GRAPHIC_UPDATE_TAG_KEY = [ "lineWidth", "scaleX", "scaleY", "angle", "anchor", "visible" ]; const tempConstantXYKey = [ "x", "y" ], tempConstantScaleXYKey = [ "scaleX", "scaleY" ], tempConstantAngleKey = [ "angle" ], builtinTextureTypes = new Set([ "circle", "diamond", "rect", "vertical-line", "horizontal-line", "bias-lr", "bias-rl", "grid", "wave" ]), point = new Point, EMPTY_STATE_NAMES = [], BROAD_UPDATE_CATEGORY = UpdateCategory.PAINT | UpdateCategory.SHAPE | UpdateCategory.BOUNDS | UpdateCategory.TRANSFORM | UpdateCategory.LAYOUT; function isPlainObjectValue(value) { return "object" == typeof value && null != value && !Array.isArray(value); } function cloneAttributeValue(value) { if (!isPlainObjectValue(value)) return value; const source = value, clone = {}; return Object.keys(source).forEach((key => { const nextValue = source[key]; clone[key] = isPlainObjectValue(nextValue) ? cloneAttributeValue(nextValue) : nextValue; })), clone; } function cloneAttributeSurface(value) { if (!isPlainObjectValue(value)) return value; const source = value, clone = {}; return Object.keys(source).forEach((key => { const nextValue = source[key]; clone[key] = isPlainObjectValue(nextValue) ? Object.assign({}, nextValue) : nextValue; })), clone; } function areAttributeValuesEqual(left, right) { return left === right || !!(isPlainObjectValue(left) || isPlainObjectValue(right) || Array.isArray(left) || Array.isArray(right)) && isEqual(left, right); } function deepMergeAttributeValue(base, value) { var _a; const result = null !== (_a = cloneAttributeValue(base)) && void 0 !== _a ? _a : {}; return Object.keys(value).forEach((key => { const nextValue = value[key], previousValue = result[key]; isPlainObjectValue(previousValue) && isPlainObjectValue(nextValue) ? result[key] = deepMergeAttributeValue(previousValue, nextValue) : result[key] = cloneAttributeValue(nextValue); })), result; } export const NOWORK_ANIMATE_ATTR = { strokeSeg: 1, boundsPadding: 2, pickMode: 1, boundsMode: 1, customPickShape: 1, pickable: 1, childrenPickable: 1, visible: 1, zIndex: 1, layout: 1, keepDirIn3d: 1, globalZIndex: 1, outerBorder: 1, innerBorder: 1, lineDash: 1, lineCap: 1, lineJoin: 1, miterLimit: 2, strokeBoundsBuffer: 2, scaleCenter: 1, anchor: 1, anchor3d: 1, postMatrix: 1, backgroundMode: 2, background: 1, texture: 1, cursor: 1, html: 1 }; class GraphicImpl extends Node { static mixin(source) { const keys = Object.keys(source); for (let i = 0; i < keys.length; ++i) { const propertyName = keys[i]; Object.defineProperty(this.prototype, propertyName, Object.getOwnPropertyDescriptor(source, propertyName)); } } get AABBBounds() { return this.tryUpdateAABBBounds(); } get OBBBounds() { return this.tryUpdateOBBBounds(); } get globalAABBBounds() { return this.tryUpdateGlobalAABBBounds(); } get transMatrix() { return this.tryUpdateLocalTransMatrix(!0); } get globalTransMatrix() { return this.tryUpdateGlobalTransMatrix(!0); } get baseAttributes() { var _a; return null !== (_a = this._baseAttributes) && void 0 !== _a ? _a : this.attribute; } set baseAttributes(value) { value !== this.attribute ? this._baseAttributes = value : this._baseAttributes = void 0; } constructor(params = {}) { var _a; super(), this._AABBBounds = new AABBBounds, this._updateTag = UpdateTag.INIT, this.attribute = params, this.valid = this.isValid(), this.updateAABBBoundsStamp = 0, params.background && this.loadImage(null !== (_a = params.background.background) && void 0 !== _a ? _a : params.background, !0), params.texture && isExternalTexture(params.texture) && this.loadImage(params.texture, !1), params.shadowGraphic && this.setShadowGraphic(params.shadowGraphic); } get normalAttrs() { return this.baseAttributes; } set normalAttrs(_value) {} getBaseAttributesStorage() { var _a; return null !== (_a = this._baseAttributes) && void 0 !== _a ? _a : this.attribute; } getGraphicService() { var _a, _b; return null !== (_b = null === (_a = this.stage) || void 0 === _a ? void 0 : _a.graphicService) && void 0 !== _b ? _b : application.graphicService; } getAttributes() { return this.attribute; } getStateTransitionOrchestrator() { return this.stateTransitionOrchestrator || (this.stateTransitionOrchestrator = new StateTransitionOrchestrator), this.stateTransitionOrchestrator; } resolveBoundSharedStateScope() { var _a; let parent = this.parent; for (;parent; ) { if (parent.sharedStateScope) return parent.sharedStateScope; parent = parent.parent; } return null === (_a = this.stage) || void 0 === _a ? void 0 : _a.rootSharedStateScope; } syncSharedStateScopeBindingFromTree(markDirty = !0) { var _a; const nextScope = this.resolveBoundSharedStateScope(); return this.boundSharedStateScope === nextScope ? (this.syncSharedStateActiveRegistrations(), !1) : (this.boundSharedStateScope = nextScope, this.boundSharedStateRevision = void 0, this.compiledStateDefinitions = void 0, this.compiledStateDefinitionsCacheKey = void 0, this.stateEngine = void 0, this.stateEngineCompiledDefinitions = void 0, this.syncSharedStateActiveRegistrations(), markDirty && (null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) && this.markSharedStateDirty(), !0); } syncSharedStateScopeBindingOnTreeChange(markDirty = !0) { var _a, _b; return !!((null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) || this.boundSharedStateScope || (null === (_b = this.registeredActiveScopes) || void 0 === _b ? void 0 : _b.size) || this.sharedStateDirty) && this.syncSharedStateScopeBindingFromTree(markDirty); } syncSharedStateActiveRegistrations() { var _a; const previousScopes = this.registeredActiveScopes; if (!(null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) || !this.boundSharedStateScope) return (null == previousScopes ? void 0 : previousScopes.size) && (previousScopes.forEach((scope => { scope.subtreeActiveDescendants.delete(this); })), previousScopes.clear()), void (this.registeredActiveScopes = void 0); const nextScopes = new Set(collectSharedStateScopeChain(this.boundSharedStateScope)); null == previousScopes || previousScopes.forEach((scope => { nextScopes.has(scope) || scope.subtreeActiveDescendants.delete(this); })), nextScopes.forEach((scope => { scope.subtreeActiveDescendants.add(this); })), this.registeredActiveScopes = nextScopes; } clearSharedStateActiveRegistrations() { const previousScopes = this.registeredActiveScopes; previousScopes && (previousScopes.forEach((scope => { scope.subtreeActiveDescendants.delete(this); })), previousScopes.clear()), this.registeredActiveScopes = void 0; } markSharedStateDirty() { this.sharedStateDirty = !0, enqueueGraphicSharedStateRefresh(this.stage, this), scheduleStageSharedStateRefresh(this.stage); } onParentSharedStateTreeChanged(stage, layer) { this.stage === stage && this.layer === layer ? this.syncSharedStateScopeBindingOnTreeChange() : this.setStage(stage, layer); } refreshSharedStateBeforeRender() { var _a; (null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) ? (this.syncSharedStateScopeBindingFromTree(!1), this.boundSharedStateScope && ensureSharedStateScopeFresh(this.boundSharedStateScope), this.recomputeCurrentStatePatch(), this.stopStateAnimates(), this._restoreAttributeFromStaticTruth({ type: AttributeUpdateType.STATE }), this.emitStateUpdateEvent(), this.sharedStateDirty = !1) : this.sharedStateDirty = !1; } getLocalStatesVersion() { var _a, _b; return this.localStateDefinitionsSource !== this.states && (this.localStateDefinitionsSource = this.states, this.localStateDefinitionsVersion = (null !== (_a = this.localStateDefinitionsVersion) && void 0 !== _a ? _a : 0) + 1), null !== (_b = this.localStateDefinitionsVersion) && void 0 !== _b ? _b : 0; } resolveEffectiveCompiledDefinitions() { this.syncSharedStateScopeBindingFromTree(!1); const boundScope = this.boundSharedStateScope; boundScope && (ensureSharedStateScopeFresh(boundScope), this.boundSharedStateRevision = boundScope.revision); const hasStates = !!this.states && Object.keys(this.states).length > 0; if (!boundScope) { if (!hasStates) return { compiledDefinitions: void 0 }; const cacheKey = `local:${this.getLocalStatesVersion()}`; return this.compiledStateDefinitions && this.compiledStateDefinitionsCacheKey === cacheKey || (this.compiledStateDefinitions = (new StateDefinitionCompiler).compile(this.states), this.compiledStateDefinitionsCacheKey = cacheKey), { compiledDefinitions: this.compiledStateDefinitions }; } return { compiledDefinitions: boundScope.effectiveCompiledDefinitions }; } recomputeCurrentStatePatch() { var _a, _b; if (!(null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length)) return this.effectiveStates = [], this.resolvedStatePatch = void 0, void this.syncSharedStateActiveRegistrations(); const stateResolveBaseAttrs = this.getStateResolveBaseAttrs(), transition = this.resolveUseStatesTransition(this.currentStates, stateResolveBaseAttrs), effectiveStates = null !== (_b = transition.effectiveStates) && void 0 !== _b ? _b : transition.states, resolvedStateAttrs = this.stateEngine && this.compiledStateDefinitions ? Object.assign({}, this.stateEngine.resolvedPatch) : {}; this.currentStates = transition.states, this.effectiveStates = [ ...effectiveStates ], this.resolvedStatePatch = resolvedStateAttrs, this.syncSharedStateActiveRegistrations(); } buildStaticAttributeSnapshot() { var _a; const snapshot = cloneAttributeValue(null !== (_a = this.baseAttributes) && void 0 !== _a ? _a : {}), resolvedPatch = this.resolvedStatePatch; return resolvedPatch ? (Object.keys(resolvedPatch).forEach((key => { const nextValue = resolvedPatch[key], previousValue = snapshot[key]; "deep" === this.stateMergeMode && isPlainObjectValue(previousValue) && isPlainObjectValue(nextValue) ? snapshot[key] = deepMergeAttributeValue(previousValue, nextValue) : snapshot[key] = cloneAttributeValue(nextValue); })), snapshot) : snapshot; } buildRemovedStateAnimationAttrs(targetStateAttrs, previousResolvedStatePatch) { const extraAttrs = {}; if (!previousResolvedStatePatch) return extraAttrs; const snapshot = this.buildStaticAttributeSnapshot(), staticTargetAttrs = snapshot; return Object.keys(previousResolvedStatePatch).forEach((key => { const hasTargetAttr = Object.prototype.hasOwnProperty.call(targetStateAttrs, key); if (hasTargetAttr && void 0 !== targetStateAttrs[key]) return; const assignFallbackAttr = value => { void 0 === value && this.shouldSkipStateTransitionDefaultAttribute(key, staticTargetAttrs) || (extraAttrs[key] = void 0 === value ? value : cloneAttributeValue(value)); }; if (hasTargetAttr) assignFallbackAttr(this.getStateTransitionDefaultAttribute(key, staticTargetAttrs)); else if (Object.prototype.hasOwnProperty.call(snapshot, key)) { const snapshotValue = snapshot[key]; assignFallbackAttr(void 0 === snapshotValue ? this.getStateTransitionDefaultAttribute(key, staticTargetAttrs) : snapshotValue); } else assignFallbackAttr(this.getStateTransitionDefaultAttribute(key, staticTargetAttrs)); })), extraAttrs; } syncObjectToSnapshot(target, snapshot, excludedKeys) { const delta = new Map; return new Set([ ...Object.keys(target), ...Object.keys(snapshot) ]).forEach((key => { if (!0 === (null == excludedKeys ? void 0 : excludedKeys[key])) return; const hasNext = Object.prototype.hasOwnProperty.call(snapshot, key), previousValue = target[key]; if (!hasNext) return void (Object.prototype.hasOwnProperty.call(target, key) && (delta.set(key, { prev: previousValue, next: void 0 }), delete target[key])); const nextValue = snapshot[key]; areAttributeValuesEqual(previousValue, nextValue) || (delta.set(key, { prev: previousValue, next: nextValue }), target[key] = cloneAttributeValue(nextValue)); })), delta; } _syncAttribute(excludedKeys) { this.attribute === this.baseAttributes && this.resolvedStatePatch && this.detachAttributeFromBaseAttributes(); const snapshot = this.buildStaticAttributeSnapshot(), delta = this.syncObjectToSnapshot(this.attribute, snapshot, excludedKeys); return this.valid = this.isValid(), this.attributeMayContainTransientAttrs = !!excludedKeys, delta; } _syncFinalAttributeFromStaticTruth(excludedKeys) { const target = this.finalAttribute; if (!target) return; const snapshot = this.buildStaticAttributeSnapshot(); this.syncObjectToSnapshot(target, snapshot, excludedKeys); } mergeAttributeDeltaCategory(category, key, prev, next) { var _a; let nextCategory = "stroke" === key || "shadowBlur" === key ? classifyAttributeDelta(key, prev, next) : null !== (_a = ATTRIBUTE_CATEGORY[key]) && void 0 !== _a ? _a : UpdateCategory.PAINT; return nextCategory & UpdateCategory.PICK && (nextCategory |= UpdateCategory.BOUNDS), nextCategory === UpdateCategory.PAINT && this.needUpdateTag(key) && (nextCategory = UpdateCategory.SHAPE | UpdateCategory.BOUNDS), category | nextCategory; } submitUpdateByCategory(category, forceUpdateTag = !1) { if (forceUpdateTag) return this.addUpdateShapeAndBoundsTag(), this.addUpdatePositionTag(), void this.addUpdateLayoutTag(); (category & BROAD_UPDATE_CATEGORY) !== BROAD_UPDATE_CATEGORY ? (category & UpdateCategory.SHAPE ? this.addUpdateShapeAndBoundsTag() : category & UpdateCategory.BOUNDS && this.addUpdateBoundTag(), category & UpdateCategory.PAINT && this.addUpdatePaintTag(), category & UpdateCategory.TRANSFORM && this.addUpdatePositionTag(), category & UpdateCategory.LAYOUT && this.addUpdateLayoutTag()) : this.addBroadUpdateTag(); } submitUpdateByDelta(delta, forceUpdateTag = !1) { let category = UpdateCategory.NONE; delta.forEach(((entry, key) => { category = this.mergeAttributeDeltaCategory(category, key, entry.prev, entry.next); })), this.submitUpdateByCategory(category, forceUpdateTag); } submitTouchedKeyUpdate(keys, forceUpdateTag = !1) { this.submitTouchedUpdate(forceUpdateTag || this.needUpdateTags(keys)); } submitTouchedUpdate(needsShapeAndBounds) { !this.updateShapeAndBoundsTagSetted() && needsShapeAndBounds ? this.addUpdateShapeAndBoundsTag() : this.addUpdateBoundTag(), this.addUpdatePositionTag(), this.addUpdateLayoutTag(); } commitBaseAttributeMutation(forceUpdateTag = !1, context) { var _a, _b, _c; (null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) && (this.resolverEpoch = (null !== (_b = this.resolverEpoch) && void 0 !== _b ? _b : 0) + 1, null === (_c = this.stateEngine) || void 0 === _c || _c.invalidateResolverCache(), this.recomputeCurrentStatePatch()); const delta = this._syncAttribute(); this.submitUpdateByDelta(delta, forceUpdateTag), this.onAttributeUpdate(context); } canCommitBaseAttributesByTouchedKeys() { var _a, _b; return !((null === (_a = this.currentStates) || void 0 === _a ? void 0 : _a.length) || this.resolvedStatePatch || this.attributeMayContainTransientAttrs) && (!(null === (_b = this.animates) || void 0 === _b ? void 0 : _b.size) && !this._animationStateManager || !this.hasAnyTrackedAnimate()); } detachAttributeFromBaseAttributes() { this.attribute === this.baseAttributes && (this._baseAttributes = this.attribute, this.attribute = cloneAttributeSurface(this.attribute)); } commitInternalBaseAttributes(params, context) { params && Object.keys(params).length && (this.canCommitBaseAttributesByTouchedKeys() ? this.commitBaseAttributesByTouchedKeys(params, !1, context) : (this.detachAttributeFromBaseAttributes(), this.applyBaseAttributes(params), this.commitBaseAttributeMutation(!1, context))); } commitBaseAttributesByTouchedKeys(params, forceUpdateTag = !1, context) { const source = params, baseAttributes = this.getBaseAttributesStorage(); let hasKeys = !1, needsShapeAndBounds = forceUpdateTag; for (const key in source) Object.prototype.hasOwnProperty.call(source, key) && (hasKeys = !0, baseAttributes[key] = source[key], !needsShapeAndBounds && this.needUpdateTag(key) && (needsShapeAndBounds = !0)); hasKeys && (this.attribute = baseAttributes, this._baseAttributes = void 0, this.valid = this.isValid(), this.attributeMayContainTransientAttrs = !1, this.submitTouchedUpdate(needsShapeAndBounds), this.onAttributeUpdate(context)); } commitBaseAttributeBySingleKey(key, value, forceUpdateTag = !1, context) { this.getBaseAttributesStorage()[key] = value, this.attribute = this.getBaseAttributesStorage(), this._baseAttributes = void 0, this.valid = this.isValid(), this.attributeMayContainTransientAttrs = !1, this.submitTouchedUpdate(forceUpdateTag || this.needUpdateTag(key)), this.onAttributeUpdate(context); } applyBaseAttributes(params) { const keys = Object.keys(params); for (let i = 0; i < keys.length; i++) { const key = keys[i]; this.getBaseAttributesStorage()[key] = params[key]; } } _commitAnimationStaticAttributes(params, context) { if (!params) return; const source = params, baseAttributes = this.getBaseAttributesStorage(), target = this.attribute, delta = new Map; let hasKeys = !1; for (const key in source) { if (!Object.prototype.hasOwnProperty.call(source, key)) continue; hasKeys = !0; const previousValue = target[key], nextValue = source[key]; baseAttributes[key] = nextValue, target[key] = nextValue, areAttributeValuesEqual(previousValue, nextValue) || delta.set(key, { prev: previousValue, next: nextValue }); } hasKeys && (this.valid = this.isValid(), this.attributeMayContainTransientAttrs = !0, this.submitUpdateByDelta(delta), this.onAttributeUpdate(context)); } applyAnimationTransientAttributes(params, forceUpdateTag = !1, context) { const source = params; let target, needsShapeAndBounds = forceUpdateTag; for (const key in source) Object.prototype.hasOwnProperty.call(source, key) && (target || (this.detachAttributeFromBaseAttributes(), target = this.attribute), target[key] = source[key], !needsShapeAndBounds && this.needUpdateTag(key) && (needsShapeAndBounds = !0)); target && (this.attributeMayContainTransientAttrs = !0, this.valid = this.isValid(), this.submitTouchedUpdate(needsShapeAndBounds), this.onAttributeUpdate(context)); } applyTransientAttributes(params, forceUpdateTag = !1, context) { this.detachAttributeFromBaseAttributes(); const delta = new Map, keys = Object.keys(params); for (let i = 0; i < keys.length; i++) { const key = keys[i], previousValue = this.attribute[key], nextValue = params[key]; areAttributeValuesEqual(previousValue, nextValue) || (delta.set(key, { prev: previousValue, next: nextValue }), this.attribute[key] = nextValue); } delta.size && (this.attributeMayContainTransientAttrs = !0), this.valid = this.isValid(), this.submitUpdateByDelta(delta, forceUpdateTag), this.onAttributeUpdate(context); } _restoreAttributeFromStaticTruth(context, excludedKeys) { this._syncFinalAttributeFromStaticTruth(excludedKeys); const delta = this._syncAttribute(excludedKeys); this.submitUpdateByDelta(delta), this.onAttributeUpdate(context); } collectStatePatchDeltaKeys(previousPatch, nextPatch) { const keys = previousPatch ? Object.keys(previousPatch) : []; if (!nextPatch) return keys; for (const key in nextPatch) Object.prototype.hasOwnProperty.call(nextPatch, key) && !Object.prototype.hasOwnProperty.call(null != previousPatch ? previousPatch : {}, key) && keys.push(key); return keys; } getStaticTruthValueForStateKey(key, nextPatch) { var _a; const baseAttributes = null !== (_a = this.baseAttributes) && void 0 !== _a ? _a : {}, patch = nextPatch; if (patch && Object.prototype.hasOwnProperty.call(patch, key)) { const patchValue = patch[key], baseValue = baseAttributes[key]; return "deep" === this.stateMergeMode && isPlainObjectValue(baseValue) && isPlainObjectValue(patchValue) ? { hasValue: !0, value: deepMergeAttributeValue(baseValue, patchValue) } : { hasValue: !0, value: patchValue }; } return Object.prototype.hasOwnProperty.call(baseAttributes, key) ? { hasValue: !0, value: baseAttributes[key] } : { hasValue: !1, value: void 0 }; } syncStatePatchDeltaToTarget(target, keys, nextPatch, collectCategory = !1) { let category = UpdateCategory.NONE; for (let i = 0; i < keys.length; i++) { const key = keys[i], previousValue = target[key], next = this.getStaticTruthValueForStateKey(key, nextPatch); if (!next.hasValue) { Object.prototype.hasOwnProperty.call(target, key) && (delete target[key], collectCategory && (category = this.mergeAttributeDeltaCategory(category, key, previousValue, void 0))); continue; } if (areAttributeValuesEqual(previousValue, next.value)) continue; const nextValue = cloneAttributeValue(next.value); target[key] = nextValue, collectCategory && (category = this.mergeAttributeDeltaCategory(category, key, previousValue, nextValue)); } return category; } restoreAttributeFromStatePatchDelta(previousPatch, nextPatch, context) { this.detachAttributeFromBaseAttributes(); const keys = this.collectStatePatchDeltaKeys(previousPatch, nextPatch), finalAttribute = this.finalAttribute; finalAttribute && this.syncStatePatchDeltaToTarget(finalAttribute, keys, nextPatch, !1); const category = this.syncStatePatchDeltaToTarget(this.attribute, keys, nextPatch, !0); this.valid = this.isValid(), this.attributeMayContainTransientAttrs = !1, this.submitUpdateByCategory(category), this.onAttributeUpdate(context); } setMode(mode) { "3d" === mode ? this.set3dMode() : this.set2dMode(); } set3dMode() { this.in3dMode = !0; } set2dMode() { this.in3dMode = !1; } getOffsetXY(attr, includeScroll = !1) { var _a, _b; const {dx: dx = attr.dx, dy: dy = attr.dy} = this.attribute; if (includeScroll && this.parent) { const attribute = this.parent.attribute; point.x = dx + (null !== (_a = attribute.scrollX) && void 0 !== _a ? _a : 0), point.y = dy + (null !== (_b = attribute.scrollY) && void 0 !== _b ? _b : 0); } else point.x = dx, point.y = dy; return point; } onAnimateBind(animate) { this.detachAttributeFromBaseAttributes(), this._emitCustomEvent("animate-bind", animate); } visitTrackedAnimates(cb) { const hook = this.forEachTrackedAnimate; "function" != typeof hook ? this.animates && this.animates.forEach(cb) : hook.call(this, cb); } hasAnyTrackedAnimate() { var _a; const hook = this.hasTrackedAnimate; if ("function" == typeof hook) return hook.call(this); const getTrackedAnimates = this.getTrackedAnimates; return "function" == typeof getTrackedAnimates ? getTrackedAnimates.call(this).size > 0 : !!(null === (_a = this.animates) || void 0 === _a ? void 0 : _a.size); } mayHaveTrackedAnimates() { var _a; return !!(null === (_a = this.animates) || void 0 === _a ? void 0 : _a.size) || !!this._animationStateManager; } tryUpdateAABBBounds() { if (!(this.shadowRoot || this._updateTag & UpdateTag.UPDATE_BOUNDS)) return this._AABBBounds; const full = "imprecise" === this.attribute.boundsMode; if (!this.shadowRoot) { const graphicService = this.getGraphicService(), graphicTheme = this.getGraphicTheme(); if (!graphicService.validCheck(this.attribute, graphicTheme, this._AABBBounds, this)) return this._AABBBounds; if (!this.valid) return this._AABBBounds.clear(), this._AABBBounds; graphicService.beforeUpdateAABBBounds(this, this.stage, !0, this._AABBBounds); const bounds = this.doUpdateAABBBounds(full, graphicTheme); return graphicService.afterUpdateAABBBounds(this, this.stage, this._AABBBounds, this, !0), "empty" === this.attribute.boundsMode && bounds.clear(), bounds; } if (!this.shouldUpdateAABBBounds()) return this._AABBBounds; if (!this.valid) return this._AABBBounds.clear(), this._AABBBounds; this.getGraphicService().beforeUpdateAABBBounds(this, this.stage, !0, this._AABBBounds); const bounds = this.doUpdateAABBBounds(full); return this.getGraphicService().afterUpdateAABBBounds(this, this.stage, this._AABBBounds, this, !0), "empty" === this.attribute.boundsMode && bounds.clear(), bounds; } tryUpdateOBBBounds() { if (this._OBBBounds || (this._OBBBounds = new OBBBounds), this.tryUpdateAABBBounds(), this.updateOBBBoundsStamp === this.updateAABBBoundsStamp) return this._OBBBounds; if (this.updateOBBBoundsStamp = this.updateAABBBoundsStamp, !this.valid) return this._OBBBounds.clear(), this._OBBBounds; return this.doUpdateOBBBounds(); } combindShadowAABBBounds(bounds) { if (this.shadowRoot) { const b = this.shadowRoot.AABBBounds.clone(); bounds.union(b); } } doUpdateOBBBounds() { return this._OBBBounds; } getClipPath() { const {clipConfig: clipConfig} = this.attribute; if (!clipConfig) return null; this.clipPathMap || (this.clipPathMap = new Map); const {shape: shape} = clipConfig; let path = this.clipPathMap.get(shape) || null; return path || (this.clipPathMap.size > 10 && this.clipPathMap.clear(), path = this.parsePath(shape), path && this.clipPathMap.set(shape, path)), path; } parsePath(symbolType) { if (!symbolType) return null; let path = builtinSymbolsMap[symbolType]; if (path) return path; if (path = Graphic.userSymbolMap[symbolType], path) return path; const _symbolType = builtInSymbolStrMap[symbolType]; if (!0 === isSvg(symbolType = _symbolType || symbolType)) { const parser = new XMLParser, {svg: svg} = parser.parse(symbolType); if (!svg) return null; const path = isArray(svg.path) ? svg.path : [ svg.path ]; _tempBounds.clear(); const cacheList = []; path.forEach((item => { const cache = (new CustomPath2D).fromString(item.d), attribute = {}; SVG_PARSE_ATTRIBUTE_MAP_KEYS.forEach((k => { item[k] && (attribute[SVG_PARSE_ATTRIBUTE_MAP[k]] = item[k]); })), cacheList.push({ path: cache, attribute: attribute }), _tempBounds.union(cache.bounds); })); const width = _tempBounds.width(), height = _tempBounds.height(), scale = 1 / max(width, height); cacheList.forEach((cache => cache.path.transform(0, 0, scale, scale))); const _parsedPath = new CustomSymbolClass(symbolType, cacheList, !0); return Graphic.userSymbolMap[symbolType] = _parsedPath, _parsedPath; } const cache = (new CustomPath2D).fromString(symbolType), width = cache.bounds.width(), height = cache.bounds.height(), scale = 1 / max(width, height); cache.transform(0, 0, scale, scale); const _parsedPath = new CustomSymbolClass(symbolType, cache); return Graphic.userSymbolMap[symbolType] = _parsedPath, _parsedPath; } doUpdateAABBBounds(full, graphicTheme) { this.updateAABBBoundsStamp++; const resolvedGraphicTheme = null != graphicTheme ? graphicTheme : this.getGraphicTheme(); this._AABBBounds.clear(); const attribute = this.attribute, bounds = this.updateAABBBounds(attribute, resolvedGraphicTheme, this._AABBBounds, full), {boundsPadding: boundsPadding = resolvedGraphicTheme.boundsPadding} = attribute, paddingArray = parsePadding(boundsPadding); return paddingArray && bounds.expand(paddingArray), this.clearUpdateBoundTag(), bounds; } updatePathProxyAABBBounds(aabbBounds) { const path = "function" == typeof this.pathProxy ? this.pathProxy(this.attribute) : this.pathProxy; if (!path) return !1; const boundsContext = new BoundsContext(aabbBounds); return renderCommandList(path.commandList, boundsContext, 0, 0), !0; } tryUpdateGlobalAABBBounds() { const b = this.AABBBounds; return this._globalAABBBounds ? this._globalAABBBounds.setValue(b.x1, b.y1, b.x2, b.y2) : this._globalAABBBounds = b.clone(), this._globalAABBBounds.empty() || this.parent && this._globalAABBBounds.transformWithMatrix(this.parent.globalTransMatrix), this._globalAABBBounds; } tryUpdateGlobalTransMatrix(clearTag = !0) { if (this._globalTransMatrix) { if (this.parent) { const m = this.parent.globalTransMatrix; this._globalTransMatrix.setValue(m.a, m.b, m.c, m.d, m.e, m.f); } } else this._globalTransMatrix = this.parent ? this.parent.globalTransMatrix.clone() : this.transMatrix.clone(); return this.shouldUpdateGlobalMatrix() && this.doUpdateGlobalMatrix(), this._globalTransMatrix; } shouldUpdateGlobalMatrix() { return !0; } tryUpdateLocalTransMatrix(clearTag = !0) { return this._transMatrix || (this._transMatrix = new Matrix), this.shouldUpdateLocalMatrix() && (this.doUpdateLocalMatrix(), clearTag && this.clearUpdateLocalPositionTag()), this._transMatrix; } shouldUpdateAABBBounds() { return this.shadowRoot ? (!!(this._updateTag & UpdateTag.UPDATE_BOUNDS) || this.shadowRoot.shouldUpdateAABBBounds()) && this.getGraphicService().validCheck(this.attribute, this.getGraphicTheme(), this._AABBBounds, this) : !!(this._updateTag & UpdateTag.UPDATE_BOUNDS) && this.getGraphicService().validCheck(this.attribute, this.getGraphicTheme(), this._AABBBounds, this); } shouldSelfChangeUpdateAABBBounds() { return this.shadowRoot ? !!(this._updateTag & UpdateTag.UPDATE_BOUNDS) || this.shadowRoot.shouldUpdateAABBBounds() : !!(this._updateTag & UpdateTag.UPDATE_BOUNDS); } shouldUpdateLocalMatrix() { return !!(this._updateTag & UpdateTag.UPDATE_LOCAL_MATRIX); } isValid() { var _a, _b; const attribute = this.attribute; return Number.isFinite((null !== (_a = attribute.x) && void 0 !== _a ? _a : 0) + (null !== (_b = attribute.y) && void 0 !== _b ? _b : 0)); } _validNumber(num) { return null == num || Number.isFinite(num); } shouldUpdateShape() { return !!(this._updateTag & UpdateTag.UPDATE_SHAPE); } clearUpdateShapeTag() { this._updateTag &= UpdateTag.CLEAR_SHAPE; } containsPoint(x, y, mode, picker) { if (!picker) return !1; if (mode === IContainPointMode.GLOBAL) { const point = new Point(x, y); this.parent && this.parent.globalTransMatrix.transformPoint(point, point), x = point.x, y = point.y; } return picker.containsPoint(this, { x: x, y: y }); } setWidthHeightWithoutTransform(aabbBounds) { this.widthWithoutTransform = aabbBounds.x2 - aabbBounds.x1, this.heightWithoutTransform = aabbBounds.y2 - aabbBounds.y1; } setAttributesAndPreventAnimate(params, forceUpdateTag = !1, context, ignorePriority) { if (!params) return; const keys = Object.keys(params); this.captureTransientFromAttrsBeforePreventAnimate(params, keys, context), this.syncFinalAttributesFromUpdateContext(context), this.visitTrackedAnimates((animate => { (animate.priority !== 1 / 0 || ignorePriority) && animate.preventAttrs(keys); })), this.applyTransientAttributes(params, forceUpdateTag, context); } syncFinalAttributesFromUpdateContext(context) { var _a; const updateType = null == context ? void 0 : context.type; if (updateType === AttributeUpdateType.STATE || null != updateType && updateType >= AttributeUpdateType.ANIMATE_BIND && updateType <= AttributeUpdateType.ANIMATE_END) return; const finalAttrs = null === (_a = this.context) || void 0 === _a ? void 0 : _a.finalAttrs, setFinalAttributes = this.setFinalAttributes; finalAttrs && "function" == typeof setFinalAttributes && setFinalAttributes.call(this, finalAttrs); } captureTransientFromAttrsBeforePreventAnimate(params, keys, context) { var _a, _b; const graphicContext = this.context, diffAttrs = null !== (_a = null == graphicContext ? void 0 : graphicContext.diffAttrs) && void 0 !== _a ? _a : params, updateType = null == context ? void 0 : context.type; if (!keys.length || !diffAttrs || updateType === AttributeUpdateType.STATE || null != updateType && updateType >= AttributeUpdateType.ANIMATE_BIND && updateType <= AttributeUpdateType.ANIMATE_END) return; const sameDiffAttrs = this.transientFromAttrsBeforePreventAnimateDiffAttrs === diffAttrs; let fromAttrs = sameDiffAttrs && null !== (_b = this.transientFromAttrsBeforePreventAnimate) && void 0 !== _b ? _b : null; sameDiffAttrs || (this.transientFromAttrsBeforePreventAnimate = null, this.transientFromAttrsBeforePreventAnimateDiffAttrs = null); let captured = !1; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (!Object.prototype.hasOwnProperty.call(diffAttrs, key)) continue; const previousValue = this.attribute[key], nextValue = params[key]; isEqual(previousValue, nextValue) || (null != fromAttrs || (fromAttrs = {}), fromAttrs[key] = cloneAttributeValue(previousValue), captured = !0); } captured && (this.transientFromAttrsBeforePreventAnimate = fromAttrs, this.transientFromAttrsBeforePreventAnimateDiffAttrs = diffAttrs); } consumeTransientFromAttrsBeforePreventAnimate(diffAttrs) { const transientFromAttrs = this.transientFromAttrsBeforePreventAnimate, sourceDiffAttrs = this.transientFromAttrsBeforePreventAnimateDiffAttrs; if (!transientFromAttrs || !sourceDiffAttrs) return null; for (const key in diffAttrs) if (Object.prototype.hasOwnProperty.call(diffAttrs, key) && (!Object.prototype.hasOwnProperty.call(sourceDiffAttrs, key) || !isEqual(sourceDiffAttrs[key], diffAttrs[key]))) return null; let fromAttrs = null, remaining = !1; for (const key in transientFromAttrs) Object.prototype.hasOwnProperty.call(transientFromAttrs, key) && (Object.prototype.hasOwnProperty.call(diffAttrs, key) ? (null != fromAttrs || (fromAttrs = {}), fromAttrs[key] = transientFromAttrs[key]) : remaining = !0); if (remaining) { const nextTransientFromAttrs = {}; for (const key in transientFromAttrs) Object.prototype.hasOwnProperty.call(transientFromAttrs, key) && !Object.prototype.hasOwnProperty.call(diffAttrs, key) && (nextTransientFromAttrs[key] = transientFromAttrs[key]); this.transientFromAttrsBeforePreventAnimate = nextTransientFromAttrs; } else this.transientFromAttrsBeforePreventAnimate = null, this.transientFromAttrsBeforePreventAnimateDiffAttrs = null; return fromAttrs; } setAttributes(params, forceUpdateTag = !1, context) { params && ((params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate(params, this.attribute, null, context) || params).background && this.loadImage(params.background, !0), params.texture && isExternalTexture(params.texture) && this.loadImage(params.texture, !1), params.shadowGraphic && this.setShadowGraphic(params.shadowGraphic), this._setAttributes(params, forceUpdateTag, context)); } _setAttributes(params, forceUpdateTag = !1, context) { this.canCommitBaseAttributesByTouchedKeys() ? this.commitBaseAttributesByTouchedKeys(params, forceUpdateTag, context) : (this.detachAttributeFromBaseAttributes(), this.applyBaseAttributes(params), this.commitBaseAttributeMutation(forceUpdateTag, context)); } setAttribute(key, value, forceUpdateTag, context) { const params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ [key]: value }, this.attribute, key, context); if (params) this._setAttributes(params, forceUpdateTag, context); else if (this.canCommitBaseAttributesByTouchedKeys()) this.commitBaseAttributeBySingleKey(key, value, !!forceUpdateTag, context); else { const nextAttrs = { [key]: value }; this.applyBaseAttributes(nextAttrs), this.commitBaseAttributeMutation(!!forceUpdateTag, context); } "background" === key ? this.loadImage(value, !0) : "texture" === key && isExternalTexture(value) ? this.loadImage(value, !1) : "shadowGraphic" === key && this.setShadowGraphic(value); } needUpdateTags(keys, k = GRAPHIC_UPDATE_TAG_KEY) { for (let i = 0; i < k.length; i++) { const attrKey = k[i]; if (-1 !== keys.indexOf(attrKey)) return !0; } return !1; } needUpdateTag(key, k = GRAPHIC_UPDATE_TAG_KEY) { for (let i = 0; i < k.length; i++) { if (key === k[i]) return !0; } return !1; } initAttributes(params) { const context = { type: AttributeUpdateType.INIT }; params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate(params, this.attribute, null, context) || params, this.attribute = params, this._baseAttributes = void 0, this.resolvedStatePatch = void 0, this.attributeMayContainTransientAttrs = !1, this.valid = this.isValid(), params.background && this.loadImage(params.background, !0), params.texture && isExternalTexture(params.texture) && this.loadImage(params.texture, !1), params.shadowGraphic && this.setShadowGraphic(params.shadowGraphic), this._updateTag = UpdateTag.INIT, this.valid = this.isValid(), this.onAttributeUpdate(context); } translate(x, y) { var _a, _b; if (0 === x && 0 === y) return this; const context = { type: AttributeUpdateType.TRANSLATE }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ x: x, y: y }, this.attribute, tempConstantXYKey, context); params && (x = params.x, y = params.y, delete params.x, delete params.y); const attribute = this.baseAttributes, postMatrix = attribute.postMatrix, nextAttrs = params || {}; if (postMatrix) { const nextPostMatrix = postMatrix.clone(); application.transformUtil.fromMatrix(nextPostMatrix, nextPostMatrix).translate(x, y), nextAttrs.postMatrix = nextPostMatrix; } else nextAttrs.x = (null !== (_a = attribute.x) && void 0 !== _a ? _a : DefaultTransform.x) + x, nextAttrs.y = (null !== (_b = attribute.y) && void 0 !== _b ? _b : DefaultTransform.y) + y; return this.commitInternalBaseAttributes(nextAttrs, context), this; } translateTo(x, y) { const attribute = this.baseAttributes; if (attribute.x === x && attribute.y === y) return this; const context = { type: AttributeUpdateType.TRANSLATE_TO }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ x: x, y: y }, this.attribute, tempConstantXYKey, context); return params ? (this.commitInternalBaseAttributes(params, context), this) : (this.commitInternalBaseAttributes({ x: x, y: y }, context), this); } scale(scaleX, scaleY, scaleCenter) { var _a, _b; if (1 === scaleX && 1 === scaleY) return this; const context = { type: AttributeUpdateType.SCALE }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ scaleX: scaleX, scaleY: scaleY, scaleCenter: scaleCenter }, this.attribute, tempConstantScaleXYKey, context); params && (scaleX = params.scaleX, scaleY = params.scaleY, delete params.scaleX, delete params.scaleY); const attribute = this.baseAttributes, nextAttrs = params || {}; if (scaleCenter) { let {postMatrix: postMatrix} = this.baseAttributes; postMatrix = postMatrix ? postMatrix.clone() : new Matrix, application.transformUtil.fromMatrix(postMatrix, postMatrix).scale(scaleX, scaleY, scaleCenter), nextAttrs.postMatrix = postMatrix; } else nextAttrs.scaleX = (null !== (_a = attribute.scaleX) && void 0 !== _a ? _a : DefaultTransform.scaleX) * scaleX, nextAttrs.scaleY = (null !== (_b = attribute.scaleY) && void 0 !== _b ? _b : DefaultTransform.scaleY) * scaleY; return this.commitInternalBaseAttributes(nextAttrs, context), this; } scaleTo(scaleX, scaleY) { const attribute = this.baseAttributes; if (attribute.scaleX === scaleX && attribute.scaleY === scaleY) return this; const context = { type: AttributeUpdateType.SCALE_TO }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ scaleX: scaleX, scaleY: scaleY }, this.attribute, tempConstantScaleXYKey, context); return params ? (this.commitInternalBaseAttributes(params, context), this) : (this.commitInternalBaseAttributes({ scaleX: scaleX, scaleY: scaleY }, context), this); } rotate(angle, rotateCenter) { var _a; if (0 === angle) return this; const context = { type: AttributeUpdateType.ROTATE }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate({ angle: angle, rotateCenter: rotateCenter }, this.attribute, tempConstantAngleKey, context); params && delete params.angle; const attribute = this.baseAttributes, nextAttrs = params || {}; if (rotateCenter) { let {postMatrix: postMatrix} = this.baseAttributes; postMatrix = postMatrix ? postMatrix.clone() : new Matrix, application.transformUtil.fromMatrix(postMatrix, postMatrix).rotate(angle, rotateCenter), nextAttrs.postMatrix = postMatrix; } else nextAttrs.angle = (null !== (_a = attribute.angle) && void 0 !== _a ? _a : DefaultTransform.angle) + angle; return this.commitInternalBaseAttributes(nextAttrs, context), this; } rotateTo(angle) { if (this.baseAttributes.angle === angle) return this; const context = { type: AttributeUpdateType.ROTATE_TO }, params = this.onBeforeAttributeUpdate && this.onBeforeAttributeUpdate(angle, this.attribute, tempConstantAngleKey, context); return params ? (this.commitInternalBaseAttributes(params, context), this) : (this.commitInternalBaseAttributes({ angle: angle }, context), this); } skewTo(b, c) { return this; } onAttributeUpdate(context) { context && context.skipUpdateCallback || (this.getGraphicService().onAttributeUpdate(this), this._emitCustomEvent("afterAttributeUpdate", context)); } update(d) { d ? (d.bounds && this.tryUpdateAABBBounds(), d.trans && this.tryUpdateLocalTransMatrix()) : (this.tryUpdateAABBBounds(), this.tryUpdateLocalTransMatrix()); } hasState(stateName) { return !(!this.currentStates || !this.currentStates.length) && (!!isNil(stateName) || this.currentStates.includes(stateName)); } getState(stateName) { var _a; return null === (_a = this.states) || void 0 === _a ? void 0 : _a[stateName]; } getStateResolveBaseAttrs() { var _a; return null !== (_a = this.baseAttributes) && void 0 !== _a ? _a : this.attribute; } syncStateResolveContext(stateResolveBaseAttrs = this.getStateResolveBaseAttrs()) { var _a; return null === (_a = this.stateEngine) || void 0 === _a || _a.setResolveContext(this, stateResolveBaseAttrs), stateResolveBaseAttrs; } ensureStateEngine(stateResolveBaseAttrs = this.getStateResolveBaseAttrs()) { const {compiledDefinitions: compiledDefinitions} = this.resolveEffectiveCompiledDefinitions(); return this.compiledStateDefinitions = compiledDefinitions, compiledDefinitions ? this.stateEngine && this.stateEngineCompiledDefinitions === compiledDefinitions && this.stateEngineStateSort === this.stateSort && this.stateEngineMergeMode === this.stateMergeMode || (this.stateEngine = new StateEngine({ compiledDefinitions: compiledDefinitions, stateSort: this.stateSort, mergeMode: this.stateMergeMode }), this.stateEngineCompiledDefinitions = compiledDefinitions, this.stateEngineStateSort = this.stateSort, this.stateEngineMergeMode = this.stateMergeMode) : (this.stateEngine = void 0, this.stateEngineCompiledDefinitions = void 0), this.syncStateResolveContext(stateResolveBaseAttrs), this.stateEngine && this.currentStates && !this.sameStateNames(this.stateEngine.activeStates, this.currentStates) && this.stateEngine.applyStates(this.currentStates), this.stateEngine; } toGraphicStateTransition(result) { return { changed: result.changed, states: [ ...result.activeStates ], effectiveStates: [ ...result.effectiveStates ] }; } sortLocalStates(states) { return this.stateSort ? [ ...states ].sort(this.stateSo