{"version":3,"file":"KeyframesResolver.mjs","sources":["../../../../src/animation/keyframes/KeyframesResolver.ts"],"sourcesContent":["import { isNumericalString, isZeroValueString } from \"motion-utils\"\nimport { frame } from \"../../frameloop\"\nimport { MotionValue } from \"../../value\"\nimport { complex } from \"../../value/types/complex\"\nimport { getAnimatableNone } from \"../../value/types/utils/animatable-none\"\nimport { AnyResolvedKeyframe } from \"../types\"\nimport { WithRender } from \"./types\"\nimport { fillWildcards } from \"./utils/fill-wildcards\"\nimport {\n boxDependentValues,\n removeNonTranslationalTransform,\n} from \"./utils/unit-conversion\"\n\nexport type UnresolvedKeyframes = Array\n\nexport type ResolvedKeyframes = Array\n\nconst toResolve = new Set()\nlet isScheduled = false\nlet anyNeedsMeasurement = false\nlet isForced = false\n\nfunction measureAllKeyframes() {\n if (anyNeedsMeasurement) {\n const resolversToMeasure: KeyframeResolver[] = []\n const elementsToMeasure = new Set()\n const elementsToUntransform = new Set()\n\n toResolve.forEach((resolver) => {\n if (!resolver.needsMeasurement) return\n\n resolversToMeasure.push(resolver)\n elementsToMeasure.add(resolver.element!)\n\n if (boxDependentValues.has(resolver.name!)) {\n elementsToUntransform.add(resolver.element!)\n }\n })\n\n const transformsToRestore = new Map<\n WithRender,\n [string, AnyResolvedKeyframe][]\n >()\n\n /**\n * Write pass\n * Values measured from the bounding box need bounding box-changing\n * transforms removed first. Values read from computed style don't.\n */\n elementsToUntransform.forEach((element: WithRender) => {\n const removedTransforms = removeNonTranslationalTransform(\n element as any\n )\n\n if (!removedTransforms.length) return\n\n transformsToRestore.set(element, removedTransforms)\n\n element.render()\n })\n\n // Read\n resolversToMeasure.forEach((resolver) => resolver.measureInitialState())\n\n // Write\n elementsToMeasure.forEach((element: WithRender) => {\n element.render()\n\n const restore = transformsToRestore.get(element)\n if (restore) {\n restore.forEach(([key, value]) => {\n element.getValue(key)?.set(value)\n })\n }\n })\n\n // Read\n resolversToMeasure.forEach((resolver) => resolver.measureEndState())\n\n // Write\n resolversToMeasure.forEach((resolver) => {\n if (resolver.suspendedScrollY !== undefined) {\n window.scrollTo(0, resolver.suspendedScrollY)\n }\n })\n }\n\n anyNeedsMeasurement = false\n isScheduled = false\n\n toResolve.forEach((resolver) => resolver.complete(isForced))\n toResolve.clear()\n}\n\nfunction readAllKeyframes() {\n toResolve.forEach((resolver) => {\n resolver.readKeyframes()\n\n if (resolver.needsMeasurement) {\n anyNeedsMeasurement = true\n }\n })\n}\n\nexport function flushKeyframeResolvers() {\n isForced = true\n readAllKeyframes()\n measureAllKeyframes()\n isForced = false\n}\n\n/**\n * Normalise a value read from the subject into an animation origin: a\n * number read as a string (\"0\", \"200\") becomes a number, and a value\n * that isn't animatable (e.g. \"none\") but whose target is becomes an\n * animatable zero in the shape of the target.\n */\nfunction readOrigin(\n value: AnyResolvedKeyframe | null | undefined,\n name: string,\n target: AnyResolvedKeyframe | null\n) {\n if (typeof value === \"string\") {\n if (isNumericalString(value) || isZeroValueString(value)) {\n return parseFloat(value)\n } else if (!complex.test(value) && complex.test(target)) {\n return getAnimatableNone(name, target as string)\n }\n }\n\n return value ?? undefined\n}\n\nexport type OnKeyframesResolved = (\n resolvedKeyframes: ResolvedKeyframes,\n finalKeyframe: T,\n forced: boolean\n) => void\n\nexport class KeyframeResolver {\n name?: string\n element?: WithRender\n finalKeyframe?: T\n suspendedScrollY?: number\n\n protected unresolvedKeyframes: UnresolvedKeyframes\n\n protected motionValue?: MotionValue\n private onComplete: OnKeyframesResolved\n\n state: \"pending\" | \"scheduled\" | \"complete\" = \"pending\"\n\n /**\n * Track whether this resolver is async. If it is, it'll be added to the\n * resolver queue and flushed in the next frame. Resolvers that aren't going\n * to trigger read/write thrashing don't need to be async.\n */\n private isAsync = false\n\n /**\n * Track whether this resolver needs to perform a measurement\n * to resolve its keyframes.\n */\n needsMeasurement = false\n\n constructor(\n unresolvedKeyframes: UnresolvedKeyframes,\n onComplete: OnKeyframesResolved,\n name?: string,\n motionValue?: MotionValue,\n element?: WithRender,\n isAsync = false\n ) {\n this.unresolvedKeyframes = [...unresolvedKeyframes]\n this.onComplete = onComplete\n this.name = name\n this.motionValue = motionValue\n this.element = element\n this.isAsync = isAsync\n }\n\n scheduleResolve() {\n this.state = \"scheduled\"\n\n if (this.isAsync) {\n toResolve.add(this)\n\n if (!isScheduled) {\n isScheduled = true\n frame.read(readAllKeyframes)\n frame.resolveKeyframes(measureAllKeyframes)\n }\n } else {\n this.readKeyframes()\n this.complete()\n }\n }\n\n readKeyframes() {\n const { unresolvedKeyframes, name, element, motionValue } = this\n\n // If initial keyframe is null we need to read it from the DOM\n if (unresolvedKeyframes[0] === null) {\n const currentValue = motionValue?.get()\n\n // TODO: This doesn't work if the final keyframe is a wildcard\n const finalKeyframe =\n unresolvedKeyframes[unresolvedKeyframes.length - 1]\n\n if (currentValue !== undefined) {\n unresolvedKeyframes[0] = currentValue\n } else if (element && name) {\n const valueAsRead = readOrigin(\n element.readValue(name, finalKeyframe),\n name,\n finalKeyframe\n )\n\n if (valueAsRead !== undefined) {\n unresolvedKeyframes[0] = valueAsRead\n }\n }\n\n if (unresolvedKeyframes[0] === undefined) {\n unresolvedKeyframes[0] = finalKeyframe\n }\n\n if (motionValue && currentValue === undefined) {\n motionValue.set(unresolvedKeyframes[0] as T)\n }\n }\n\n fillWildcards(unresolvedKeyframes)\n }\n\n setFinalKeyframe() {}\n measureInitialState() {}\n renderEndStyles() {}\n measureEndState() {}\n\n complete(isForcedComplete = false) {\n this.state = \"complete\"\n\n this.onComplete(\n this.unresolvedKeyframes as ResolvedKeyframes,\n this.finalKeyframe as T,\n isForcedComplete\n )\n\n toResolve.delete(this)\n }\n\n cancel() {\n if (this.state === \"scheduled\") {\n toResolve.delete(this)\n this.state = \"pending\"\n }\n }\n\n resume() {\n if (this.state === \"pending\") this.scheduleResolve()\n }\n}\n"],"names":[],"mappings":"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"}