1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-01-26 05:27:35 +02:00

Implementing next photo preloading

#134

Also fixing play button animation.
This commit is contained in:
Patrik J. Braun 2022-06-26 09:56:13 +02:00
parent d0b609b416
commit c06620a795
6 changed files with 124 additions and 74 deletions

View File

@ -154,6 +154,21 @@
opacity: 1.0;
}
@keyframes blink {
0% {
opacity: 0.5;
}
25% {
opacity: 1.0;
}
75% {
opacity: 1.0;
}
100% {
opacity: 0.5;
}
}
@-webkit-keyframes blink {
0% {
opacity: 0.5;

View File

@ -257,12 +257,9 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
}
}
public play(): void {
this.pause();
this.timerSub = this.timer
.pipe(filter((t) => t % 2 === 0))
.subscribe(() => {
if (this.mediaElement.imageLoadFinished === false) {
private showNextMedia = () => {
if (this.mediaElement.imageLoadFinished.this === false ||
this.mediaElement.imageLoadFinished.next === false) {
return;
}
// do not skip video if its playing
@ -274,25 +271,19 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
return;
}
this.nextPhoto.emit();
});
};
public play(): void {
this.pause();
this.timerSub = this.timer
.pipe(filter((t) => t % 2 === 0))
.subscribe(this.showNextMedia);
this.playBackState = PlayBackStates.Play;
}
public fastForward(): void {
this.pause();
this.timerSub = this.timer.subscribe(() => {
if (this.mediaElement.imageLoadFinished === false) {
return;
}
if (
this.activePhoto &&
this.activePhoto.gridMedia.isVideo() &&
!this.mediaElement.Paused
) {
return;
}
this.nextPhoto.emit();
});
this.timerSub = this.timer.subscribe(this.showNextMedia);
this.playBackState = PlayBackStates.FastForward;
}

View File

@ -6,6 +6,7 @@
<div class="lightbox" #lightbox>
<app-gallery-lightbox-media [gridMedia]="activePhoto ? activePhoto.gridMedia : null"
[nextGridMedia]="NexGridMedia"
[loadMedia]="!animating"
[zoom]="controls ? controls.Zoom : 1"
[drag]="controls ? controls.drag : {x:0,y:0}"

View File

@ -15,6 +15,7 @@ import {ContentService} from '../content.service';
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {ControlsLightboxComponent} from './controls/controls.lightbox.gallery.component';
import {SupportedFormats} from '../../../../../common/SupportedFormats';
import {GridMedia} from '../grid/GridMedia';
export enum LightboxStates {
Open = 1,
@ -389,7 +390,7 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
this.router
.navigate([], {
queryParams: this.queryService.getParams(
this.gridPhotoQL.toArray()[photoIndex].gridMedia.media
this.gridPhotoQL.get(photoIndex).gridMedia.media
),
})
.catch(console.error);
@ -440,14 +441,12 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
}
private updateActivePhoto(photoIndex: number, resize = true): void {
const pcList = this.gridPhotoQL.toArray();
if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) {
throw new Error('Can\'t find the media');
}
this.videoSourceError = false;
this.activePhotoId = photoIndex;
this.activePhoto = pcList[photoIndex];
this.activePhoto = this.gridPhotoQL.get(photoIndex);
if (resize) {
this.animatePhoto(
@ -455,7 +454,7 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
);
}
this.navigation.hasPrev = photoIndex > 0;
this.navigation.hasNext = photoIndex + 1 < pcList.length;
this.navigation.hasNext = photoIndex + 1 < this.gridPhotoQL.length;
const to = this.activePhoto.getDimension();
@ -501,5 +500,12 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
return {top, left, width, height} as Dimension;
}
get NexGridMedia(): GridMedia {
if (this.activePhotoId + 1 < this.gridPhotoQL?.length) {
return this.gridPhotoQL.get(this.activePhotoId + 1)?.gridMedia;
}
return null;
}
}

View File

@ -22,7 +22,7 @@
(error)="onImageError()"
(timeupdate)="onVideoProgress()"
#video>
<source [src]="gridMedia.getBestFitMediaPath()" (error)="onSourceError($event)">
<source [src]="gridMedia.getBestFitMediaPath()" (error)="onSourceError()">
Something went wrong.
</video>

View File

@ -20,7 +20,8 @@ import { Config } from '../../../../../../common/config/public/Config';
})
export class GalleryLightboxMediaComponent implements OnChanges {
@Input() gridMedia: GridMedia;
@Input() loadMedia = false;
@Input() nextGridMedia: GridMedia;
@Input() loadMedia = false; // prevents loading media
@Input() windowAspect = 1;
@Input() zoom = 1;
@Input() drag = {x: 0, y: 0};
@ -31,17 +32,24 @@ export class GalleryLightboxMediaComponent implements OnChanges {
prevGirdPhoto: GridMedia = null;
public imageSize = {width: 'auto', height: '100'};
public imageLoadFinished = false;
private nextImage = new Image();
// do not skip to the next photo if not both are loaded (or resulted in an error)
public imageLoadFinished = {
this: false,
next: false
};
thumbnailSrc: string = null;
photo = {
src: null as string,
isBestFit: null as boolean,
};
public transcodeNeedVideos = SupportedFormats.TranscodeNeed.Videos;
// if media not loaded, show thumbnail
private mediaLoaded = false;
private videoProgress = 0;
constructor(public elementRef: ElementRef, private sanitizer: DomSanitizer) {}
constructor(public elementRef: ElementRef, private sanitizer: DomSanitizer) {
}
get ImageTransform(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle(
@ -120,8 +128,12 @@ export class GalleryLightboxMediaComponent implements OnChanges {
this.prevGirdPhoto = this.gridMedia;
this.thumbnailSrc = null;
this.photo.src = null;
this.nextImage.src = "";
this.mediaLoaded = false;
this.imageLoadFinished = false;
this.imageLoadFinished = {
this: false,
next: false
};
}
this.setImageSize();
if (
@ -156,16 +168,18 @@ export class GalleryLightboxMediaComponent implements OnChanges {
onImageError(): void {
// TODO:handle error
this.imageLoadFinished = true;
this.imageLoadFinished.this = true;
console.error(
'Error: cannot load media for lightbox url: ' +
this.gridMedia.getBestFitMediaPath()
);
this.loadNextPhoto();
}
onImageLoad(): void {
this.imageLoadFinished = true;
this.imageLoadFinished.this = true;
this.mediaLoaded = true;
this.loadNextPhoto();
}
public showThumbnail(): boolean {
@ -178,11 +192,34 @@ export class GalleryLightboxMediaComponent implements OnChanges {
);
}
onSourceError($event: any): void {
onSourceError(): void {
this.mediaLoaded = false;
this.videoSourceError.emit();
}
/**
* Loads next photo to faster show it on navigation.
* Called after the current photo is loaded
* @private
*/
private loadNextPhoto(): void {
if (!this.nextGridMedia || !this.loadMedia) {
return;
}
// Videos do not support preloading
if (!this.nextGridMedia.isPhoto()) {
this.imageLoadFinished.next = true;
return;
}
if (Config.Client.Media.Photo.Converting.enabled === true) {
this.nextImage.src = this.nextGridMedia.getBestFitMediaPath();
} else {
this.nextImage.src = this.nextGridMedia.getMediaPath();
}
this.nextImage.onload = () => this.imageLoadFinished.next = true;
}
private loadPhoto(): void {
if (!this.gridMedia || !this.loadMedia || !this.gridMedia.isPhoto()) {
return;