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 { ScrollingModule } from '@angular/cdk/scrolling';
import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -237,7 +238,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
MatCheckboxModule,
MatListModule,
MatDatepickerModule,
MatInputModule
MatInputModule,
DragDropModule
],
providers: [
{

View File

@ -1,3 +1,13 @@
<div class="virtual-scroll" #scrollElement>
<div class="virtual" [style.height]="height + 'px'"></div>
<div class="virtual-scroll" #scrollElement (click)="scrollClicked($event)">
<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>

View File

@ -1,6 +1,7 @@
@import '../../../assets/styles/red-variables';
.virtual-scroll {
// TODO fix this - pass information as input or such
display: none;
position: fixed;
width: 10px;
right: 480px;
@ -8,8 +9,17 @@
z-index: 100;
top: 191px;
overflow: auto;
background: $grey-6;
.virtual {
height: 2000px;
.scroller {
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 { syncScroll } from '../sync-scroll';
import { CdkDragMove, CdkDragRelease, CdkDragStart } from '@angular/cdk/drag-drop';
@Component({
selector: 'redaction-virtual-scroll',
@ -10,17 +10,57 @@ export class VirtualScrollComponent implements AfterViewInit {
@Input() targetQuerySelector = '.red-content';
@ViewChild('scrollElement')
scrollElement: ElementRef;
@ViewChild('scroller')
scroller: ElementRef;
content: HTMLElement;
height: 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() {}
ngAfterViewInit(): void {
this.content = document.querySelector(this.targetQuerySelector);
this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight;
this.height = Math.round(this.content.scrollHeight / this.factor);
console.log(this.factor, this.height);
syncScroll([this.scrollElement.nativeElement, this.content]);
const scrollFactor = this.content.scrollHeight / this.content.clientHeight;
this.height = this.scrollElement.nativeElement.clientHeight / scrollFactor;
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;
}
}