@lytjs/common-transition-engine 6.5.0 → 6.7.0
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/dist/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +566 -566
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// @lytjs/common-transition-engine\r\n// 过渡引擎:平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行\r\n\r\ndeclare const __DEV__: boolean;\r\n\r\nimport type {\r\n RendererHost,\r\n TransitionDurationInfo,\r\n HostEvent,\r\n HostEventHandler,\r\n} from '@lytjs/host-contract';\r\nimport type { HostRect } from '@lytjs/host-contract';\r\n\r\n// ============================================================\r\n// 类型定义\r\n// ============================================================\r\n\r\nexport interface TransitionProps<T = unknown> {\r\n name?: string;\r\n appear?: boolean;\r\n enterFromClass?: string;\r\n enterActiveClass?: string;\r\n enterToClass?: string;\r\n leaveFromClass?: string;\r\n leaveActiveClass?: string;\r\n leaveToClass?: string;\r\n onBeforeEnter?: (el: T) => void;\r\n onEnter?: (el: T, done: () => void) => void;\r\n onAfterEnter?: (el: T) => void;\r\n onEnterCancelled?: (el: T) => void;\r\n onBeforeLeave?: (el: T) => void;\r\n onLeave?: (el: T, done: () => void) => void;\r\n onAfterLeave?: (el: T) => void;\r\n onLeaveCancelled?: (el: T) => void;\r\n}\r\n\r\n/**\r\n * 过渡状态(运行时收敛层)。\r\n * 与 @lytjs/vdom/transition 中的 TransitionState 不同,\r\n * 此版本用于运行时收敛层的过渡控制。\r\n */\r\nexport interface RuntimeTransitionState {\r\n /** 当前过渡阶段 */\r\n phase: 'idle' | 'entering' | 'leaving';\r\n /** 是否已取消 */\r\n cancelled: boolean;\r\n /** 过渡完成回调 */\r\n doneCallback: (() => void) | null;\r\n /** FIX: P0-10 存储过渡属性引用,用于 cancelTransition 时调用取消钩子 */\r\n // FIX: DTS build error - 使用 unknown 避免类型不兼容\r\n props?: unknown;\r\n}\r\n\r\n/**\r\n * FLIP 动画的四个阶段记录。\r\n */\r\nexport interface FLIPRecord<HE> {\r\n /** 目标元素 */\r\n el: HE;\r\n /** First: 初始位置 */\r\n first: HostRect;\r\n /** Last: 最终位置 */\r\n last: HostRect;\r\n /** Invert: 偏移量 */\r\n invert: { x: number; y: number };\r\n /** Play: 播放回调 */\r\n play: (() => void) | null;\r\n}\r\n\r\n/**\r\n * 过渡类名解析结果。\r\n */\r\nexport interface ResolvedTransitionClasses {\r\n /** 起始类名 */\r\n from: string;\r\n /** 激活类名 */\r\n active: string;\r\n /** 结束类名 */\r\n to: string;\r\n}\r\n\r\n/**\r\n * 过渡引擎配置项。\r\n */\r\nexport interface TransitionEngineOptions {\r\n /** 默认过渡名称(默认 'v') */\r\n defaultName?: string;\r\n /** 过渡超时时间(ms,默认 5000) */\r\n timeout?: number;\r\n /** 是否启用 FLIP 动画(默认 true) */\r\n enableFLIP?: boolean;\r\n}\r\n\r\n// ============================================================\r\n// 常量\r\n// ============================================================\r\n\r\n/** 默认配置 */\r\nconst DEFAULT_OPTIONS: Required<TransitionEngineOptions> = {\r\n defaultName: 'v',\r\n timeout: 5000,\r\n enableFLIP: true,\r\n};\r\n\r\n/** 过渡清理函数映射 */\r\nconst transitionCleanupMap = new WeakMap<object, (() => void) | null>();\r\n\r\n// ============================================================\r\n// TransitionEngine\r\n// ============================================================\r\n\r\n/**\r\n * 过渡引擎。\r\n *\r\n * 平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行。\r\n * 包含 enter/leave 过渡逻辑和 FLIP 动画逻辑。\r\n *\r\n * @template HN - 宿主节点类型\r\n * @template HE - 宿主元素类型\r\n */\r\nexport class TransitionEngine<HN extends object = object, HE extends HN = HN> {\r\n /** RendererHost 实例 */\r\n private host: RendererHost<HN, HE>;\r\n\r\n /** 配置项 */\r\n private options: Required<TransitionEngineOptions>;\r\n\r\n /** 活跃的过渡状态映射(el → state) */\r\n private stateMap = new WeakMap<HE, RuntimeTransitionState>();\r\n\r\n /**\r\n * 创建过渡引擎实例。\r\n * @param host - RendererHost 实例\r\n * @param options - 可选的配置项\r\n */\r\n constructor(host: RendererHost<HN, HE>, options?: TransitionEngineOptions) {\r\n this.host = host;\r\n this.options = { ...DEFAULT_OPTIONS, ...options };\r\n }\r\n\r\n // ==========================================================\r\n // 过渡状态管理\r\n // ==========================================================\r\n\r\n /**\r\n * 获取元素的过渡状态。\r\n * @param el - 宿主元素\r\n * @returns 过渡状态\r\n */\r\n getState(el: HE): RuntimeTransitionState {\r\n let state = this.stateMap.get(el);\r\n if (!state) {\r\n state = {\r\n phase: 'idle',\r\n cancelled: false,\r\n doneCallback: null,\r\n };\r\n this.stateMap.set(el, state);\r\n }\r\n return state;\r\n }\r\n\r\n /**\r\n * 检查元素是否正在进行过渡。\r\n * @param el - 宿主元素\r\n */\r\n isTransitioning(el: HE): boolean {\r\n const state = this.stateMap.get(el);\r\n return state !== undefined && state.phase !== 'idle';\r\n }\r\n\r\n // ==========================================================\r\n // Enter 过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 执行进入过渡。\r\n *\r\n * @param el - 宿主元素\r\n * @param props - 过渡属性\r\n * @param done - 过渡完成回调\r\n */\r\n performEnter(el: HE, props: TransitionProps<HE>, done: () => void): void {\r\n // 取消可能存在的旧过渡\r\n this.cancelTransition(el);\r\n\r\n const state = this.getState(el);\r\n state.phase = 'entering';\r\n state.cancelled = false;\r\n state.doneCallback = done;\r\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\r\n state.props = props;\r\n\r\n const classes = this.resolveTransitionClasses(props, 'enter');\r\n\r\n // 调用 onBeforeEnter 钩子\r\n if (props.onBeforeEnter) {\r\n props.onBeforeEnter(el);\r\n }\r\n\r\n // 添加 enter-from 和 enter-active 类\r\n this.host.addClass(el, classes.from);\r\n this.host.addClass(el, classes.active);\r\n\r\n // 强制回流,确保浏览器记录初始状态\r\n this.host.forceReflow(el);\r\n\r\n // 移除 enter-from,添加 enter-to\r\n this.host.removeClass(el, classes.from);\r\n this.host.addClass(el, classes.to);\r\n\r\n // 检查是否有 JS enter 钩子\r\n if (props.onEnter) {\r\n props.onEnter(el, () => {\r\n this.finishEnter(el, classes, props);\r\n });\r\n } else {\r\n // CSS 过渡:等待 transitionend/animationend\r\n const info = this.host.getTransitionInfo(el, 'enter');\r\n if (info.hasTransition || info.hasAnimation) {\r\n if (info.duration > 0) {\r\n this.host.setTimeout(() => this.finishEnter(el, classes, props), info.duration + 50);\r\n } else {\r\n this.waitForTransitionEnd(el, info, () => this.finishEnter(el, classes, props));\r\n }\r\n } else {\r\n // 无 CSS 过渡,立即完成\r\n this.finishEnter(el, classes, props);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 完成进入过渡。\r\n */\r\n private finishEnter(\r\n el: HE,\r\n classes: ResolvedTransitionClasses,\r\n props: TransitionProps<HE>,\r\n ): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.cancelled) return;\r\n\r\n this.host.removeClass(el, classes.active);\r\n this.host.removeClass(el, classes.to);\r\n\r\n if (props.onAfterEnter) {\r\n props.onAfterEnter(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n\r\n // 清理\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n // ==========================================================\r\n // Leave 过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 执行离开过渡。\r\n *\r\n * @param el - 宿主元素\r\n * @param props - 过渡属性\r\n * @param done - 过渡完成回调\r\n */\r\n performLeave(el: HE, props: TransitionProps<HE>, done: () => void): void {\r\n // 取消可能存在的旧过渡\r\n this.cancelTransition(el);\r\n\r\n const state = this.getState(el);\r\n state.phase = 'leaving';\r\n state.cancelled = false;\r\n state.doneCallback = done;\r\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\r\n state.props = props;\r\n\r\n const classes = this.resolveTransitionClasses(props, 'leave');\r\n\r\n // 调用 onBeforeLeave 钩子\r\n if (props.onBeforeLeave) {\r\n props.onBeforeLeave(el);\r\n }\r\n\r\n // 添加 leave-from 和 leave-active 类\r\n this.host.addClass(el, classes.from);\r\n this.host.addClass(el, classes.active);\r\n\r\n // 强制回流\r\n this.host.forceReflow(el);\r\n\r\n // 移除 leave-from,添加 leave-to\r\n this.host.removeClass(el, classes.from);\r\n this.host.addClass(el, classes.to);\r\n\r\n // 检查是否有 JS leave 钩子\r\n if (props.onLeave) {\r\n props.onLeave(el, () => {\r\n this.finishLeave(el, classes, props);\r\n });\r\n } else {\r\n // CSS 过渡\r\n const info = this.host.getTransitionInfo(el, 'leave');\r\n if (info.hasTransition || info.hasAnimation) {\r\n if (info.duration > 0) {\r\n this.host.setTimeout(() => this.finishLeave(el, classes, props), info.duration + 50);\r\n } else {\r\n this.waitForTransitionEnd(el, info, () => this.finishLeave(el, classes, props));\r\n }\r\n } else {\r\n this.finishLeave(el, classes, props);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 完成离开过渡。\r\n */\r\n private finishLeave(\r\n el: HE,\r\n classes: ResolvedTransitionClasses,\r\n props: TransitionProps<HE>,\r\n ): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.cancelled) return;\r\n\r\n this.host.removeClass(el, classes.active);\r\n this.host.removeClass(el, classes.to);\r\n\r\n if (props.onAfterLeave) {\r\n props.onAfterLeave(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n // ==========================================================\r\n // 取消过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 取消元素上正在进行的过渡。\r\n *\r\n * @param el - 宿主元素\r\n */\r\n cancelTransition(el: HE): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.phase === 'idle') return;\r\n\r\n state.cancelled = true;\r\n\r\n // FIX: P0-10 根据 phase 调用对应的取消钩子(onEnterCancelled / onLeaveCancelled)\r\n // FIX: DTS build error - 使用类型断言访问 props\r\n const props = state.props as\r\n | { onEnterCancelled?: (el: HE) => void; onLeaveCancelled?: (el: HE) => void }\r\n | undefined;\r\n if (props) {\r\n if (state.phase === 'entering' && props.onEnterCancelled) {\r\n props.onEnterCancelled(el);\r\n } else if (state.phase === 'leaving' && props.onLeaveCancelled) {\r\n props.onLeaveCancelled(el);\r\n }\r\n }\r\n\r\n // 执行清理函数\r\n const cleanup = transitionCleanupMap.get(el);\r\n if (cleanup) {\r\n cleanup();\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n state.props = undefined;\r\n }\r\n\r\n // ==========================================================\r\n // FLIP 动画\r\n // ==========================================================\r\n\r\n /**\r\n * 记录 FLIP 动画的 First 状态。\r\n *\r\n * @param el - 宿主元素\r\n * @returns FLIP 记录(含 First 阶段数据)\r\n */\r\n flipRecordFirst(el: HE): FLIPRecord<HE> {\r\n const first = this.host.getBoundingClientRect(el);\r\n return {\r\n el,\r\n first,\r\n last: { left: 0, top: 0, width: 0, height: 0, right: 0, bottom: 0 },\r\n invert: { x: 0, y: 0 },\r\n play: null,\r\n };\r\n }\r\n\r\n /**\r\n * 记录 FLIP 动画的 Last 状态并计算 Invert。\r\n *\r\n * @param record - FLIP 记录(含 First 阶段数据)\r\n * @returns 更新后的 FLIP 记录(含 Last 和 Invert 数据)\r\n */\r\n flipRecordLast(record: FLIPRecord<HE>): FLIPRecord<HE> {\r\n const last = this.host.getBoundingClientRect(record.el);\r\n const invertX = record.first.left - last.left;\r\n const invertY = record.first.top - last.top;\r\n\r\n return {\r\n ...record,\r\n last,\r\n invert: { x: invertX, y: invertY },\r\n };\r\n }\r\n\r\n /**\r\n * 执行 FLIP 动画的 Play 阶段。\r\n *\r\n * @param record - FLIP 记录(含 First、Last、Invert 数据)\r\n * @param duration - 动画时长(ms,默认 300)\r\n * @param easing - 缓动函数名(默认 'ease')\r\n */\r\n flipPlay(record: FLIPRecord<HE>, duration?: number, easing?: string): void {\r\n if (!this.options.enableFLIP) return;\r\n\r\n const dur = duration ?? 300;\r\n const ease = easing ?? 'ease';\r\n\r\n // Invert: 应用反向偏移\r\n this.host.setStyle(\r\n record.el,\r\n 'transform',\r\n `translate(${record.invert.x}px, ${record.invert.y}px)`,\r\n );\r\n this.host.setStyle(record.el, 'transition', 'none');\r\n\r\n // 强制回流\r\n this.host.forceReflow(record.el);\r\n\r\n // Play: 移除反向偏移,添加过渡\r\n this.host.setStyle(record.el, 'transition', `transform ${dur}ms ${ease}`);\r\n this.host.setStyle(record.el, 'transform', '');\r\n\r\n // 动画结束后清理\r\n this.host.setTimeout(() => {\r\n this.host.setStyle(record.el, 'transition', '');\r\n this.host.setStyle(record.el, 'transform', '');\r\n }, dur + 50);\r\n }\r\n\r\n /**\r\n * 执行完整的 FLIP 动画(First → Last → Invert → Play)。\r\n *\r\n * @param el - 宿主元素\r\n * @param updateFn - 在 First 和 Last 之间执行的更新函数(改变元素位置)\r\n * @param duration - 动画时长(ms,默认 300)\r\n * @param easing - 缓动函数名(默认 'ease')\r\n */\r\n flip(el: HE, updateFn: () => void, duration?: number, easing?: string): void {\r\n if (!this.options.enableFLIP) {\r\n updateFn();\r\n return;\r\n }\r\n\r\n // First: 记录初始位置\r\n const record = this.flipRecordFirst(el);\r\n\r\n // 执行更新(改变元素位置)\r\n updateFn();\r\n\r\n // Last: 记录最终位置\r\n const updatedRecord = this.flipRecordLast(record);\r\n\r\n // Play: 执行动画\r\n this.flipPlay(updatedRecord, duration, easing);\r\n }\r\n\r\n // ==========================================================\r\n // 内部方法\r\n // ==========================================================\r\n\r\n /**\r\n * 解析过渡类名。\r\n */\r\n private resolveTransitionClasses(\r\n props: TransitionProps<HE>,\r\n type: 'enter' | 'leave',\r\n ): ResolvedTransitionClasses {\r\n const name = props.name ?? this.options.defaultName;\r\n\r\n if (type === 'enter') {\r\n return {\r\n from: props.enterFromClass ?? `${name}-enter-from`,\r\n active: props.enterActiveClass ?? `${name}-enter-active`,\r\n to: props.enterToClass ?? `${name}-enter-to`,\r\n };\r\n } else {\r\n return {\r\n from: props.leaveFromClass ?? `${name}-leave-from`,\r\n active: props.leaveActiveClass ?? `${name}-leave-active`,\r\n to: props.leaveToClass ?? `${name}-leave-to`,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * 等待 CSS 过渡/动画结束。\r\n *\r\n * 通过监听 transitionend/animationend 事件实现,\r\n * 超时后自动完成(防止事件未触发)。\r\n */\r\n private waitForTransitionEnd(el: HE, info: TransitionDurationInfo, done: () => void): void {\r\n let called = false;\r\n const finish = () => {\r\n if (!called) {\r\n called = true;\r\n done();\r\n }\r\n };\r\n\r\n // 安全超时\r\n const timeout = info.duration > 0 ? info.duration + 50 : this.options.timeout;\r\n const timer = this.host.setTimeout(finish, timeout);\r\n\r\n // 创建事件处理函数\r\n // FIX: P1-15 创建类型适配的包装函数,将 onEnd 签名转换为 HostEventHandler\r\n // FIX: P2-v11-23 添加运行时验证,确保 onEnd 接收到的事件对象具有有效的 target 属性\r\n const onEnd = (event: unknown) => {\r\n // 运行时验证事件对象\r\n if (event == null || typeof event !== 'object') return;\r\n const hostEvent = event as { target: unknown; type: string };\r\n if (hostEvent.target !== el) return;\r\n\r\n this.host.clearTimeout(timer);\r\n finish();\r\n };\r\n const hostEventHandler: HostEventHandler = (event: HostEvent) => onEnd(event);\r\n\r\n // 通过 host 添加事件监听\r\n const disposeTransition = this.host.addEventListener(el, 'transitionend', hostEventHandler);\r\n const disposeAnimation = this.host.addEventListener(el, 'animationend', hostEventHandler);\r\n\r\n // 存储清理函数\r\n transitionCleanupMap.set(el, () => {\r\n this.host.clearTimeout(timer);\r\n disposeTransition();\r\n disposeAnimation();\r\n });\r\n }\r\n\r\n // ==========================================================\r\n // 清理\r\n // ==========================================================\r\n\r\n /**\r\n * 销毁过渡引擎,清理所有内部状态。\r\n */\r\n dispose(): void {\r\n this.stateMap = new WeakMap<HE, RuntimeTransitionState>();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// @lytjs/common-transition-engine\n// 过渡引擎:平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行\n\ndeclare const __DEV__: boolean;\n\nimport type {\n RendererHost,\n TransitionDurationInfo,\n HostEvent,\n HostEventHandler,\n} from '@lytjs/host-contract';\nimport type { HostRect } from '@lytjs/host-contract';\n\n// ============================================================\n// 类型定义\n// ============================================================\n\nexport interface TransitionProps<T = unknown> {\n name?: string;\n appear?: boolean;\n enterFromClass?: string;\n enterActiveClass?: string;\n enterToClass?: string;\n leaveFromClass?: string;\n leaveActiveClass?: string;\n leaveToClass?: string;\n onBeforeEnter?: (el: T) => void;\n onEnter?: (el: T, done: () => void) => void;\n onAfterEnter?: (el: T) => void;\n onEnterCancelled?: (el: T) => void;\n onBeforeLeave?: (el: T) => void;\n onLeave?: (el: T, done: () => void) => void;\n onAfterLeave?: (el: T) => void;\n onLeaveCancelled?: (el: T) => void;\n}\n\n/**\n * 过渡状态(运行时收敛层)。\n * 与 @lytjs/vdom/transition 中的 TransitionState 不同,\n * 此版本用于运行时收敛层的过渡控制。\n */\nexport interface RuntimeTransitionState {\n /** 当前过渡阶段 */\n phase: 'idle' | 'entering' | 'leaving';\n /** 是否已取消 */\n cancelled: boolean;\n /** 过渡完成回调 */\n doneCallback: (() => void) | null;\n /** FIX: P0-10 存储过渡属性引用,用于 cancelTransition 时调用取消钩子 */\n // FIX: DTS build error - 使用 unknown 避免类型不兼容\n props?: unknown;\n}\n\n/**\n * FLIP 动画的四个阶段记录。\n */\nexport interface FLIPRecord<HE> {\n /** 目标元素 */\n el: HE;\n /** First: 初始位置 */\n first: HostRect;\n /** Last: 最终位置 */\n last: HostRect;\n /** Invert: 偏移量 */\n invert: { x: number; y: number };\n /** Play: 播放回调 */\n play: (() => void) | null;\n}\n\n/**\n * 过渡类名解析结果。\n */\nexport interface ResolvedTransitionClasses {\n /** 起始类名 */\n from: string;\n /** 激活类名 */\n active: string;\n /** 结束类名 */\n to: string;\n}\n\n/**\n * 过渡引擎配置项。\n */\nexport interface TransitionEngineOptions {\n /** 默认过渡名称(默认 'v') */\n defaultName?: string;\n /** 过渡超时时间(ms,默认 5000) */\n timeout?: number;\n /** 是否启用 FLIP 动画(默认 true) */\n enableFLIP?: boolean;\n}\n\n// ============================================================\n// 常量\n// ============================================================\n\n/** 默认配置 */\nconst DEFAULT_OPTIONS: Required<TransitionEngineOptions> = {\n defaultName: 'v',\n timeout: 5000,\n enableFLIP: true,\n};\n\n/** 过渡清理函数映射 */\nconst transitionCleanupMap = new WeakMap<object, (() => void) | null>();\n\n// ============================================================\n// TransitionEngine\n// ============================================================\n\n/**\n * 过渡引擎。\n *\n * 平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行。\n * 包含 enter/leave 过渡逻辑和 FLIP 动画逻辑。\n *\n * @template HN - 宿主节点类型\n * @template HE - 宿主元素类型\n */\nexport class TransitionEngine<HN extends object = object, HE extends HN = HN> {\n /** RendererHost 实例 */\n private host: RendererHost<HN, HE>;\n\n /** 配置项 */\n private options: Required<TransitionEngineOptions>;\n\n /** 活跃的过渡状态映射(el → state) */\n private stateMap = new WeakMap<HE, RuntimeTransitionState>();\n\n /**\n * 创建过渡引擎实例。\n * @param host - RendererHost 实例\n * @param options - 可选的配置项\n */\n constructor(host: RendererHost<HN, HE>, options?: TransitionEngineOptions) {\n this.host = host;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n // ==========================================================\n // 过渡状态管理\n // ==========================================================\n\n /**\n * 获取元素的过渡状态。\n * @param el - 宿主元素\n * @returns 过渡状态\n */\n getState(el: HE): RuntimeTransitionState {\n let state = this.stateMap.get(el);\n if (!state) {\n state = {\n phase: 'idle',\n cancelled: false,\n doneCallback: null,\n };\n this.stateMap.set(el, state);\n }\n return state;\n }\n\n /**\n * 检查元素是否正在进行过渡。\n * @param el - 宿主元素\n */\n isTransitioning(el: HE): boolean {\n const state = this.stateMap.get(el);\n return state !== undefined && state.phase !== 'idle';\n }\n\n // ==========================================================\n // Enter 过渡\n // ==========================================================\n\n /**\n * 执行进入过渡。\n *\n * @param el - 宿主元素\n * @param props - 过渡属性\n * @param done - 过渡完成回调\n */\n performEnter(el: HE, props: TransitionProps<HE>, done: () => void): void {\n // 取消可能存在的旧过渡\n this.cancelTransition(el);\n\n const state = this.getState(el);\n state.phase = 'entering';\n state.cancelled = false;\n state.doneCallback = done;\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\n state.props = props;\n\n const classes = this.resolveTransitionClasses(props, 'enter');\n\n // 调用 onBeforeEnter 钩子\n if (props.onBeforeEnter) {\n props.onBeforeEnter(el);\n }\n\n // 添加 enter-from 和 enter-active 类\n this.host.addClass(el, classes.from);\n this.host.addClass(el, classes.active);\n\n // 强制回流,确保浏览器记录初始状态\n this.host.forceReflow(el);\n\n // 移除 enter-from,添加 enter-to\n this.host.removeClass(el, classes.from);\n this.host.addClass(el, classes.to);\n\n // 检查是否有 JS enter 钩子\n if (props.onEnter) {\n props.onEnter(el, () => {\n this.finishEnter(el, classes, props);\n });\n } else {\n // CSS 过渡:等待 transitionend/animationend\n const info = this.host.getTransitionInfo(el, 'enter');\n if (info.hasTransition || info.hasAnimation) {\n if (info.duration > 0) {\n this.host.setTimeout(() => this.finishEnter(el, classes, props), info.duration + 50);\n } else {\n this.waitForTransitionEnd(el, info, () => this.finishEnter(el, classes, props));\n }\n } else {\n // 无 CSS 过渡,立即完成\n this.finishEnter(el, classes, props);\n }\n }\n }\n\n /**\n * 完成进入过渡。\n */\n private finishEnter(\n el: HE,\n classes: ResolvedTransitionClasses,\n props: TransitionProps<HE>,\n ): void {\n const state = this.stateMap.get(el);\n if (!state || state.cancelled) return;\n\n this.host.removeClass(el, classes.active);\n this.host.removeClass(el, classes.to);\n\n if (props.onAfterEnter) {\n props.onAfterEnter(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n\n // 清理\n transitionCleanupMap.delete(el);\n }\n\n // ==========================================================\n // Leave 过渡\n // ==========================================================\n\n /**\n * 执行离开过渡。\n *\n * @param el - 宿主元素\n * @param props - 过渡属性\n * @param done - 过渡完成回调\n */\n performLeave(el: HE, props: TransitionProps<HE>, done: () => void): void {\n // 取消可能存在的旧过渡\n this.cancelTransition(el);\n\n const state = this.getState(el);\n state.phase = 'leaving';\n state.cancelled = false;\n state.doneCallback = done;\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\n state.props = props;\n\n const classes = this.resolveTransitionClasses(props, 'leave');\n\n // 调用 onBeforeLeave 钩子\n if (props.onBeforeLeave) {\n props.onBeforeLeave(el);\n }\n\n // 添加 leave-from 和 leave-active 类\n this.host.addClass(el, classes.from);\n this.host.addClass(el, classes.active);\n\n // 强制回流\n this.host.forceReflow(el);\n\n // 移除 leave-from,添加 leave-to\n this.host.removeClass(el, classes.from);\n this.host.addClass(el, classes.to);\n\n // 检查是否有 JS leave 钩子\n if (props.onLeave) {\n props.onLeave(el, () => {\n this.finishLeave(el, classes, props);\n });\n } else {\n // CSS 过渡\n const info = this.host.getTransitionInfo(el, 'leave');\n if (info.hasTransition || info.hasAnimation) {\n if (info.duration > 0) {\n this.host.setTimeout(() => this.finishLeave(el, classes, props), info.duration + 50);\n } else {\n this.waitForTransitionEnd(el, info, () => this.finishLeave(el, classes, props));\n }\n } else {\n this.finishLeave(el, classes, props);\n }\n }\n }\n\n /**\n * 完成离开过渡。\n */\n private finishLeave(\n el: HE,\n classes: ResolvedTransitionClasses,\n props: TransitionProps<HE>,\n ): void {\n const state = this.stateMap.get(el);\n if (!state || state.cancelled) return;\n\n this.host.removeClass(el, classes.active);\n this.host.removeClass(el, classes.to);\n\n if (props.onAfterLeave) {\n props.onAfterLeave(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n\n transitionCleanupMap.delete(el);\n }\n\n // ==========================================================\n // 取消过渡\n // ==========================================================\n\n /**\n * 取消元素上正在进行的过渡。\n *\n * @param el - 宿主元素\n */\n cancelTransition(el: HE): void {\n const state = this.stateMap.get(el);\n if (!state || state.phase === 'idle') return;\n\n state.cancelled = true;\n\n // FIX: P0-10 根据 phase 调用对应的取消钩子(onEnterCancelled / onLeaveCancelled)\n // FIX: DTS build error - 使用类型断言访问 props\n const props = state.props as\n | { onEnterCancelled?: (el: HE) => void; onLeaveCancelled?: (el: HE) => void }\n | undefined;\n if (props) {\n if (state.phase === 'entering' && props.onEnterCancelled) {\n props.onEnterCancelled(el);\n } else if (state.phase === 'leaving' && props.onLeaveCancelled) {\n props.onLeaveCancelled(el);\n }\n }\n\n // 执行清理函数\n const cleanup = transitionCleanupMap.get(el);\n if (cleanup) {\n cleanup();\n transitionCleanupMap.delete(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n state.props = undefined;\n }\n\n // ==========================================================\n // FLIP 动画\n // ==========================================================\n\n /**\n * 记录 FLIP 动画的 First 状态。\n *\n * @param el - 宿主元素\n * @returns FLIP 记录(含 First 阶段数据)\n */\n flipRecordFirst(el: HE): FLIPRecord<HE> {\n const first = this.host.getBoundingClientRect(el);\n return {\n el,\n first,\n last: { left: 0, top: 0, width: 0, height: 0, right: 0, bottom: 0 },\n invert: { x: 0, y: 0 },\n play: null,\n };\n }\n\n /**\n * 记录 FLIP 动画的 Last 状态并计算 Invert。\n *\n * @param record - FLIP 记录(含 First 阶段数据)\n * @returns 更新后的 FLIP 记录(含 Last 和 Invert 数据)\n */\n flipRecordLast(record: FLIPRecord<HE>): FLIPRecord<HE> {\n const last = this.host.getBoundingClientRect(record.el);\n const invertX = record.first.left - last.left;\n const invertY = record.first.top - last.top;\n\n return {\n ...record,\n last,\n invert: { x: invertX, y: invertY },\n };\n }\n\n /**\n * 执行 FLIP 动画的 Play 阶段。\n *\n * @param record - FLIP 记录(含 First、Last、Invert 数据)\n * @param duration - 动画时长(ms,默认 300)\n * @param easing - 缓动函数名(默认 'ease')\n */\n flipPlay(record: FLIPRecord<HE>, duration?: number, easing?: string): void {\n if (!this.options.enableFLIP) return;\n\n const dur = duration ?? 300;\n const ease = easing ?? 'ease';\n\n // Invert: 应用反向偏移\n this.host.setStyle(\n record.el,\n 'transform',\n `translate(${record.invert.x}px, ${record.invert.y}px)`,\n );\n this.host.setStyle(record.el, 'transition', 'none');\n\n // 强制回流\n this.host.forceReflow(record.el);\n\n // Play: 移除反向偏移,添加过渡\n this.host.setStyle(record.el, 'transition', `transform ${dur}ms ${ease}`);\n this.host.setStyle(record.el, 'transform', '');\n\n // 动画结束后清理\n this.host.setTimeout(() => {\n this.host.setStyle(record.el, 'transition', '');\n this.host.setStyle(record.el, 'transform', '');\n }, dur + 50);\n }\n\n /**\n * 执行完整的 FLIP 动画(First → Last → Invert → Play)。\n *\n * @param el - 宿主元素\n * @param updateFn - 在 First 和 Last 之间执行的更新函数(改变元素位置)\n * @param duration - 动画时长(ms,默认 300)\n * @param easing - 缓动函数名(默认 'ease')\n */\n flip(el: HE, updateFn: () => void, duration?: number, easing?: string): void {\n if (!this.options.enableFLIP) {\n updateFn();\n return;\n }\n\n // First: 记录初始位置\n const record = this.flipRecordFirst(el);\n\n // 执行更新(改变元素位置)\n updateFn();\n\n // Last: 记录最终位置\n const updatedRecord = this.flipRecordLast(record);\n\n // Play: 执行动画\n this.flipPlay(updatedRecord, duration, easing);\n }\n\n // ==========================================================\n // 内部方法\n // ==========================================================\n\n /**\n * 解析过渡类名。\n */\n private resolveTransitionClasses(\n props: TransitionProps<HE>,\n type: 'enter' | 'leave',\n ): ResolvedTransitionClasses {\n const name = props.name ?? this.options.defaultName;\n\n if (type === 'enter') {\n return {\n from: props.enterFromClass ?? `${name}-enter-from`,\n active: props.enterActiveClass ?? `${name}-enter-active`,\n to: props.enterToClass ?? `${name}-enter-to`,\n };\n } else {\n return {\n from: props.leaveFromClass ?? `${name}-leave-from`,\n active: props.leaveActiveClass ?? `${name}-leave-active`,\n to: props.leaveToClass ?? `${name}-leave-to`,\n };\n }\n }\n\n /**\n * 等待 CSS 过渡/动画结束。\n *\n * 通过监听 transitionend/animationend 事件实现,\n * 超时后自动完成(防止事件未触发)。\n */\n private waitForTransitionEnd(el: HE, info: TransitionDurationInfo, done: () => void): void {\n let called = false;\n const finish = () => {\n if (!called) {\n called = true;\n done();\n }\n };\n\n // 安全超时\n const timeout = info.duration > 0 ? info.duration + 50 : this.options.timeout;\n const timer = this.host.setTimeout(finish, timeout);\n\n // 创建事件处理函数\n // FIX: P1-15 创建类型适配的包装函数,将 onEnd 签名转换为 HostEventHandler\n // FIX: P2-v11-23 添加运行时验证,确保 onEnd 接收到的事件对象具有有效的 target 属性\n const onEnd = (event: unknown) => {\n // 运行时验证事件对象\n if (event == null || typeof event !== 'object') return;\n const hostEvent = event as { target: unknown; type: string };\n if (hostEvent.target !== el) return;\n\n this.host.clearTimeout(timer);\n finish();\n };\n const hostEventHandler: HostEventHandler = (event: HostEvent) => onEnd(event);\n\n // 通过 host 添加事件监听\n const disposeTransition = this.host.addEventListener(el, 'transitionend', hostEventHandler);\n const disposeAnimation = this.host.addEventListener(el, 'animationend', hostEventHandler);\n\n // 存储清理函数\n transitionCleanupMap.set(el, () => {\n this.host.clearTimeout(timer);\n disposeTransition();\n disposeAnimation();\n });\n }\n\n // ==========================================================\n // 清理\n // ==========================================================\n\n /**\n * 销毁过渡引擎,清理所有内部状态。\n */\n dispose(): void {\n this.stateMap = new WeakMap<HE, RuntimeTransitionState>();\n }\n}\n"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// @lytjs/common-transition-engine\r\n// 过渡引擎:平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行\r\n\r\ndeclare const __DEV__: boolean;\r\n\r\nimport type {\r\n RendererHost,\r\n TransitionDurationInfo,\r\n HostEvent,\r\n HostEventHandler,\r\n} from '@lytjs/host-contract';\r\nimport type { HostRect } from '@lytjs/host-contract';\r\n\r\n// ============================================================\r\n// 类型定义\r\n// ============================================================\r\n\r\nexport interface TransitionProps<T = unknown> {\r\n name?: string;\r\n appear?: boolean;\r\n enterFromClass?: string;\r\n enterActiveClass?: string;\r\n enterToClass?: string;\r\n leaveFromClass?: string;\r\n leaveActiveClass?: string;\r\n leaveToClass?: string;\r\n onBeforeEnter?: (el: T) => void;\r\n onEnter?: (el: T, done: () => void) => void;\r\n onAfterEnter?: (el: T) => void;\r\n onEnterCancelled?: (el: T) => void;\r\n onBeforeLeave?: (el: T) => void;\r\n onLeave?: (el: T, done: () => void) => void;\r\n onAfterLeave?: (el: T) => void;\r\n onLeaveCancelled?: (el: T) => void;\r\n}\r\n\r\n/**\r\n * 过渡状态(运行时收敛层)。\r\n * 与 @lytjs/vdom/transition 中的 TransitionState 不同,\r\n * 此版本用于运行时收敛层的过渡控制。\r\n */\r\nexport interface RuntimeTransitionState {\r\n /** 当前过渡阶段 */\r\n phase: 'idle' | 'entering' | 'leaving';\r\n /** 是否已取消 */\r\n cancelled: boolean;\r\n /** 过渡完成回调 */\r\n doneCallback: (() => void) | null;\r\n /** FIX: P0-10 存储过渡属性引用,用于 cancelTransition 时调用取消钩子 */\r\n // FIX: DTS build error - 使用 unknown 避免类型不兼容\r\n props?: unknown;\r\n}\r\n\r\n/**\r\n * FLIP 动画的四个阶段记录。\r\n */\r\nexport interface FLIPRecord<HE> {\r\n /** 目标元素 */\r\n el: HE;\r\n /** First: 初始位置 */\r\n first: HostRect;\r\n /** Last: 最终位置 */\r\n last: HostRect;\r\n /** Invert: 偏移量 */\r\n invert: { x: number; y: number };\r\n /** Play: 播放回调 */\r\n play: (() => void) | null;\r\n}\r\n\r\n/**\r\n * 过渡类名解析结果。\r\n */\r\nexport interface ResolvedTransitionClasses {\r\n /** 起始类名 */\r\n from: string;\r\n /** 激活类名 */\r\n active: string;\r\n /** 结束类名 */\r\n to: string;\r\n}\r\n\r\n/**\r\n * 过渡引擎配置项。\r\n */\r\nexport interface TransitionEngineOptions {\r\n /** 默认过渡名称(默认 'v') */\r\n defaultName?: string;\r\n /** 过渡超时时间(ms,默认 5000) */\r\n timeout?: number;\r\n /** 是否启用 FLIP 动画(默认 true) */\r\n enableFLIP?: boolean;\r\n}\r\n\r\n// ============================================================\r\n// 常量\r\n// ============================================================\r\n\r\n/** 默认配置 */\r\nconst DEFAULT_OPTIONS: Required<TransitionEngineOptions> = {\r\n defaultName: 'v',\r\n timeout: 5000,\r\n enableFLIP: true,\r\n};\r\n\r\n/** 过渡清理函数映射 */\r\nconst transitionCleanupMap = new WeakMap<object, (() => void) | null>();\r\n\r\n// ============================================================\r\n// TransitionEngine\r\n// ============================================================\r\n\r\n/**\r\n * 过渡引擎。\r\n *\r\n * 平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行。\r\n * 包含 enter/leave 过渡逻辑和 FLIP 动画逻辑。\r\n *\r\n * @template HN - 宿主节点类型\r\n * @template HE - 宿主元素类型\r\n */\r\nexport class TransitionEngine<HN extends object = object, HE extends HN = HN> {\r\n /** RendererHost 实例 */\r\n private host: RendererHost<HN, HE>;\r\n\r\n /** 配置项 */\r\n private options: Required<TransitionEngineOptions>;\r\n\r\n /** 活跃的过渡状态映射(el → state) */\r\n private stateMap = new WeakMap<HE, RuntimeTransitionState>();\r\n\r\n /**\r\n * 创建过渡引擎实例。\r\n * @param host - RendererHost 实例\r\n * @param options - 可选的配置项\r\n */\r\n constructor(host: RendererHost<HN, HE>, options?: TransitionEngineOptions) {\r\n this.host = host;\r\n this.options = { ...DEFAULT_OPTIONS, ...options };\r\n }\r\n\r\n // ==========================================================\r\n // 过渡状态管理\r\n // ==========================================================\r\n\r\n /**\r\n * 获取元素的过渡状态。\r\n * @param el - 宿主元素\r\n * @returns 过渡状态\r\n */\r\n getState(el: HE): RuntimeTransitionState {\r\n let state = this.stateMap.get(el);\r\n if (!state) {\r\n state = {\r\n phase: 'idle',\r\n cancelled: false,\r\n doneCallback: null,\r\n };\r\n this.stateMap.set(el, state);\r\n }\r\n return state;\r\n }\r\n\r\n /**\r\n * 检查元素是否正在进行过渡。\r\n * @param el - 宿主元素\r\n */\r\n isTransitioning(el: HE): boolean {\r\n const state = this.stateMap.get(el);\r\n return state !== undefined && state.phase !== 'idle';\r\n }\r\n\r\n // ==========================================================\r\n // Enter 过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 执行进入过渡。\r\n *\r\n * @param el - 宿主元素\r\n * @param props - 过渡属性\r\n * @param done - 过渡完成回调\r\n */\r\n performEnter(el: HE, props: TransitionProps<HE>, done: () => void): void {\r\n // 取消可能存在的旧过渡\r\n this.cancelTransition(el);\r\n\r\n const state = this.getState(el);\r\n state.phase = 'entering';\r\n state.cancelled = false;\r\n state.doneCallback = done;\r\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\r\n state.props = props;\r\n\r\n const classes = this.resolveTransitionClasses(props, 'enter');\r\n\r\n // 调用 onBeforeEnter 钩子\r\n if (props.onBeforeEnter) {\r\n props.onBeforeEnter(el);\r\n }\r\n\r\n // 添加 enter-from 和 enter-active 类\r\n this.host.addClass(el, classes.from);\r\n this.host.addClass(el, classes.active);\r\n\r\n // 强制回流,确保浏览器记录初始状态\r\n this.host.forceReflow(el);\r\n\r\n // 移除 enter-from,添加 enter-to\r\n this.host.removeClass(el, classes.from);\r\n this.host.addClass(el, classes.to);\r\n\r\n // 检查是否有 JS enter 钩子\r\n if (props.onEnter) {\r\n props.onEnter(el, () => {\r\n this.finishEnter(el, classes, props);\r\n });\r\n } else {\r\n // CSS 过渡:等待 transitionend/animationend\r\n const info = this.host.getTransitionInfo(el, 'enter');\r\n if (info.hasTransition || info.hasAnimation) {\r\n if (info.duration > 0) {\r\n this.host.setTimeout(() => this.finishEnter(el, classes, props), info.duration + 50);\r\n } else {\r\n this.waitForTransitionEnd(el, info, () => this.finishEnter(el, classes, props));\r\n }\r\n } else {\r\n // 无 CSS 过渡,立即完成\r\n this.finishEnter(el, classes, props);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 完成进入过渡。\r\n */\r\n private finishEnter(\r\n el: HE,\r\n classes: ResolvedTransitionClasses,\r\n props: TransitionProps<HE>,\r\n ): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.cancelled) return;\r\n\r\n this.host.removeClass(el, classes.active);\r\n this.host.removeClass(el, classes.to);\r\n\r\n if (props.onAfterEnter) {\r\n props.onAfterEnter(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n\r\n // 清理\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n // ==========================================================\r\n // Leave 过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 执行离开过渡。\r\n *\r\n * @param el - 宿主元素\r\n * @param props - 过渡属性\r\n * @param done - 过渡完成回调\r\n */\r\n performLeave(el: HE, props: TransitionProps<HE>, done: () => void): void {\r\n // 取消可能存在的旧过渡\r\n this.cancelTransition(el);\r\n\r\n const state = this.getState(el);\r\n state.phase = 'leaving';\r\n state.cancelled = false;\r\n state.doneCallback = done;\r\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\r\n state.props = props;\r\n\r\n const classes = this.resolveTransitionClasses(props, 'leave');\r\n\r\n // 调用 onBeforeLeave 钩子\r\n if (props.onBeforeLeave) {\r\n props.onBeforeLeave(el);\r\n }\r\n\r\n // 添加 leave-from 和 leave-active 类\r\n this.host.addClass(el, classes.from);\r\n this.host.addClass(el, classes.active);\r\n\r\n // 强制回流\r\n this.host.forceReflow(el);\r\n\r\n // 移除 leave-from,添加 leave-to\r\n this.host.removeClass(el, classes.from);\r\n this.host.addClass(el, classes.to);\r\n\r\n // 检查是否有 JS leave 钩子\r\n if (props.onLeave) {\r\n props.onLeave(el, () => {\r\n this.finishLeave(el, classes, props);\r\n });\r\n } else {\r\n // CSS 过渡\r\n const info = this.host.getTransitionInfo(el, 'leave');\r\n if (info.hasTransition || info.hasAnimation) {\r\n if (info.duration > 0) {\r\n this.host.setTimeout(() => this.finishLeave(el, classes, props), info.duration + 50);\r\n } else {\r\n this.waitForTransitionEnd(el, info, () => this.finishLeave(el, classes, props));\r\n }\r\n } else {\r\n this.finishLeave(el, classes, props);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 完成离开过渡。\r\n */\r\n private finishLeave(\r\n el: HE,\r\n classes: ResolvedTransitionClasses,\r\n props: TransitionProps<HE>,\r\n ): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.cancelled) return;\r\n\r\n this.host.removeClass(el, classes.active);\r\n this.host.removeClass(el, classes.to);\r\n\r\n if (props.onAfterLeave) {\r\n props.onAfterLeave(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n // ==========================================================\r\n // 取消过渡\r\n // ==========================================================\r\n\r\n /**\r\n * 取消元素上正在进行的过渡。\r\n *\r\n * @param el - 宿主元素\r\n */\r\n cancelTransition(el: HE): void {\r\n const state = this.stateMap.get(el);\r\n if (!state || state.phase === 'idle') return;\r\n\r\n state.cancelled = true;\r\n\r\n // FIX: P0-10 根据 phase 调用对应的取消钩子(onEnterCancelled / onLeaveCancelled)\r\n // FIX: DTS build error - 使用类型断言访问 props\r\n const props = state.props as\r\n | { onEnterCancelled?: (el: HE) => void; onLeaveCancelled?: (el: HE) => void }\r\n | undefined;\r\n if (props) {\r\n if (state.phase === 'entering' && props.onEnterCancelled) {\r\n props.onEnterCancelled(el);\r\n } else if (state.phase === 'leaving' && props.onLeaveCancelled) {\r\n props.onLeaveCancelled(el);\r\n }\r\n }\r\n\r\n // 执行清理函数\r\n const cleanup = transitionCleanupMap.get(el);\r\n if (cleanup) {\r\n cleanup();\r\n transitionCleanupMap.delete(el);\r\n }\r\n\r\n state.phase = 'idle';\r\n state.doneCallback = null;\r\n state.props = undefined;\r\n }\r\n\r\n // ==========================================================\r\n // FLIP 动画\r\n // ==========================================================\r\n\r\n /**\r\n * 记录 FLIP 动画的 First 状态。\r\n *\r\n * @param el - 宿主元素\r\n * @returns FLIP 记录(含 First 阶段数据)\r\n */\r\n flipRecordFirst(el: HE): FLIPRecord<HE> {\r\n const first = this.host.getBoundingClientRect(el);\r\n return {\r\n el,\r\n first,\r\n last: { left: 0, top: 0, width: 0, height: 0, right: 0, bottom: 0 },\r\n invert: { x: 0, y: 0 },\r\n play: null,\r\n };\r\n }\r\n\r\n /**\r\n * 记录 FLIP 动画的 Last 状态并计算 Invert。\r\n *\r\n * @param record - FLIP 记录(含 First 阶段数据)\r\n * @returns 更新后的 FLIP 记录(含 Last 和 Invert 数据)\r\n */\r\n flipRecordLast(record: FLIPRecord<HE>): FLIPRecord<HE> {\r\n const last = this.host.getBoundingClientRect(record.el);\r\n const invertX = record.first.left - last.left;\r\n const invertY = record.first.top - last.top;\r\n\r\n return {\r\n ...record,\r\n last,\r\n invert: { x: invertX, y: invertY },\r\n };\r\n }\r\n\r\n /**\r\n * 执行 FLIP 动画的 Play 阶段。\r\n *\r\n * @param record - FLIP 记录(含 First、Last、Invert 数据)\r\n * @param duration - 动画时长(ms,默认 300)\r\n * @param easing - 缓动函数名(默认 'ease')\r\n */\r\n flipPlay(record: FLIPRecord<HE>, duration?: number, easing?: string): void {\r\n if (!this.options.enableFLIP) return;\r\n\r\n const dur = duration ?? 300;\r\n const ease = easing ?? 'ease';\r\n\r\n // Invert: 应用反向偏移\r\n this.host.setStyle(\r\n record.el,\r\n 'transform',\r\n `translate(${record.invert.x}px, ${record.invert.y}px)`,\r\n );\r\n this.host.setStyle(record.el, 'transition', 'none');\r\n\r\n // 强制回流\r\n this.host.forceReflow(record.el);\r\n\r\n // Play: 移除反向偏移,添加过渡\r\n this.host.setStyle(record.el, 'transition', `transform ${dur}ms ${ease}`);\r\n this.host.setStyle(record.el, 'transform', '');\r\n\r\n // 动画结束后清理\r\n this.host.setTimeout(() => {\r\n this.host.setStyle(record.el, 'transition', '');\r\n this.host.setStyle(record.el, 'transform', '');\r\n }, dur + 50);\r\n }\r\n\r\n /**\r\n * 执行完整的 FLIP 动画(First → Last → Invert → Play)。\r\n *\r\n * @param el - 宿主元素\r\n * @param updateFn - 在 First 和 Last 之间执行的更新函数(改变元素位置)\r\n * @param duration - 动画时长(ms,默认 300)\r\n * @param easing - 缓动函数名(默认 'ease')\r\n */\r\n flip(el: HE, updateFn: () => void, duration?: number, easing?: string): void {\r\n if (!this.options.enableFLIP) {\r\n updateFn();\r\n return;\r\n }\r\n\r\n // First: 记录初始位置\r\n const record = this.flipRecordFirst(el);\r\n\r\n // 执行更新(改变元素位置)\r\n updateFn();\r\n\r\n // Last: 记录最终位置\r\n const updatedRecord = this.flipRecordLast(record);\r\n\r\n // Play: 执行动画\r\n this.flipPlay(updatedRecord, duration, easing);\r\n }\r\n\r\n // ==========================================================\r\n // 内部方法\r\n // ==========================================================\r\n\r\n /**\r\n * 解析过渡类名。\r\n */\r\n private resolveTransitionClasses(\r\n props: TransitionProps<HE>,\r\n type: 'enter' | 'leave',\r\n ): ResolvedTransitionClasses {\r\n const name = props.name ?? this.options.defaultName;\r\n\r\n if (type === 'enter') {\r\n return {\r\n from: props.enterFromClass ?? `${name}-enter-from`,\r\n active: props.enterActiveClass ?? `${name}-enter-active`,\r\n to: props.enterToClass ?? `${name}-enter-to`,\r\n };\r\n } else {\r\n return {\r\n from: props.leaveFromClass ?? `${name}-leave-from`,\r\n active: props.leaveActiveClass ?? `${name}-leave-active`,\r\n to: props.leaveToClass ?? `${name}-leave-to`,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * 等待 CSS 过渡/动画结束。\r\n *\r\n * 通过监听 transitionend/animationend 事件实现,\r\n * 超时后自动完成(防止事件未触发)。\r\n */\r\n private waitForTransitionEnd(el: HE, info: TransitionDurationInfo, done: () => void): void {\r\n let called = false;\r\n const finish = () => {\r\n if (!called) {\r\n called = true;\r\n done();\r\n }\r\n };\r\n\r\n // 安全超时\r\n const timeout = info.duration > 0 ? info.duration + 50 : this.options.timeout;\r\n const timer = this.host.setTimeout(finish, timeout);\r\n\r\n // 创建事件处理函数\r\n // FIX: P1-15 创建类型适配的包装函数,将 onEnd 签名转换为 HostEventHandler\r\n // FIX: P2-v11-23 添加运行时验证,确保 onEnd 接收到的事件对象具有有效的 target 属性\r\n const onEnd = (event: unknown) => {\r\n // 运行时验证事件对象\r\n if (event == null || typeof event !== 'object') return;\r\n const hostEvent = event as { target: unknown; type: string };\r\n if (hostEvent.target !== el) return;\r\n\r\n this.host.clearTimeout(timer);\r\n finish();\r\n };\r\n const hostEventHandler: HostEventHandler = (event: HostEvent) => onEnd(event);\r\n\r\n // 通过 host 添加事件监听\r\n const disposeTransition = this.host.addEventListener(el, 'transitionend', hostEventHandler);\r\n const disposeAnimation = this.host.addEventListener(el, 'animationend', hostEventHandler);\r\n\r\n // 存储清理函数\r\n transitionCleanupMap.set(el, () => {\r\n this.host.clearTimeout(timer);\r\n disposeTransition();\r\n disposeAnimation();\r\n });\r\n }\r\n\r\n // ==========================================================\r\n // 清理\r\n // ==========================================================\r\n\r\n /**\r\n * 销毁过渡引擎,清理所有内部状态。\r\n */\r\n dispose(): void {\r\n this.stateMap = new WeakMap<HE, RuntimeTransitionState>();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// @lytjs/common-transition-engine\n// 过渡引擎:平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行\n\ndeclare const __DEV__: boolean;\n\nimport type {\n RendererHost,\n TransitionDurationInfo,\n HostEvent,\n HostEventHandler,\n} from '@lytjs/host-contract';\nimport type { HostRect } from '@lytjs/host-contract';\n\n// ============================================================\n// 类型定义\n// ============================================================\n\nexport interface TransitionProps<T = unknown> {\n name?: string;\n appear?: boolean;\n enterFromClass?: string;\n enterActiveClass?: string;\n enterToClass?: string;\n leaveFromClass?: string;\n leaveActiveClass?: string;\n leaveToClass?: string;\n onBeforeEnter?: (el: T) => void;\n onEnter?: (el: T, done: () => void) => void;\n onAfterEnter?: (el: T) => void;\n onEnterCancelled?: (el: T) => void;\n onBeforeLeave?: (el: T) => void;\n onLeave?: (el: T, done: () => void) => void;\n onAfterLeave?: (el: T) => void;\n onLeaveCancelled?: (el: T) => void;\n}\n\n/**\n * 过渡状态(运行时收敛层)。\n * 与 @lytjs/vdom/transition 中的 TransitionState 不同,\n * 此版本用于运行时收敛层的过渡控制。\n */\nexport interface RuntimeTransitionState {\n /** 当前过渡阶段 */\n phase: 'idle' | 'entering' | 'leaving';\n /** 是否已取消 */\n cancelled: boolean;\n /** 过渡完成回调 */\n doneCallback: (() => void) | null;\n /** FIX: P0-10 存储过渡属性引用,用于 cancelTransition 时调用取消钩子 */\n // FIX: DTS build error - 使用 unknown 避免类型不兼容\n props?: unknown;\n}\n\n/**\n * FLIP 动画的四个阶段记录。\n */\nexport interface FLIPRecord<HE> {\n /** 目标元素 */\n el: HE;\n /** First: 初始位置 */\n first: HostRect;\n /** Last: 最终位置 */\n last: HostRect;\n /** Invert: 偏移量 */\n invert: { x: number; y: number };\n /** Play: 播放回调 */\n play: (() => void) | null;\n}\n\n/**\n * 过渡类名解析结果。\n */\nexport interface ResolvedTransitionClasses {\n /** 起始类名 */\n from: string;\n /** 激活类名 */\n active: string;\n /** 结束类名 */\n to: string;\n}\n\n/**\n * 过渡引擎配置项。\n */\nexport interface TransitionEngineOptions {\n /** 默认过渡名称(默认 'v') */\n defaultName?: string;\n /** 过渡超时时间(ms,默认 5000) */\n timeout?: number;\n /** 是否启用 FLIP 动画(默认 true) */\n enableFLIP?: boolean;\n}\n\n// ============================================================\n// 常量\n// ============================================================\n\n/** 默认配置 */\nconst DEFAULT_OPTIONS: Required<TransitionEngineOptions> = {\n defaultName: 'v',\n timeout: 5000,\n enableFLIP: true,\n};\n\n/** 过渡清理函数映射 */\nconst transitionCleanupMap = new WeakMap<object, (() => void) | null>();\n\n// ============================================================\n// TransitionEngine\n// ============================================================\n\n/**\n * 过渡引擎。\n *\n * 平台无关的过渡动画状态机,所有 DOM 操作通过 RendererHost 执行。\n * 包含 enter/leave 过渡逻辑和 FLIP 动画逻辑。\n *\n * @template HN - 宿主节点类型\n * @template HE - 宿主元素类型\n */\nexport class TransitionEngine<HN extends object = object, HE extends HN = HN> {\n /** RendererHost 实例 */\n private host: RendererHost<HN, HE>;\n\n /** 配置项 */\n private options: Required<TransitionEngineOptions>;\n\n /** 活跃的过渡状态映射(el → state) */\n private stateMap = new WeakMap<HE, RuntimeTransitionState>();\n\n /**\n * 创建过渡引擎实例。\n * @param host - RendererHost 实例\n * @param options - 可选的配置项\n */\n constructor(host: RendererHost<HN, HE>, options?: TransitionEngineOptions) {\n this.host = host;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n // ==========================================================\n // 过渡状态管理\n // ==========================================================\n\n /**\n * 获取元素的过渡状态。\n * @param el - 宿主元素\n * @returns 过渡状态\n */\n getState(el: HE): RuntimeTransitionState {\n let state = this.stateMap.get(el);\n if (!state) {\n state = {\n phase: 'idle',\n cancelled: false,\n doneCallback: null,\n };\n this.stateMap.set(el, state);\n }\n return state;\n }\n\n /**\n * 检查元素是否正在进行过渡。\n * @param el - 宿主元素\n */\n isTransitioning(el: HE): boolean {\n const state = this.stateMap.get(el);\n return state !== undefined && state.phase !== 'idle';\n }\n\n // ==========================================================\n // Enter 过渡\n // ==========================================================\n\n /**\n * 执行进入过渡。\n *\n * @param el - 宿主元素\n * @param props - 过渡属性\n * @param done - 过渡完成回调\n */\n performEnter(el: HE, props: TransitionProps<HE>, done: () => void): void {\n // 取消可能存在的旧过渡\n this.cancelTransition(el);\n\n const state = this.getState(el);\n state.phase = 'entering';\n state.cancelled = false;\n state.doneCallback = done;\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\n state.props = props;\n\n const classes = this.resolveTransitionClasses(props, 'enter');\n\n // 调用 onBeforeEnter 钩子\n if (props.onBeforeEnter) {\n props.onBeforeEnter(el);\n }\n\n // 添加 enter-from 和 enter-active 类\n this.host.addClass(el, classes.from);\n this.host.addClass(el, classes.active);\n\n // 强制回流,确保浏览器记录初始状态\n this.host.forceReflow(el);\n\n // 移除 enter-from,添加 enter-to\n this.host.removeClass(el, classes.from);\n this.host.addClass(el, classes.to);\n\n // 检查是否有 JS enter 钩子\n if (props.onEnter) {\n props.onEnter(el, () => {\n this.finishEnter(el, classes, props);\n });\n } else {\n // CSS 过渡:等待 transitionend/animationend\n const info = this.host.getTransitionInfo(el, 'enter');\n if (info.hasTransition || info.hasAnimation) {\n if (info.duration > 0) {\n this.host.setTimeout(() => this.finishEnter(el, classes, props), info.duration + 50);\n } else {\n this.waitForTransitionEnd(el, info, () => this.finishEnter(el, classes, props));\n }\n } else {\n // 无 CSS 过渡,立即完成\n this.finishEnter(el, classes, props);\n }\n }\n }\n\n /**\n * 完成进入过渡。\n */\n private finishEnter(\n el: HE,\n classes: ResolvedTransitionClasses,\n props: TransitionProps<HE>,\n ): void {\n const state = this.stateMap.get(el);\n if (!state || state.cancelled) return;\n\n this.host.removeClass(el, classes.active);\n this.host.removeClass(el, classes.to);\n\n if (props.onAfterEnter) {\n props.onAfterEnter(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n\n // 清理\n transitionCleanupMap.delete(el);\n }\n\n // ==========================================================\n // Leave 过渡\n // ==========================================================\n\n /**\n * 执行离开过渡。\n *\n * @param el - 宿主元素\n * @param props - 过渡属性\n * @param done - 过渡完成回调\n */\n performLeave(el: HE, props: TransitionProps<HE>, done: () => void): void {\n // 取消可能存在的旧过渡\n this.cancelTransition(el);\n\n const state = this.getState(el);\n state.phase = 'leaving';\n state.cancelled = false;\n state.doneCallback = done;\n // FIX: P0-10 存储 props 引用,用于 cancelTransition 时调用取消钩子\n state.props = props;\n\n const classes = this.resolveTransitionClasses(props, 'leave');\n\n // 调用 onBeforeLeave 钩子\n if (props.onBeforeLeave) {\n props.onBeforeLeave(el);\n }\n\n // 添加 leave-from 和 leave-active 类\n this.host.addClass(el, classes.from);\n this.host.addClass(el, classes.active);\n\n // 强制回流\n this.host.forceReflow(el);\n\n // 移除 leave-from,添加 leave-to\n this.host.removeClass(el, classes.from);\n this.host.addClass(el, classes.to);\n\n // 检查是否有 JS leave 钩子\n if (props.onLeave) {\n props.onLeave(el, () => {\n this.finishLeave(el, classes, props);\n });\n } else {\n // CSS 过渡\n const info = this.host.getTransitionInfo(el, 'leave');\n if (info.hasTransition || info.hasAnimation) {\n if (info.duration > 0) {\n this.host.setTimeout(() => this.finishLeave(el, classes, props), info.duration + 50);\n } else {\n this.waitForTransitionEnd(el, info, () => this.finishLeave(el, classes, props));\n }\n } else {\n this.finishLeave(el, classes, props);\n }\n }\n }\n\n /**\n * 完成离开过渡。\n */\n private finishLeave(\n el: HE,\n classes: ResolvedTransitionClasses,\n props: TransitionProps<HE>,\n ): void {\n const state = this.stateMap.get(el);\n if (!state || state.cancelled) return;\n\n this.host.removeClass(el, classes.active);\n this.host.removeClass(el, classes.to);\n\n if (props.onAfterLeave) {\n props.onAfterLeave(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n\n transitionCleanupMap.delete(el);\n }\n\n // ==========================================================\n // 取消过渡\n // ==========================================================\n\n /**\n * 取消元素上正在进行的过渡。\n *\n * @param el - 宿主元素\n */\n cancelTransition(el: HE): void {\n const state = this.stateMap.get(el);\n if (!state || state.phase === 'idle') return;\n\n state.cancelled = true;\n\n // FIX: P0-10 根据 phase 调用对应的取消钩子(onEnterCancelled / onLeaveCancelled)\n // FIX: DTS build error - 使用类型断言访问 props\n const props = state.props as\n | { onEnterCancelled?: (el: HE) => void; onLeaveCancelled?: (el: HE) => void }\n | undefined;\n if (props) {\n if (state.phase === 'entering' && props.onEnterCancelled) {\n props.onEnterCancelled(el);\n } else if (state.phase === 'leaving' && props.onLeaveCancelled) {\n props.onLeaveCancelled(el);\n }\n }\n\n // 执行清理函数\n const cleanup = transitionCleanupMap.get(el);\n if (cleanup) {\n cleanup();\n transitionCleanupMap.delete(el);\n }\n\n state.phase = 'idle';\n state.doneCallback = null;\n state.props = undefined;\n }\n\n // ==========================================================\n // FLIP 动画\n // ==========================================================\n\n /**\n * 记录 FLIP 动画的 First 状态。\n *\n * @param el - 宿主元素\n * @returns FLIP 记录(含 First 阶段数据)\n */\n flipRecordFirst(el: HE): FLIPRecord<HE> {\n const first = this.host.getBoundingClientRect(el);\n return {\n el,\n first,\n last: { left: 0, top: 0, width: 0, height: 0, right: 0, bottom: 0 },\n invert: { x: 0, y: 0 },\n play: null,\n };\n }\n\n /**\n * 记录 FLIP 动画的 Last 状态并计算 Invert。\n *\n * @param record - FLIP 记录(含 First 阶段数据)\n * @returns 更新后的 FLIP 记录(含 Last 和 Invert 数据)\n */\n flipRecordLast(record: FLIPRecord<HE>): FLIPRecord<HE> {\n const last = this.host.getBoundingClientRect(record.el);\n const invertX = record.first.left - last.left;\n const invertY = record.first.top - last.top;\n\n return {\n ...record,\n last,\n invert: { x: invertX, y: invertY },\n };\n }\n\n /**\n * 执行 FLIP 动画的 Play 阶段。\n *\n * @param record - FLIP 记录(含 First、Last、Invert 数据)\n * @param duration - 动画时长(ms,默认 300)\n * @param easing - 缓动函数名(默认 'ease')\n */\n flipPlay(record: FLIPRecord<HE>, duration?: number, easing?: string): void {\n if (!this.options.enableFLIP) return;\n\n const dur = duration ?? 300;\n const ease = easing ?? 'ease';\n\n // Invert: 应用反向偏移\n this.host.setStyle(\n record.el,\n 'transform',\n `translate(${record.invert.x}px, ${record.invert.y}px)`,\n );\n this.host.setStyle(record.el, 'transition', 'none');\n\n // 强制回流\n this.host.forceReflow(record.el);\n\n // Play: 移除反向偏移,添加过渡\n this.host.setStyle(record.el, 'transition', `transform ${dur}ms ${ease}`);\n this.host.setStyle(record.el, 'transform', '');\n\n // 动画结束后清理\n this.host.setTimeout(() => {\n this.host.setStyle(record.el, 'transition', '');\n this.host.setStyle(record.el, 'transform', '');\n }, dur + 50);\n }\n\n /**\n * 执行完整的 FLIP 动画(First → Last → Invert → Play)。\n *\n * @param el - 宿主元素\n * @param updateFn - 在 First 和 Last 之间执行的更新函数(改变元素位置)\n * @param duration - 动画时长(ms,默认 300)\n * @param easing - 缓动函数名(默认 'ease')\n */\n flip(el: HE, updateFn: () => void, duration?: number, easing?: string): void {\n if (!this.options.enableFLIP) {\n updateFn();\n return;\n }\n\n // First: 记录初始位置\n const record = this.flipRecordFirst(el);\n\n // 执行更新(改变元素位置)\n updateFn();\n\n // Last: 记录最终位置\n const updatedRecord = this.flipRecordLast(record);\n\n // Play: 执行动画\n this.flipPlay(updatedRecord, duration, easing);\n }\n\n // ==========================================================\n // 内部方法\n // ==========================================================\n\n /**\n * 解析过渡类名。\n */\n private resolveTransitionClasses(\n props: TransitionProps<HE>,\n type: 'enter' | 'leave',\n ): ResolvedTransitionClasses {\n const name = props.name ?? this.options.defaultName;\n\n if (type === 'enter') {\n return {\n from: props.enterFromClass ?? `${name}-enter-from`,\n active: props.enterActiveClass ?? `${name}-enter-active`,\n to: props.enterToClass ?? `${name}-enter-to`,\n };\n } else {\n return {\n from: props.leaveFromClass ?? `${name}-leave-from`,\n active: props.leaveActiveClass ?? `${name}-leave-active`,\n to: props.leaveToClass ?? `${name}-leave-to`,\n };\n }\n }\n\n /**\n * 等待 CSS 过渡/动画结束。\n *\n * 通过监听 transitionend/animationend 事件实现,\n * 超时后自动完成(防止事件未触发)。\n */\n private waitForTransitionEnd(el: HE, info: TransitionDurationInfo, done: () => void): void {\n let called = false;\n const finish = () => {\n if (!called) {\n called = true;\n done();\n }\n };\n\n // 安全超时\n const timeout = info.duration > 0 ? info.duration + 50 : this.options.timeout;\n const timer = this.host.setTimeout(finish, timeout);\n\n // 创建事件处理函数\n // FIX: P1-15 创建类型适配的包装函数,将 onEnd 签名转换为 HostEventHandler\n // FIX: P2-v11-23 添加运行时验证,确保 onEnd 接收到的事件对象具有有效的 target 属性\n const onEnd = (event: unknown) => {\n // 运行时验证事件对象\n if (event == null || typeof event !== 'object') return;\n const hostEvent = event as { target: unknown; type: string };\n if (hostEvent.target !== el) return;\n\n this.host.clearTimeout(timer);\n finish();\n };\n const hostEventHandler: HostEventHandler = (event: HostEvent) => onEnd(event);\n\n // 通过 host 添加事件监听\n const disposeTransition = this.host.addEventListener(el, 'transitionend', hostEventHandler);\n const disposeAnimation = this.host.addEventListener(el, 'animationend', hostEventHandler);\n\n // 存储清理函数\n transitionCleanupMap.set(el, () => {\n this.host.clearTimeout(timer);\n disposeTransition();\n disposeAnimation();\n });\n }\n\n // ==========================================================\n // 清理\n // ==========================================================\n\n /**\n * 销毁过渡引擎,清理所有内部状态。\n */\n dispose(): void {\n this.stateMap = new WeakMap<HE, RuntimeTransitionState>();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lytjs/common-transition-engine",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
4
4
|
"description": "Platform-agnostic transition engine with FLIP animation support for LytJS",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@lytjs/host-contract": "^6.
|
|
30
|
+
"@lytjs/host-contract": "^6.7.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"tsup": "^8.4.0",
|