1880
// keyframe. Otherwise it applies to every keyframe.
1881
moveOldFrameIntoViewport(keyframes[0]);
1882
}
1883
+ // TODO: Reverse the reverse if the original direction is reverse.
1884
const reverse = rangeStart > rangeEnd;
1885
targetElement.animate(keyframes, {
1886
pseudoElement: pseudoElement,
1891
// from scroll bouncing.
1892
easing: 'linear',
1893
// We fill in both direction for overscroll.
1893
- fill: 'both',
1894
+ fill: 'both', // TODO: Should we preserve the fill instead?
1895
// We play all gestures in reverse, except if we're in reverse direction
1896
// in which case we need to play it in reverse of the reverse.
1897
direction: reverse ? 'normal' : 'reverse',
1936
// up if they exist later.
1937
const foundGroups: Set<string> = new Set();
1938
const foundNews: Set<string> = new Set();
1939
+ // Collect the longest duration of any view-transition animation including delay.
1940
+ let longestDuration = 0;
1941
for (let i = 0; i < animations.length; i++) {
1942
+ const effect: KeyframeEffect = (animations[i].effect: any);
1943
// $FlowFixMe
1940
- const pseudoElement: ?string = animations[i].effect.pseudoElement;
1944
+ const pseudoElement: ?string = effect.pseudoElement;
1945
if (pseudoElement == null) {
1942
- } else if (pseudoElement.startsWith('::view-transition-group')) {
1943
- foundGroups.add(pseudoElement.slice(23));
1944
- } else if (pseudoElement.startsWith('::view-transition-new')) {
1945
- // TODO: This is not really a sufficient detection because if the new
1946
- // pseudo element might exist but have animations disabled on it.
1947
- foundNews.add(pseudoElement.slice(21));
1946
+ } else if (pseudoElement.startsWith('::view-transition')) {
1947
+ const timing = effect.getTiming();
1948
+ const duration =
1949
+ typeof timing.duration === 'number' ? timing.duration : 0;
1950
+ // TODO: Consider interation count higher than 1.
1951
+ const durationWithDelay = timing.delay + duration;
1952
+ if (durationWithDelay > longestDuration) {
1953
+ longestDuration = durationWithDelay;
1954
+ }
1955
+ if (pseudoElement.startsWith('::view-transition-group')) {
1956
+ foundGroups.add(pseudoElement.slice(23));
1957
+ } else if (pseudoElement.startsWith('::view-transition-new')) {
1958
+ // TODO: This is not really a sufficient detection because if the new
1959
+ // pseudo element might exist but have animations disabled on it.
1960
+ foundNews.add(pseudoElement.slice(21));
1961
+ }
1962
}
1963
}
1964
+ const durationToRangeMultipler =
1965
+ (rangeEnd - rangeStart) / longestDuration;
1966
for (let i = 0; i < animations.length; i++) {
1967
const anim = animations[i];
1968
if (anim.playState !== 'running') {
2002
}
2003
// TODO: If this has only an old state and no new state,
2004
}
2005
+ // Adjust the range based on how long the animation would've ran as time based.
2006
+ // Since we're running animations in reverse from how they normally would run,
2007
+ // therefore the timing is from the rangeEnd to the start.
2008
+ const timing = effect.getTiming();
2009
+ const duration =
2010
+ typeof timing.duration === 'number' ? timing.duration : 0;
2011
+ let adjustedRangeStart =
2012
+ rangeEnd - (duration + timing.delay) * durationToRangeMultipler;
2013
+ let adjustedRangeEnd =
2014
+ rangeEnd - timing.delay * durationToRangeMultipler;
2015
+ if (
2016
+ timing.direction === 'reverse' ||
2017
+ timing.direction === 'alternate-reverse'
2018
+ ) {
2019
+ // This animation was originally in reverse so we have to play it in flipped range.
2020
+ const temp = adjustedRangeStart;
2021
+ adjustedRangeStart = adjustedRangeEnd;
2022
+ adjustedRangeEnd = temp;
2023
+ }
2024
animateGesture(
2025
effect.getKeyframes(),
2026
// $FlowFixMe: Always documentElement atm.
2027
effect.target,
2028
pseudoElement,
2029
timeline,
1995
- rangeStart,
1996
- rangeEnd,
2030
+ adjustedRangeStart,
2031
+ adjustedRangeEnd,
2032
isGeneratedGroupAnim,
2033
isExitGroupAnim,
2034
);