mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-23 01:27:14 +02:00
Adding circular progress bar to slideshow
This commit is contained in:
parent
3df1f43031
commit
64432799d5
@ -286,3 +286,9 @@ input[type="range"].zoom-progress::-moz-range-track {
|
|||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas{
|
||||||
|
right: 12px;
|
||||||
|
position: relative;
|
||||||
|
top: -34px;
|
||||||
|
}
|
||||||
|
@ -181,8 +181,13 @@
|
|||||||
class="oi oi-chevron-left"></span></div>
|
class="oi oi-chevron-left"></span></div>
|
||||||
<div [class.dim-controls]="controllersDimmed" class="navigation-arrow highlight"
|
<div [class.dim-controls]="controllersDimmed" class="navigation-arrow highlight"
|
||||||
*ngIf="navigation.hasNext && zoom == 1" title="key: right arrow" id="rightArrow" i18n-title
|
*ngIf="navigation.hasNext && zoom == 1" title="key: right arrow" id="rightArrow" i18n-title
|
||||||
(click)="nextPhoto.emit()"><span
|
(click)="nextMediaManuallyTriggered()">
|
||||||
class="oi oi-chevron-right"></span></div>
|
<span class="oi oi-chevron-right"></span>
|
||||||
|
<canvas
|
||||||
|
*ngIf="playBackState == PlayBackStates.Play"
|
||||||
|
#canvas width="55px" height="55px"></canvas>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div [class.dim-controls]="controllersDimmed" class="controls controls-zoom row" *ngIf="Zoom > 1">
|
<div [class.dim-controls]="controllersDimmed" class="controls controls-zoom row" *ngIf="Zoom > 1">
|
||||||
<div class="col-1 col-md-4">
|
<div class="col-1 col-md-4">
|
||||||
|
@ -1,32 +1,15 @@
|
|||||||
import {
|
import {Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, ViewChild,} from '@angular/core';
|
||||||
Component,
|
|
||||||
ElementRef,
|
|
||||||
EventEmitter,
|
|
||||||
HostListener,
|
|
||||||
Input,
|
|
||||||
OnChanges,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
|
||||||
Output,
|
|
||||||
ViewChild,
|
|
||||||
} from '@angular/core';
|
|
||||||
import {MediaDTOUtils} from '../../../../../../common/entities/MediaDTO';
|
import {MediaDTOUtils} from '../../../../../../common/entities/MediaDTO';
|
||||||
import {CookieNames} from '../../../../../../common/CookieNames';
|
|
||||||
import {FullScreenService} from '../../fullscreen.service';
|
import {FullScreenService} from '../../fullscreen.service';
|
||||||
import {GalleryPhotoComponent} from '../../grid/photo/photo.grid.gallery.component';
|
import {GalleryPhotoComponent} from '../../grid/photo/photo.grid.gallery.component';
|
||||||
import {Observable, Subscription, timer} from 'rxjs';
|
import {interval, Subscription} from 'rxjs';
|
||||||
import {filter} from 'rxjs/operators';
|
import {filter, skip} from 'rxjs/operators';
|
||||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||||
import {GalleryLightboxMediaComponent} from '../media/media.lightbox.gallery.component';
|
import {GalleryLightboxMediaComponent} from '../media/media.lightbox.gallery.component';
|
||||||
import {Config} from '../../../../../../common/config/public/Config';
|
import {Config} from '../../../../../../common/config/public/Config';
|
||||||
import {
|
import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes,} from '../../../../../../common/entities/SearchQueryDTO';
|
||||||
SearchQueryTypes,
|
|
||||||
TextSearch,
|
|
||||||
TextSearchQueryMatchTypes,
|
|
||||||
} from '../../../../../../common/entities/SearchQueryDTO';
|
|
||||||
import {AuthenticationService} from '../../../../model/network/authentication.service';
|
import {AuthenticationService} from '../../../../model/network/authentication.service';
|
||||||
import {LightboxService} from '../lightbox.service';
|
import {LightboxService} from '../lightbox.service';
|
||||||
import {CookieService} from 'ngx-cookie-service';
|
|
||||||
import {GalleryCacheService} from '../../cache.gallery.service';
|
import {GalleryCacheService} from '../../cache.gallery.service';
|
||||||
|
|
||||||
export enum PlayBackStates {
|
export enum PlayBackStates {
|
||||||
@ -41,6 +24,9 @@ export enum PlayBackStates {
|
|||||||
})
|
})
|
||||||
export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||||
readonly MAX_ZOOM = 10;
|
readonly MAX_ZOOM = 10;
|
||||||
|
@ViewChild('canvas')
|
||||||
|
canvas: ElementRef<HTMLCanvasElement>;
|
||||||
|
private ctx: CanvasRenderingContext2D;
|
||||||
|
|
||||||
@ViewChild('root', {static: false}) root: ElementRef;
|
@ViewChild('root', {static: false}) root: ElementRef;
|
||||||
@Output() closed = new EventEmitter();
|
@Output() closed = new EventEmitter();
|
||||||
@ -70,7 +56,6 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
public searchEnabled: boolean;
|
public searchEnabled: boolean;
|
||||||
|
|
||||||
private visibilityTimer: number = null;
|
private visibilityTimer: number = null;
|
||||||
private timer: Observable<number>;
|
|
||||||
private timerSub: Subscription;
|
private timerSub: Subscription;
|
||||||
private prevDrag = {x: 0, y: 0};
|
private prevDrag = {x: 0, y: 0};
|
||||||
private prevZoom = 1;
|
private prevZoom = 1;
|
||||||
@ -125,7 +110,6 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.timer = timer(1000, 1000);
|
|
||||||
if (this.cacheService.getSlideshowSpeed()) {
|
if (this.cacheService.getSlideshowSpeed()) {
|
||||||
this.selectedSlideshowSpeed = this.cacheService.getSlideshowSpeed();
|
this.selectedSlideshowSpeed = this.cacheService.getSlideshowSpeed();
|
||||||
} else {
|
} else {
|
||||||
@ -234,7 +218,7 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
break;
|
break;
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
if (this.navigation.hasNext) {
|
if (this.navigation.hasNext) {
|
||||||
this.nextPhoto.emit();
|
this.nextMediaManuallyTriggered();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
@ -302,10 +286,47 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
this.nextPhoto.emit();
|
this.nextPhoto.emit();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private drawSliderProgress(t: number) {
|
||||||
|
let p = 0;
|
||||||
|
|
||||||
|
// Video is a special snowflake. It won't go to next media if a video is playing
|
||||||
|
if (!(this.activePhoto &&
|
||||||
|
this.activePhoto.gridMedia.isVideo() &&
|
||||||
|
!this.mediaElement.Paused)) {
|
||||||
|
p = (t % (this.selectedSlideshowSpeed * 10)) / this.selectedSlideshowSpeed / 10; // ticks every 100 ms
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!this.canvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.ctx) {
|
||||||
|
this.ctx = this.canvas.nativeElement.getContext('2d');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ctx.lineWidth = 5;
|
||||||
|
this.ctx.strokeStyle = 'white';
|
||||||
|
this.ctx.clearRect(0, 0, this.canvas.nativeElement.width, this.canvas.nativeElement.height);
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(this.canvas.nativeElement.width / 2, this.canvas.nativeElement.height / 2, this.canvas.nativeElement.width / 2 - this.ctx.lineWidth, 0, p * 2 * Math.PI);
|
||||||
|
|
||||||
|
this.ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
resetSlideshowTimer(): void {
|
||||||
|
if (this.playBackState == PlayBackStates.Play) {
|
||||||
|
this.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public play(): void {
|
public play(): void {
|
||||||
this.pause();
|
this.pause();
|
||||||
this.timerSub = this.timer
|
this.drawSliderProgress(0);
|
||||||
.pipe(filter((t) => t % this.selectedSlideshowSpeed === 0))
|
this.timerSub = interval(100)
|
||||||
|
.pipe(filter((t) => {
|
||||||
|
this.drawSliderProgress(t);
|
||||||
|
return t % (this.selectedSlideshowSpeed * 10) === 0; // ticks every 100 ms
|
||||||
|
}))
|
||||||
|
.pipe(skip(1)) // do not skip to next photo right away
|
||||||
.subscribe(this.showNextMedia);
|
.subscribe(this.showNextMedia);
|
||||||
this.playBackState = PlayBackStates.Play;
|
this.playBackState = PlayBackStates.Play;
|
||||||
}
|
}
|
||||||
@ -323,6 +344,7 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
if (this.timerSub != null) {
|
if (this.timerSub != null) {
|
||||||
this.timerSub.unsubscribe();
|
this.timerSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
this.ctx = null;
|
||||||
this.playBackState = PlayBackStates.Paused;
|
this.playBackState = PlayBackStates.Paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +433,7 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private hideControls = () => {
|
private hideControls = () => {
|
||||||
this.controllersDimmed = true;
|
// this.controllersDimmed = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
private updateFaceContainerDim(): void {
|
private updateFaceContainerDim(): void {
|
||||||
@ -431,5 +453,11 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
|||||||
this.faceContainerDim.width = this.photoFrameDim.width;
|
this.faceContainerDim.width = this.photoFrameDim.width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextMediaManuallyTriggered() {
|
||||||
|
this.resetSlideshowTimer();
|
||||||
|
this.nextPhoto.emit();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user