BottomSheet: move slides animations to platform
This commit is contained in:
parent
10b517bceb
commit
b61012f12b
2 changed files with 121 additions and 33 deletions
|
@ -195,3 +195,105 @@ export function animateShrinkToTopRight(
|
|||
|
||||
return animation;
|
||||
}
|
||||
|
||||
// Contribution to the animation speed:
|
||||
// - the screen size: mobiles should have longer transition,
|
||||
// the transition time should be longer as the travelling distance longer,
|
||||
// but it's not linear. The larger screen should have higher velocity,
|
||||
// to avoid the transition is too long.
|
||||
// As the screen larger, on desktops, the transition should be simpler and
|
||||
// signficantly faster.
|
||||
// On much smaller screens, like wearables, the transition should be shorter
|
||||
// than on mobiles.
|
||||
// - Animation complexity: On mobile:
|
||||
// - large, complex, full-screen transitions may have longer durations, over 375ms
|
||||
// - entering screen over 225ms
|
||||
// - leaving screen over 195ms
|
||||
|
||||
function transitionSpeedForEnter(innerWidth: number) {
|
||||
if (innerWidth < 300) {
|
||||
return 2.4;
|
||||
} else if (innerWidth < 560) {
|
||||
return 1.6;
|
||||
} else if (innerWidth < 1200) {
|
||||
return 2.4;
|
||||
} else {
|
||||
return 2.55;
|
||||
}
|
||||
}
|
||||
|
||||
function transitionSpeedForLeave(innerWidth: number) {
|
||||
if (innerWidth < 300) {
|
||||
return 2.8;
|
||||
} else if (innerWidth < 560) {
|
||||
return 1.96;
|
||||
} else if (innerWidth < 1200) {
|
||||
return 2.8;
|
||||
} else {
|
||||
return 2.55;
|
||||
}
|
||||
}
|
||||
|
||||
export function animateSlideInFromRight(
|
||||
root: HTMLElement,
|
||||
options?: Omit<KeyframeAnimationOptions, "duration">,
|
||||
) {
|
||||
const { left } = root.getBoundingClientRect();
|
||||
const { innerWidth } = window;
|
||||
|
||||
const oldOverflow = document.body.style.overflow;
|
||||
document.body.style.overflow = "hidden";
|
||||
|
||||
const distance = Math.abs(left - innerWidth);
|
||||
const duration = Math.floor(distance / transitionSpeedForEnter(innerWidth));
|
||||
|
||||
const opts = Object.assign({ duration }, options);
|
||||
|
||||
const animation = root.animate(
|
||||
{
|
||||
left: [`${innerWidth}px`, `${left}px`],
|
||||
},
|
||||
opts,
|
||||
);
|
||||
|
||||
const restore = () => {
|
||||
document.body.style.overflow = oldOverflow;
|
||||
};
|
||||
|
||||
animation.addEventListener("cancel", restore);
|
||||
animation.addEventListener("finish", restore);
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
export function animateSlideOutToRight(
|
||||
root: HTMLElement,
|
||||
options?: Omit<KeyframeAnimationOptions, "duration">,
|
||||
) {
|
||||
const { left } = root.getBoundingClientRect();
|
||||
const { innerWidth } = window;
|
||||
|
||||
const oldOverflow = document.body.style.overflow;
|
||||
document.body.style.overflow = "hidden";
|
||||
|
||||
const distance = Math.abs(left - innerWidth);
|
||||
const duration = Math.floor(distance / transitionSpeedForLeave(innerWidth));
|
||||
|
||||
const opts = Object.assign({ duration }, options);
|
||||
|
||||
const animation = root.animate(
|
||||
{
|
||||
left: [`${left}px`, `${innerWidth}px`],
|
||||
},
|
||||
opts,
|
||||
);
|
||||
|
||||
const restore = () => {
|
||||
document.body.style.overflow = oldOverflow;
|
||||
};
|
||||
|
||||
animation.addEventListener("cancel", restore);
|
||||
animation.addEventListener("finish", restore);
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue