mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
removing animation from lightbox + improving thumbnail rendering at lightbox
This commit is contained in:
parent
83d1d52813
commit
8e14c613ea
@ -1,8 +1,10 @@
|
||||
<gallery-lightbox #lightbox></gallery-lightbox>
|
||||
<gallery-lightbox #lightbox (onLastElement)="onLightboxLastElement()"></gallery-lightbox>
|
||||
<app-frame>
|
||||
|
||||
<div navbar>
|
||||
<gallery-search #search *ngIf="showSearchBar"></gallery-search>
|
||||
</div>
|
||||
|
||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.directory">
|
||||
<gallery-navbar [directory]="_galleryService.content.directory"></gallery-navbar>
|
||||
<gallery-directory *ngFor="let directory of _galleryService.content.directory.directories"
|
||||
|
@ -27,6 +27,7 @@ import {GalleryNavigatorComponent} from "./navigator/navigator.gallery.component
|
||||
export class GalleryComponent implements OnInit {
|
||||
|
||||
@ViewChild(GallerySearchComponent) search:GallerySearchComponent;
|
||||
@ViewChild(GalleryGridComponent) grid:GalleryGridComponent;
|
||||
|
||||
public showSearchBar:boolean = true;
|
||||
|
||||
@ -70,6 +71,10 @@ export class GalleryComponent implements OnInit {
|
||||
|
||||
}
|
||||
|
||||
onLightboxLastElement() {
|
||||
this.grid.renderARow();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {it, inject, beforeEachProviders} from "@angular/core/testing";
|
||||
import {it, inject, addProviders} from "@angular/core/testing";
|
||||
import {BaseRequestOptions, Http} from "@angular/http";
|
||||
import {MockBackend} from "@angular/http/testing";
|
||||
import {provide} from "@angular/core";
|
||||
@ -9,8 +9,8 @@ import {GalleryService} from "./gallery.service";
|
||||
|
||||
describe('GalleryService', () => {
|
||||
|
||||
|
||||
beforeEachProviders(() => [
|
||||
beforeEach(() => {
|
||||
addProviders([
|
||||
MockBackend,
|
||||
BaseRequestOptions,
|
||||
provide(Http, {
|
||||
@ -21,6 +21,8 @@ describe('GalleryService', () => {
|
||||
NetworkService,
|
||||
GalleryService
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
it('placeholder test', inject([], () => {
|
||||
|
@ -33,6 +33,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
@Input() lightbox:GalleryLightboxComponent;
|
||||
|
||||
photosToRender:Array<GridPhoto> = [];
|
||||
containerWidth:number = 0;
|
||||
|
||||
private IMAGE_MARGIN = 2;
|
||||
private TARGET_COL_COUNT = 5;
|
||||
@ -58,6 +59,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
if (this.isAfterViewInit === false) {
|
||||
return;
|
||||
}
|
||||
this.updateContainerWidth();
|
||||
this.sortPhotos();
|
||||
this.clearRenderedPhotos();
|
||||
setImmediate(() => {
|
||||
@ -73,7 +75,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
//TODO: implement scroll detection
|
||||
|
||||
|
||||
this.sortPhotos();
|
||||
this.updateContainerWidth();
|
||||
this.clearRenderedPhotos();
|
||||
setImmediate(() => {
|
||||
this.renderPhotos();
|
||||
@ -130,31 +132,15 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
private renderedPhotoIndex:number = 0;
|
||||
|
||||
private renderPhotos() {
|
||||
if (this.getContainerWidth() == 0 || this.renderedPhotoIndex >= this.photos.length || !this.shouldRenderMore()) {
|
||||
if (this.containerWidth == 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) === true) {
|
||||
|
||||
let photoRowBuilder = new GridRowBuilder(this.photos, this.renderedPhotoIndex, this.IMAGE_MARGIN, this.getContainerWidth());
|
||||
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT);
|
||||
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight);
|
||||
|
||||
let rowHeight = photoRowBuilder.calcRowHeight();
|
||||
let imageHeight = rowHeight - (this.IMAGE_MARGIN * 2);
|
||||
|
||||
photoRowBuilder.getPhotoRow().forEach((photo) => {
|
||||
let imageWidth = imageHeight * (photo.metadata.size.width / photo.metadata.size.height);
|
||||
this.photosToRender.push(new GridPhoto(photo, imageWidth, imageHeight, this.renderedPhotoIndex));
|
||||
});
|
||||
|
||||
renderedContentHeight += rowHeight;
|
||||
this.renderedPhotoIndex += photoRowBuilder.getPhotoRow().length;
|
||||
renderedContentHeight += this.renderARow();
|
||||
|
||||
}
|
||||
}
|
||||
@ -184,11 +170,33 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
private getContainerWidth():number {
|
||||
if (!this.gridContainer) {
|
||||
return 0;
|
||||
public renderARow():number {
|
||||
|
||||
let maxRowHeight = window.innerHeight / this.MIN_ROW_COUNT;
|
||||
let minRowHeight = window.innerHeight / this.MAX_ROW_COUNT;
|
||||
|
||||
let photoRowBuilder = new GridRowBuilder(this.photos, this.renderedPhotoIndex, this.IMAGE_MARGIN, this.containerWidth);
|
||||
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT);
|
||||
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight);
|
||||
|
||||
let rowHeight = photoRowBuilder.calcRowHeight();
|
||||
let imageHeight = rowHeight - (this.IMAGE_MARGIN * 2);
|
||||
|
||||
photoRowBuilder.getPhotoRow().forEach((photo) => {
|
||||
let imageWidth = imageHeight * (photo.metadata.size.width / photo.metadata.size.height);
|
||||
this.photosToRender.push(new GridPhoto(photo, imageWidth, imageHeight, this.renderedPhotoIndex));
|
||||
});
|
||||
|
||||
this.renderedPhotoIndex += photoRowBuilder.getPhotoRow().length;
|
||||
console.log(this.photosToRender.length);
|
||||
return rowHeight;
|
||||
}
|
||||
return this.gridContainer.nativeElement.clientWidth;
|
||||
|
||||
private updateContainerWidth():number {
|
||||
if (!this.gridContainer) {
|
||||
return;
|
||||
}
|
||||
this.containerWidth = this.gridContainer.nativeElement.clientWidth;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,16 +3,16 @@
|
||||
z-index: 1100; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 0; /* Full width */
|
||||
height: 0; /* Full height */
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: hidden;
|
||||
display: flex; /* add */
|
||||
justify-content: center; /* add to align horizontal */
|
||||
align-items: center; /* add to align vertical */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.blackCanvas{
|
||||
display: none;
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1099; /* Sit on top */
|
||||
left: 0;
|
||||
|
@ -1,10 +1,14 @@
|
||||
<div [hidden]="!activePhoto">
|
||||
|
||||
<div class="blackCanvas" #blackCanvas>
|
||||
<div class="blackCanvas">
|
||||
</div>
|
||||
|
||||
<div class="lightbox" #lightbox>
|
||||
<gallery-lightbox-photo #imgContainer [gridPhoto]="activePhoto ? activePhoto.gridPhoto : null">
|
||||
<div class="lightbox">
|
||||
<gallery-lightbox-photo [gridPhoto]="activePhoto ? activePhoto.gridPhoto : null"
|
||||
[style.top.px]="photoDimension.top"
|
||||
[style.left.px]="photoDimension.left"
|
||||
[style.width.px]="photoDimension.width"
|
||||
[style.height.px]="photoDimension.height">
|
||||
</gallery-lightbox-photo>
|
||||
</div>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
///<reference path="../../../browser.d.ts"/>
|
||||
|
||||
import {Component, ElementRef, ViewChild, QueryList} from "@angular/core";
|
||||
import {Component, QueryList, Output, EventEmitter} from "@angular/core";
|
||||
import {Photo} from "../../../../common/entities/Photo";
|
||||
import {GalleryPhotoComponent} from "../grid/photo/photo.grid.gallery.component.ts";
|
||||
import {BrowserDomAdapter} from "@angular/platform-browser/src/browser/browser_adapter";
|
||||
@ -14,15 +14,11 @@ import {GalleryLightboxPhotoComponent} from "./photo/photo.lightbox.gallery.comp
|
||||
directives: [GalleryLightboxPhotoComponent]
|
||||
})
|
||||
export class GalleryLightboxComponent {
|
||||
@Output('onLastElement') onLastElement = new EventEmitter();
|
||||
|
||||
@ViewChild('lightbox') lightBoxDiv:ElementRef;
|
||||
@ViewChild('blackCanvas') blackCanvasDiv:ElementRef;
|
||||
@ViewChild('controls') controlsDiv:ElementRef;
|
||||
@ViewChild('imgContainer') imgContainer:GalleryLightboxPhotoComponent;
|
||||
|
||||
|
||||
public imageSize = {width: "auto", height: "100"};
|
||||
public navigation = {hasPrev: true, hasNext: true};
|
||||
public photoDimension:Dimension = new Dimension(0, 0, 0, 0);
|
||||
|
||||
private activePhoto:GalleryPhotoComponent;
|
||||
public gridPhotoQL:QueryList<GalleryPhotoComponent>;
|
||||
|
||||
@ -42,20 +38,16 @@ export class GalleryLightboxComponent {
|
||||
if (pcList[i] === this.activePhoto && i + 1 < pcList.length) {
|
||||
this.activePhoto = pcList[i + 1];
|
||||
this.navigation.hasPrev = true;
|
||||
if (i + 2 < pcList.length) {
|
||||
this.navigation.hasNext = true;
|
||||
} else {
|
||||
this.navigation.hasNext = false;
|
||||
|
||||
this.navigation.hasNext = i + 2 < pcList.length;
|
||||
|
||||
if (i + 3 === pcList.length) {
|
||||
this.onLastElement.emit({}); //trigger to render more photos if there are
|
||||
}
|
||||
|
||||
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
|
||||
|
||||
this.forceAnimateFrom(toImage,
|
||||
{},
|
||||
this.imgContainer.nativeElement.nativeElement);
|
||||
this.photoDimension = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo);
|
||||
|
||||
|
||||
this.setImageSize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -67,33 +59,16 @@ export class GalleryLightboxComponent {
|
||||
if (pcList[i] === this.activePhoto && i > 0) {
|
||||
this.activePhoto = pcList[i - 1];
|
||||
this.navigation.hasNext = true;
|
||||
if (i - 1 > 0) {
|
||||
this.navigation.hasPrev = true;
|
||||
} else {
|
||||
this.navigation.hasPrev = false;
|
||||
}
|
||||
this.navigation.hasPrev = i - 1 > 0;
|
||||
|
||||
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
|
||||
this.photoDimension = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo);
|
||||
|
||||
this.forceAnimateFrom(toImage,
|
||||
{},
|
||||
this.imgContainer.nativeElement.nativeElement);
|
||||
|
||||
this.setImageSize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setImageSize() {
|
||||
if (this.activePhoto.gridPhoto.photo.metadata.size.height > this.activePhoto.gridPhoto.photo.metadata.size.width) {
|
||||
this.imageSize.height = "100";
|
||||
this.imageSize.width = null;
|
||||
} else {
|
||||
this.imageSize.height = null;
|
||||
this.imageSize.width = "100";
|
||||
}
|
||||
}
|
||||
|
||||
public show(photo:Photo) {
|
||||
let selectedPhoto = this.findPhotoComponent(photo);
|
||||
@ -103,73 +78,20 @@ export class GalleryLightboxComponent {
|
||||
|
||||
this.dom.setStyle(this.dom.query('body'), 'overflow', 'hidden');
|
||||
this.activePhoto = selectedPhoto;
|
||||
this.setImageSize();
|
||||
|
||||
|
||||
let from = this.activePhoto.getDimension();
|
||||
from.top -= this.getBodyScrollTop();
|
||||
|
||||
|
||||
let fromImage = {width: from.width + "px", height: from.height + "px", top: "0px", left: "0px"};
|
||||
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
|
||||
|
||||
this.forceAnimateFrom(fromImage,
|
||||
toImage,
|
||||
this.imgContainer.nativeElement.nativeElement);
|
||||
|
||||
this.forceAnimateFrom(from.toStyle(),
|
||||
{height: "100%", width: "100%", "top": "0px", "left": "0px"},
|
||||
this.lightBoxDiv.nativeElement);
|
||||
|
||||
|
||||
this.forceAnimateFrom({opacity: "0", display: "block"},
|
||||
{opacity: "1"},
|
||||
this.blackCanvasDiv.nativeElement);
|
||||
|
||||
this.forceAnimateFrom({opacity: "0", display: "block"},
|
||||
{opacity: "1"},
|
||||
this.controlsDiv.nativeElement);
|
||||
this.photoDimension = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo);
|
||||
|
||||
}
|
||||
|
||||
public hide() {
|
||||
console.log("hiding");
|
||||
let to = this.activePhoto.getDimension();
|
||||
|
||||
//iff target image out of screen -> scroll to there
|
||||
if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getScreenHeight() < to.top) {
|
||||
this.setBodyScrollTop(to.top);
|
||||
}
|
||||
to.top -= this.getBodyScrollTop();
|
||||
|
||||
|
||||
this.forceAnimateTo({height: "100%", width: "100%", "top": "0px", "left": "0px"},
|
||||
to.toStyle(),
|
||||
this.lightBoxDiv.nativeElement,
|
||||
{height: "0px", width: "0px", "top": "0px", "left": "0px"},
|
||||
()=> {
|
||||
this.activePhoto = null;
|
||||
});
|
||||
|
||||
this.dom.setStyle(this.dom.query('body'), 'overflow', 'auto');
|
||||
|
||||
this.forceAnimateTo({opacity: "1.0", display: "block"},
|
||||
{opacity: "0.0", display: "block"},
|
||||
this.blackCanvasDiv.nativeElement,
|
||||
{display: "none"});
|
||||
|
||||
this.forceAnimateTo({opacity: "1.0", display: "block"},
|
||||
{opacity: "0.0", display: "block"},
|
||||
this.controlsDiv.nativeElement,
|
||||
{display: "none"});
|
||||
|
||||
|
||||
let fromImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
|
||||
let toImage = {width: to.width + "px", height: to.height + "px", top: "0px", left: "0px"};
|
||||
|
||||
|
||||
this.forceAnimateTo(fromImage,
|
||||
toImage,
|
||||
this.imgContainer.nativeElement.nativeElement);
|
||||
this.activePhoto = null;
|
||||
|
||||
|
||||
}
|
||||
@ -186,39 +108,6 @@ export class GalleryLightboxComponent {
|
||||
return selectedPhoto;
|
||||
}
|
||||
|
||||
private forceAnimateFrom(from, to, elemnet) {
|
||||
/* let anim0 = this.animBuilder.css();
|
||||
anim0.setDuration(0);
|
||||
anim0.setToStyles(from);
|
||||
anim0.start(elemnet).onComplete(()=> {
|
||||
|
||||
let anim1 = this.animBuilder.css();
|
||||
anim1.setDuration(500);
|
||||
anim1.setFromStyles(from);
|
||||
anim1.setToStyles(to);
|
||||
anim1.start(elemnet);
|
||||
});*/
|
||||
}
|
||||
|
||||
private forceAnimateTo(from, to, elemnet, innerTo = null, onComplete = ()=> {
|
||||
}) {
|
||||
/* if (innerTo == null) {
|
||||
innerTo = to;
|
||||
}
|
||||
|
||||
let anim0 = this.animBuilder.css();
|
||||
anim0.setDuration(500);
|
||||
anim0.setFromStyles(from);
|
||||
anim0.setToStyles(to);
|
||||
anim0.start(elemnet).onComplete(()=> {
|
||||
let anim1 = this.animBuilder.css();
|
||||
anim1.setDuration(0);
|
||||
anim1.setToStyles(innerTo);
|
||||
anim1.start(elemnet).onComplete(onComplete);
|
||||
});*/
|
||||
onComplete();
|
||||
}
|
||||
|
||||
|
||||
private getBodyScrollTop() {
|
||||
return this.dom.getProperty(this.dom.query('body'), 'scrollTop');
|
||||
|
@ -1,13 +1,15 @@
|
||||
<div class="imgContainer" #imgContainer>
|
||||
<img *ngIf="gridPhoto"
|
||||
<img *ngIf="showThumbnail()"
|
||||
[style.width.%]="imageSize.width"
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="gridPhoto.getThumbnailPath()"/>
|
||||
[src]="thumbnailPath()"/>
|
||||
|
||||
<img *ngIf="gridPhoto"
|
||||
[style.width.%]="imageSize.width"
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="gridPhoto.getPhotoPath()"/>
|
||||
[src]="gridPhoto.getPhotoPath()"
|
||||
(load)="onImageLoad()"
|
||||
(error)="onImageError()"/>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -15,11 +15,14 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
public imageSize = {width: "auto", height: "100"};
|
||||
@ViewChild('imgContainer') nativeElement:ElementRef;
|
||||
|
||||
imageLoaded:boolean = false;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
|
||||
this.imageLoaded = false;
|
||||
this.setImageSize();
|
||||
}
|
||||
|
||||
@ -37,5 +40,29 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onImageLoad() {
|
||||
this.imageLoaded = true;
|
||||
}
|
||||
|
||||
onImageError() {
|
||||
//TODO:handle error
|
||||
console.error("cant load image");
|
||||
}
|
||||
|
||||
public showThumbnail():boolean {
|
||||
return this.gridPhoto && !this.imageLoaded &&
|
||||
(this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable());
|
||||
}
|
||||
|
||||
public thumbnailPath():string {
|
||||
if (this.gridPhoto.isThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getThumbnailPath();
|
||||
|
||||
if (this.gridPhoto.isReplacementThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getReplacementThumbnailPath();
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user