mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-10-16 14:32:03 +00:00
111 lines
4.6 KiB
TypeScript
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;
|
|
};
|
|
}
|