From 1a3412d7ac0d72e0bac8e46b1b726fd55e63b2ab Mon Sep 17 00:00:00 2001 From: jojohoch <joachim.hoch@iqb.hu-berlin.de> Date: Tue, 28 Nov 2023 17:59:48 +0100 Subject: [PATCH] [player] Improve concat scrolling - add padding - add stopping on every page - change selected index recognition --- .../pages-layout/pages-layout.component.html | 3 +++ .../pages-layout/pages-layout.component.scss | 2 ++ .../pages-layout/pages-layout.component.ts | 1 + .../page-scroll-button.component.ts | 7 ++++--- .../app/components/page/page.component.html | 2 ++ .../src/app/components/page/page.component.ts | 4 +--- .../directives/in-view-detection.directive.ts | 3 ++- .../directives/scroll-to-index.directive.ts | 18 +++++++++++------- 8 files changed, 26 insertions(+), 14 deletions(-) diff --git a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.html b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.html index 0e6e82e10..0b2b37cab 100644 --- a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.html +++ b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.html @@ -46,6 +46,7 @@ <aspect-page-scroll-button class="page-container" cdkScrollable [isSnapMode]="scrollPageMode === 'concat-scroll-snap'" + [concatScrollPadding]="concatScrollPadding" [class.concat-scroll-snap]="scrollPageMode === 'concat-scroll-snap'" [style.max-height.%]="aspectRatioColumn.scrollPages" [style.max-width.%]="aspectRatioRow.scrollPages" @@ -100,6 +101,7 @@ [style.max-width]="page.hasMaxWidth ? page.maxWidth + 'px' : '100%'" [style.padding.px]="page.margin" aspectScrollToIndex + [scrollPagesLength]="scrollPages.length" [selectIndex]="selectIndex" [index]="i"> <div *ngIf="!hidePageLabels" @@ -109,6 +111,7 @@ <aspect-page [pageIndex]="pages | pageIndex: page" [scrollPageIndex]="i" [pagesContainer]="pagesContainer" + [concatScrollPadding]="scrollPageMode === 'concat-scroll-snap' ? concatScrollPadding : 0" [page]="page" [isLastPage]="last" (selectedIndexChange)="setSelectedIndex($event)"> diff --git a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.scss b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.scss index 5366e753f..a8a5d3b07 100644 --- a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.scss +++ b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.scss @@ -21,6 +21,8 @@ .concat-scroll-snap { scroll-snap-type: y mandatory; scroll-padding: 0; + scroll-padding-bottom: 50px; // same value in component + scroll-snap-stop: always; } .page-container{ diff --git a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.ts b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.ts index 300a34094..c2bb99542 100644 --- a/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.ts +++ b/projects/player/src/app/components/layouts/pages-layout/pages-layout.component.ts @@ -31,6 +31,7 @@ export class PagesLayoutComponent implements OnInit, AfterViewInit, OnDestroy { layoutAlignment: 'row' | 'column' = 'row'; hidePageLabels: boolean = true; tabHeaderHeight: number = 0; + concatScrollPadding: number = 50; // Use the same value in Css maxWidth: { alwaysVisiblePage: number, scrollPages: number, allPages: number } = { alwaysVisiblePage: 0, scrollPages: 0, allPages: 0 }; diff --git a/projects/player/src/app/components/page-scroll-button/page-scroll-button.component.ts b/projects/player/src/app/components/page-scroll-button/page-scroll-button.component.ts index cc902ca80..2550d9cbf 100644 --- a/projects/player/src/app/components/page-scroll-button/page-scroll-button.component.ts +++ b/projects/player/src/app/components/page-scroll-button/page-scroll-button.component.ts @@ -17,7 +17,7 @@ export class PageScrollButtonComponent implements AfterViewInit, OnDestroy { } @Input() isSnapMode!: boolean; - + @Input() concatScrollPadding!: number; @Output() scrollToNextPage: EventEmitter<void> = new EventEmitter<void>(); isVisible: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); @@ -60,7 +60,8 @@ export class PageScrollButtonComponent implements AfterViewInit, OnDestroy { scrollDown(): void { const nextScrollTop = this.elementRef.nativeElement.scrollTop + 2; - if (this.isSnapMode && this.getBottomsOfPages() + const pageBottoms: number[] = this.getBottomsOfPages(); + if (this.isSnapMode && pageBottoms.length > 1 && pageBottoms .filter((page: number) => Math .abs(page - (nextScrollTop + this.elementRef.nativeElement.offsetHeight)) <= 2).length === 1) { this.clearScrollIng(); @@ -74,7 +75,7 @@ export class PageScrollButtonComponent implements AfterViewInit, OnDestroy { return [...this.elementRef.nativeElement.querySelectorAll('aspect-page')] .map(page => page.parentElement?.offsetHeight) .reduce((acc, v, i) => { - i === 0 ? acc.push(v) : acc.push(v + acc[i - 1]); + i === 0 ? acc.push(v + this.concatScrollPadding) : acc.push(v + acc[i - 1]); return acc; }, []); } diff --git a/projects/player/src/app/components/page/page.component.html b/projects/player/src/app/components/page/page.component.html index 231600c01..2f0ba8ab3 100644 --- a/projects/player/src/app/components/page/page.component.html +++ b/projects/player/src/app/components/page/page.component.html @@ -1,5 +1,6 @@ <div aspectInViewDetection detectionType="top" + [topPadding]="concatScrollPadding || 0" [intersectionContainer]="pagesContainer" (intersecting)="selectedIndexChange.emit(scrollPageIndex)"> <aspect-section @@ -17,6 +18,7 @@ </div> <div aspectInViewDetection detectionType="bottom" + [topPadding]="concatScrollPadding || 0" [intersectionContainer]="pagesContainer" (intersecting)="selectedIndexChange.emit(scrollPageIndex)"> </div> diff --git a/projects/player/src/app/components/page/page.component.ts b/projects/player/src/app/components/page/page.component.ts index eb08b2757..2acf2026e 100644 --- a/projects/player/src/app/components/page/page.component.ts +++ b/projects/player/src/app/components/page/page.component.ts @@ -2,7 +2,6 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; import { Page } from 'common/models/page'; -import { MediaPlayerService } from '../../services/media-player.service'; @Component({ selector: 'aspect-page', @@ -16,7 +15,6 @@ export class PageComponent { @Input() pageIndex!: number; @Input() scrollPageIndex!: number; @Input() pagesContainer!: HTMLElement; + @Input() concatScrollPadding!: number; @Output() selectedIndexChange = new EventEmitter<number>(); - - constructor(public mediaPlayerService: MediaPlayerService) {} } diff --git a/projects/player/src/app/directives/in-view-detection.directive.ts b/projects/player/src/app/directives/in-view-detection.directive.ts index 476e78466..86812016d 100644 --- a/projects/player/src/app/directives/in-view-detection.directive.ts +++ b/projects/player/src/app/directives/in-view-detection.directive.ts @@ -12,6 +12,7 @@ export class InViewDetectionDirective implements OnInit, OnDestroy { @Input() detectionType!: 'top' | 'bottom'; @Output() intersecting = new EventEmitter(); @Input() intersectionContainer!: HTMLElement; + @Input() topPadding!: number; intersectionDetector!: IntersectionDetector; @@ -20,7 +21,7 @@ export class InViewDetectionDirective implements OnInit, OnDestroy { constructor(private elementRef: ElementRef) {} ngOnInit(): void { - const constraint = this.detectionType === 'top' ? '0px 0px -99% 0px' : '99% 0px 0px 0px'; + const constraint = this.detectionType === 'top' ? `${this.topPadding}px 0% -90% 0%` : '-90% 0% 0% 0%'; this.intersectionDetector = new IntersectionDetector(this.intersectionContainer, constraint); this.intersectionDetector.observe(this.elementRef.nativeElement); this.intersectionDetector.intersecting diff --git a/projects/player/src/app/directives/scroll-to-index.directive.ts b/projects/player/src/app/directives/scroll-to-index.directive.ts index ac5133c9d..d0993825b 100644 --- a/projects/player/src/app/directives/scroll-to-index.directive.ts +++ b/projects/player/src/app/directives/scroll-to-index.directive.ts @@ -10,19 +10,23 @@ import { takeUntil } from 'rxjs/operators'; export class ScrollToIndexDirective implements OnInit, OnDestroy { @Input() selectIndex!: Subject<number>; @Input() index!: number; + @Input() scrollPagesLength!: number; private ngUnsubscribe = new Subject<void>(); constructor(private elementRef: ElementRef) {} ngOnInit(): void { - this.selectIndex - .pipe(takeUntil(this.ngUnsubscribe)) - .subscribe((selectedIndex: number): void => { - if (selectedIndex === this.index) { - this.elementRef.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }); + if (this.scrollPagesLength > 1) { + this.selectIndex + .pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((selectedIndex: number): void => { + if (selectedIndex === this.index) { + setTimeout(() => this.elementRef.nativeElement + .scrollIntoView({ behavior: 'smooth', block: 'start' })); + } + }); + } } ngOnDestroy(): void { -- GitLab