Files
openstapps/frontend/app/src/app/modules/dashboard/sections/search-section/search-route-transition.ts
T

111 lines
4.6 KiB
TypeScript

/*
* Copyright (C) 2023 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {AnimationController} from '@ionic/angular/standalone';
import {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
/**
* Creates the page transition used when opening the search from the search field
* on the home page: the search bar moves up into the header of the search page,
* which fades in on top while the home page content slides away. Going back plays
* the same animation in reverse.
* @param animationController Ionic animation controller used to build the animation
* @returns animation builder to pass to `[routerAnimation]`
*/
export function homePageSearchTransition(animationController: AnimationController) {
let scheduleTransform: WebKitCSSMatrix;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (_baseElement: HTMLElement, options: AnimationOptions | any) => {
const back = options.direction === 'back';
const searchPage = back ? options.leavingEl : options.enteringEl;
const homePage = back ? options.enteringEl : options.leavingEl;
const rootTransition = animationController
.create()
.duration(options.duration ?? 350)
.easing(
// quintic in / out
back ? 'cubic-bezier(0.64, 0, 0.78, 0)' : 'cubic-bezier(0.22, 1, 0.36, 1)',
);
const homePageContent = homePage.querySelector('ion-content').shadowRoot.querySelector('.inner-scroll');
const leavingSearchbar = homePage.querySelector('ion-searchbar');
const enteringSearchbar = searchPage.querySelector('ion-searchbar');
const searchPageHeader = searchPage.querySelector('ion-header');
const homePageSchedule = homePage.querySelector('.schedule');
if (!back) {
scheduleTransform = new WebKitCSSMatrix(window.getComputedStyle(homePageSchedule).transform);
}
const enteringSearchbarTop = enteringSearchbar.getBoundingClientRect().top;
const leavingSearchbarTop = leavingSearchbar.getBoundingClientRect().top;
const searchbarDelta = leavingSearchbarTop - enteringSearchbarTop;
const searchHeaderHeight = searchPageHeader.getBoundingClientRect().bottom;
const homeHeaderHeight = homePageSchedule.getBoundingClientRect().bottom;
const homePageSlideAmount = -50;
const headerDelta = homeHeaderHeight - searchHeaderHeight;
const enterTransition = animationController.create().fromTo('opacity', '0', '1').addElement(searchPage);
if (back) {
enterTransition.afterStyles({display: 'none'});
}
const exitTransition = animationController.create().fromTo('opacity', '1', '1').addElement(homePage);
const homePageSlide = animationController
.create()
.fromTo('transform', `translateY(0px)`, `translateY(${homePageSlideAmount}px)`)
.addElement(homePageContent);
const toolbarExit = animationController
.create()
.fromTo(
'transform',
scheduleTransform.toString(),
scheduleTransform.translate(undefined, -headerDelta).toString(),
)
.addElement(homePageSchedule);
const headerSlide = animationController
.create()
.fromTo('transform', `translateY(${headerDelta}px)`, 'translateY(0px)')
.addElement(searchPageHeader);
const searchbarSlideIn = animationController
.create()
.fromTo('transform', `translateY(${searchbarDelta - headerDelta}px)`, 'translateY(0px)')
.beforeStyles({
'z-index': 1000,
})
.afterClearStyles(['z-index'])
.addElement(searchPage.querySelector('.toolbar-searchbar'));
const searchbarSlideOut = animationController
.create()
.fromTo('transform', 'translateY(0px)', `translateY(-${searchbarDelta + homePageSlideAmount}px)`)
.addElement(homePage.querySelector('stapps-search-section > stapps-section'));
rootTransition
.addAnimation([
enterTransition,
exitTransition,
toolbarExit,
homePageSlide,
headerSlide,
searchbarSlideIn,
searchbarSlideOut,
])
.direction(back ? 'reverse' : 'normal');
return rootTransition;
};
}