virtual scroll updates

This commit is contained in:
Timo 2020-11-30 19:08:51 +02:00
parent 40f519afd6
commit d088834dc8
4 changed files with 73 additions and 11 deletions

View File

@ -86,6 +86,7 @@ import { DictionaryListingScreenComponent } from './screens/admin/dictionary-lis
import { CustomTooltipModule } from './common/red-tooltip/custom-tooltip.module'; import { CustomTooltipModule } from './common/red-tooltip/custom-tooltip.module';
import { ScrollingModule } from '@angular/cdk/scrolling'; import { ScrollingModule } from '@angular/cdk/scrolling';
import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component'; import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
export function HttpLoaderFactory(httpClient: HttpClient) { export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -237,7 +238,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
MatCheckboxModule, MatCheckboxModule,
MatListModule, MatListModule,
MatDatepickerModule, MatDatepickerModule,
MatInputModule MatInputModule,
DragDropModule
], ],
providers: [ providers: [
{ {

View File

@ -1,3 +1,13 @@
<div class="virtual-scroll" #scrollElement> <div class="virtual-scroll" #scrollElement (click)="scrollClicked($event)">
<div class="virtual" [style.height]="height + 'px'"></div> <div
class="scroller"
[style.height]="height + 'px'"
cdkDragBoundary=".virtual-scroll"
cdkDrag
#scroller
(cdkDragMoved)="moved($event)"
(cdkDragReleased)="released($event)"
(cdkDragStarted)="started($event)"
(click)="$event.stopPropagation()"
></div>
</div> </div>

View File

@ -1,6 +1,7 @@
@import '../../../assets/styles/red-variables';
.virtual-scroll { .virtual-scroll {
// TODO fix this - pass information as input or such // TODO fix this - pass information as input or such
display: none;
position: fixed; position: fixed;
width: 10px; width: 10px;
right: 480px; right: 480px;
@ -8,8 +9,17 @@
z-index: 100; z-index: 100;
top: 191px; top: 191px;
overflow: auto; overflow: auto;
background: $grey-6;
.virtual { .scroller {
height: 2000px; position: absolute;
height: 50px;
width: 10px;
background: $grey-5;
transition: transform 0.1s ease 0s, background 0.25s ease;
&:hover {
background: $grey-7;
}
} }
} }

View File

@ -1,5 +1,5 @@
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
import { syncScroll } from '../sync-scroll'; import { CdkDragMove, CdkDragRelease, CdkDragStart } from '@angular/cdk/drag-drop';
@Component({ @Component({
selector: 'redaction-virtual-scroll', selector: 'redaction-virtual-scroll',
@ -10,17 +10,57 @@ export class VirtualScrollComponent implements AfterViewInit {
@Input() targetQuerySelector = '.red-content'; @Input() targetQuerySelector = '.red-content';
@ViewChild('scrollElement') @ViewChild('scrollElement')
scrollElement: ElementRef; scrollElement: ElementRef;
@ViewChild('scroller')
scroller: ElementRef;
content: HTMLElement; content: HTMLElement;
height: number;
factor: number; factor: number;
height: number;
listener = () => {
console.log('adjust', this.content.scrollTop);
const top = Math.min(this.content.scrollTop * this.factor, this.scrollElement.nativeElement.clientHeight - this.height);
this.scroller.nativeElement.style.transform = 'translate3d(0px,' + top + 'px, 0px)';
};
constructor() {} constructor() {}
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.content = document.querySelector(this.targetQuerySelector); this.content = document.querySelector(this.targetQuerySelector);
this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight; this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight;
this.height = Math.round(this.content.scrollHeight / this.factor); const scrollFactor = this.content.scrollHeight / this.content.clientHeight;
console.log(this.factor, this.height); this.height = this.scrollElement.nativeElement.clientHeight / scrollFactor;
syncScroll([this.scrollElement.nativeElement, this.content]); this.content.addEventListener('scroll', this.listener);
}
scrollClicked($event: MouseEvent) {
console.log('clicked');
// half the scroll bar size - center pos ->
const top = Math.min(Math.max(0, $event.offsetY - this.height / 2), this.scrollElement.nativeElement.clientHeight - this.height);
this.scroller.nativeElement.style.transform = 'translate3d(0px,' + top + 'px, 0px)';
this.content.removeEventListener('scroll', this.listener);
this.content.scrollTop = top * this.factor;
console.log(this.content.scrollTop, top, this.factor);
this.content.addEventListener('scroll', this.listener);
}
released($event: CdkDragRelease) {
this.content.addEventListener('scroll', this.listener);
}
started($event: CdkDragStart) {
this.content.removeEventListener('scroll', this.listener);
}
moved($event: CdkDragMove<any>) {
console.log('moveded', this._getTop());
}
private _getTop() {
const translateY = this.scroller.nativeElement.style.transform
.split('translate3d')
.filter((t) => t.trim().length > 0)
.map((t) => t.split(',')[1].trim().replace('px', ''))
.map((t) => parseInt(t, 10))
.reduce((acc, el) => acc + el, 0);
this.content.scrollTop = translateY * this.factor;
} }
} }