Files
openstapps/frontend/app/src/app/modules/dashboard/dashboard-collapse.ts
Thea Schöbl b8ac30b9d0 refactor: migrate to angular esbuild
refactor: migrate to ionic standalone components
refactor: migrate ion icons to a custom element
2025-06-18 14:19:56 +02:00

99 lines
3.1 KiB
TypeScript

/*
* Copyright (C) 2022 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 {Animation, AnimationController} from '@ionic/angular/standalone';
import {NgZone} from '@angular/core';
export class DashboardCollapse {
collapseAnimation: Animation;
nextFrame: number;
setReady: () => void;
// eslint-disable-next-line unicorn/consistent-function-scoping
ready = new Promise<void>(resolve => (this.setReady = resolve));
set active(value: boolean) {
this.zone.runOutsideAngular(() => {
if (value) {
this.start();
} else {
this.stop();
}
});
}
constructor(
private animationControl: AnimationController,
private zone: NgZone,
private scrollContainer: HTMLElement,
toolbar: HTMLElement,
schedule: HTMLElement,
) {
this.zone
.runOutsideAngular(async () => {
this.collapseAnimation = this.animationControl
.create()
.duration(1000)
.addAnimation([
this.animationControl
.create()
.addElement(toolbar)
.fromTo('transform', 'translateY(0)', 'translateY(-32px)'),
this.animationControl
.create()
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.addElement(toolbar.querySelector(':scope > div > ion-img')!)
.fromTo('transform', 'scale(1)', 'scale(0.35)'),
this.animationControl
.create()
.addElement(schedule)
.fromTo('transform', 'translateY(0) scaleY(1)', 'translateY(-75px) scaleY(0.8)'),
this.animationControl
.create()
.addElement(schedule.querySelectorAll(':scope > a > *'))
.fromTo('transform', 'scaleY(1)', `scaleY(${1 / 0.8})`),
]);
this.start();
this.setReady();
})
.then();
}
private start() {
this.collapseAnimation.progressStart(true, this.scrollContainer.scrollTop / 172);
let pos = this.scrollContainer.scrollTop;
const animate = () => {
if (pos !== this.scrollContainer.scrollTop) {
pos = this.scrollContainer.scrollTop;
this.collapseAnimation.progressStep(this.scrollContainer.scrollTop / 172);
}
this.nextFrame = requestAnimationFrame(animate);
};
this.nextFrame = requestAnimationFrame(animate);
}
private stop() {
cancelAnimationFrame(this.nextFrame);
this.collapseAnimation.progressEnd(0, 0, 0);
}
destroy() {
this.stop();
this.collapseAnimation.destroy();
}
}