1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

implementing advanced grid rendering (on scroll render more images)

fixing slow image load
This commit is contained in:
Braun Patrik 2016-06-25 10:09:05 +02:00
parent 54636ac290
commit a874c7d70f
3 changed files with 61 additions and 49 deletions

View File

@ -8,7 +8,8 @@ import {
ViewChild,
ViewChildren,
QueryList,
AfterViewInit
AfterViewInit,
HostListener
} from "@angular/core";
import {Photo} from "../../../../common/entities/Photo";
import {GridRowBuilder} from "./GridRowBuilder";
@ -41,56 +42,24 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
}
ngOnChanges() {
this.renderPhotos();
this.onPhotosChanged();
}
onResize() {
this.renderPhotos();
this.onPhotosChanged();
}
ngAfterViewInit() {
this.lightbox.gridPhotoQL = this.gridPhotoQL;
//TODO: implement scroll detection
/* this.gridPhotoQL.changes.subscribe(
(x)=> {
console.log("changed");
if (!this.directory || this.gridPhotoQL.length < this.directory.photos.length) {
console.log("bad");
console.log(this.directory ? this.gridPhotoQL.length + " < "+this.directory.photos.length : "no dir");
return;
}
if (this.renderedContainerWidth != this.getContainerWidth()) {
this.renderPhotos();
}
},
(err) => {
console.log('Error: %s', err);
},
() =>{
console.log('Completed');
}
); */
setImmediate(() => {
this.renderPhotos();
});
this.onPhotosChanged();
}
private renderedContainerWidth = 0;
private renderPhotos() {
if (this.getContainerWidth() == 0) {
return;
}
let maxRowHeight = window.innerHeight / this.MIN_ROW_COUNT;
let minRowHeight = window.innerHeight / this.MAX_ROW_COUNT;
let containerWidth = this.getContainerWidth();
this.renderedContainerWidth = containerWidth;
private onPhotosChanged() {
this.photos.sort((a:Photo, b:Photo) => {
if (a.metadata.creationDate > b.metadata.creationDate) {
return 1;
@ -101,13 +70,28 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
// a must be equal to b
return 0;
});
this.photosToRender = [];
let i = 0;
this.renderedPhotoIndex = 0;
setImmediate(() => {
this.renderPhotos();
});
}
while (i < this.photos.length) {
private renderedPhotoIndex:number = 0;
let photoRowBuilder = new GridRowBuilder(this.photos, i, this.IMAGE_MARGIN, containerWidth);
private renderPhotos() {
if (this.getContainerWidth() == 0 || this.renderedPhotoIndex >= this.photos.length || !this.shouldRenderMore()) {
return;
}
let maxRowHeight = window.innerHeight / this.MIN_ROW_COUNT;
let minRowHeight = window.innerHeight / this.MAX_ROW_COUNT;
let renderedContentHeight = 0;
while (this.renderedPhotoIndex < this.photos.length && this.shouldRenderMore(renderedContentHeight)) {
let photoRowBuilder = new GridRowBuilder(this.photos, this.renderedPhotoIndex, this.IMAGE_MARGIN, this.getContainerWidth());
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT);
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight);
@ -119,11 +103,24 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
this.photosToRender.push(new GridPhoto(photo, imageWidth, imageHeight));
});
i += photoRowBuilder.getPhotoRow().length;
renderedContentHeight += rowHeight;
this.renderedPhotoIndex += photoRowBuilder.getPhotoRow().length;
}
}
private shouldRenderMore(offset:number = 0):boolean {
return document.body.scrollTop >= (document.body.clientHeight + offset - window.innerHeight) * 0.7
|| document.body.clientHeight + offset < window.innerHeight;
}
@HostListener('window:scroll')
onScroll() {
this.renderPhotos();
}
private getContainerWidth():number {
if (!this.gridContainer) {
return 0;

View File

@ -1,5 +1,5 @@
<div #photoContainer class="photo-container" (mouseover)="hover()" (mouseout)="mouseOut()">
<img #img [src]="image.src" [hidden]="!image.show">
<img #img [src]="image.src" [hidden]="!image.show || loading.show" (load)="onImageLoad()">
<gallery-grid-photo-loading [animate]="loading.animate" *ngIf="loading.show">
</gallery-grid-photo-loading>

View File

@ -1,6 +1,6 @@
///<reference path="../../../../browser.d.ts"/>
import {Component, Input, ElementRef, ViewChild, OnInit, AfterViewInit, OnDestroy, HostListener} from "@angular/core";
import {Component, Input, ElementRef, ViewChild, OnInit, AfterViewInit, OnDestroy, Renderer} from "@angular/core";
import {IRenderable, Dimension} from "../../../model/IRenderable";
import {GridPhoto} from "../GridPhoto";
import {SearchTypes} from "../../../../../common/entities/AutoCompleteItem";
@ -34,7 +34,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
loading = {
animate: false,
show: false
show: true
};
thumbnailTask:ThumbnailTaskEntity = null;
@ -47,9 +47,13 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
SearchTypes:any = [];
searchEnabled:boolean = true;
constructor(private thumbnailService:ThumbnailLoaderService) {
scrollListener = null;
constructor(private thumbnailService:ThumbnailLoaderService, private renderer:Renderer) {
this.SearchTypes = SearchTypes;
this.searchEnabled = Config.Client.Search.searchEnabled;
}
ngOnInit() {
@ -57,7 +61,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
if (this.gridPhoto.isThumbnailAvailable()) {
this.image.src = this.gridPhoto.getThumbnailPath();
this.image.show = true;
this.loading.show = false;
// this.loading.show = false;
} else {
if (this.gridPhoto.isReplacementThumbnailAvailable()) {
@ -84,15 +88,23 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
this.image.show = true;
this.loading.show = false;
this.thumbnailTask = null;
if (this.scrollListener) {
this.scrollListener();
}
},
onError: (error)=> {//onError
this.thumbnailTask = null;
if (this.scrollListener) {
this.scrollListener();
}
//TODO: handle error
console.error("something bad happened");
console.error(error);
}
};
this.scrollListener = this.renderer.listenGlobal('window', 'scroll', () => {
this.onScroll();
});
if (this.gridPhoto.isReplacementThumbnailAvailable()) {
this.thumbnailTask = this.thumbnailService.loadImage(this.gridPhoto, ThumbnailLoadingPriority.medium, listener);
} else {
@ -117,7 +129,6 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
&& document.body.scrollTop + window.innerHeight > this.container.nativeElement.offsetTop;
}
@HostListener('window:scroll')
onScroll() {
if (this.thumbnailTask != null) {
if (this.isInView() == true) {
@ -157,6 +168,10 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, AfterViewInit
}
onImageLoad() {
this.loading.show = false;
}
public getDimension():Dimension {
return new Dimension(this.imageRef.nativeElement.offsetTop,
this.imageRef.nativeElement.offsetLeft,