|
1 | 1 | import {CssSheetArray} from '@gaubee/web'; |
2 | 2 | import {match} from 'ts-pattern'; |
| 3 | +import {set_intersection} from '../set.polyfill'; |
3 | 4 | import {SharedElementBaseImpl, sharedElementLifecycle, sharedElements} from './shared-element-common'; |
4 | 5 | import { |
5 | 6 | type SharedElementAnimation, |
@@ -45,38 +46,50 @@ export class SharedElement extends SharedElementBaseImpl implements SharedElemen |
45 | 46 | return; |
46 | 47 | } |
47 | 48 | const sharedElementPagesContext = this.__getPagesContext(lifecycle, context); |
| 49 | + const {dest, from} = sharedElementPagesContext; |
| 50 | + // 必须确保两个page都存在 |
| 51 | + if (dest == null || from == null) return; |
48 | 52 |
|
49 | 53 | /// 最后,处理过渡元素 |
50 | 54 | if (lifecycle === 'finish') { |
51 | | - for (const pageItem of [sharedElementPagesContext.from, sharedElementPagesContext.dest]) { |
52 | | - if (pageItem) { |
53 | | - sharedElementLifecycle.delete(pageItem.navEntryNode); |
54 | | - /// 清理所有 viewTransitionName |
55 | | - // pageItem.node.style.viewTransitionName = ''; |
56 | | - for (const sharedElement of sharedElements.queryAll(pageItem.navEntryNode)) { |
57 | | - sharedElement.style.viewTransitionName = ''; |
58 | | - delete sharedElement.dataset.sharedElementState; |
59 | | - } |
| 55 | + for (const pageItem of [from, dest]) { |
| 56 | + sharedElementLifecycle.delete(pageItem.navEntryNode); |
| 57 | + /// 清理所有 viewTransitionName |
| 58 | + // pageItem.node.style.viewTransitionName = ''; |
| 59 | + for (const sharedElement of sharedElements.queryAll(pageItem.navEntryNode)) { |
| 60 | + sharedElement.style.viewTransitionName = ''; |
| 61 | + delete sharedElement.dataset.sharedElementState; |
60 | 62 | } |
61 | 63 | } |
62 | 64 | } else { |
| 65 | + const fromNavEntryNode = from.navEntryNode; |
| 66 | + const destNavEntryNode = dest.navEntryNode; |
| 67 | + |
63 | 68 | const sharedElementCss = this.css; |
64 | 69 | const sharedElementMap = new Map<string, HTMLElement>(); |
65 | | - const sharedElementIndex = Math.max(sharedElementPagesContext.from?.navEntryNode.sharedIndex ?? 0, sharedElementPagesContext.dest?.navEntryNode.sharedIndex ?? 0) + 1; |
66 | | - const sharedElementPages = match(lifecycle) |
67 | | - .with('first', () => [sharedElementPagesContext.dest, sharedElementPagesContext.from]) |
68 | | - .with('last', () => [sharedElementPagesContext.from, sharedElementPagesContext.dest]) |
| 70 | + const sharedElementIndex = Math.max(from.navEntryNode.sharedIndex, dest.navEntryNode.sharedIndex) + 1; |
| 71 | + // 必须确保同一个name在两个page都都存在 |
| 72 | + const fromSharedElementMap = new Map(sharedElements.queryAllWithConfig(fromNavEntryNode).map((item) => [item.name, item])); |
| 73 | + const destSharedElementMap = new Map(sharedElements.queryAllWithConfig(destNavEntryNode).map((item) => [item.name, item])); |
| 74 | + const sharedElementNames = set_intersection(new Set(fromSharedElementMap.keys()), destSharedElementMap); |
| 75 | + |
| 76 | + const sharedElementPages = [ |
| 77 | + {pageItem: dest, eleMap: destSharedElementMap}, |
| 78 | + {pageItem: from, eleMap: fromSharedElementMap}, |
| 79 | + ]; |
| 80 | + match(lifecycle) |
| 81 | + .with('first', () => sharedElementPages) |
| 82 | + .with('last', () => sharedElementPages.reverse()) |
69 | 83 | .exhaustive(); |
70 | 84 |
|
71 | | - for (const pageItem of sharedElementPages) { |
72 | | - if (pageItem) { |
73 | | - sharedElementLifecycle.set(pageItem.navEntryNode, lifecycle); |
74 | | - const navEntryNode = pageItem.navEntryNode; |
75 | | - const zIndexStart = navEntryNode.sharedIndex; |
76 | | - this.__setSharedElement(sharedElementCss, navEntryNode, sharedElements.get(navEntryNode)!, sharedElementMap, `z-index:${zIndexStart};`); |
77 | | - for (const sharedItem of sharedElements.queryAllWithConfig(pageItem.navEntryNode)) { |
78 | | - this.__setSharedElement(sharedElementCss, sharedItem.element, sharedItem, sharedElementMap, `z-index:${sharedElementIndex};`); |
79 | | - } |
| 85 | + for (const {pageItem, eleMap} of sharedElementPages) { |
| 86 | + sharedElementLifecycle.set(pageItem.navEntryNode, lifecycle); |
| 87 | + const navEntryNode = pageItem.navEntryNode; |
| 88 | + const zIndexStart = navEntryNode.sharedIndex; |
| 89 | + this.__setSharedElement(sharedElementCss, navEntryNode, sharedElements.get(navEntryNode)!, sharedElementMap, `z-index:${zIndexStart};`); |
| 90 | + for (const sharedName of sharedElementNames) { |
| 91 | + const sharedItem = eleMap.get(sharedName)!; |
| 92 | + this.__setSharedElement(sharedElementCss, sharedItem.element, sharedItem, sharedElementMap, `z-index:${sharedElementIndex};`); |
80 | 93 | } |
81 | 94 | } |
82 | 95 | } |
|
0 commit comments