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:
parent
54636ac290
commit
a874c7d70f
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user