1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/frontend/app/gallery/map/lightbox/lightbox.map.gallery.component.ts

260 lines
7.3 KiB
TypeScript
Raw Normal View History

2018-05-28 00:04:35 +08:00
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild, AfterViewInit} from '@angular/core';
2018-03-31 03:30:30 +08:00
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {Dimension} from '../../../model/IRenderable';
import {FullScreenService} from '../../fullscreen.service';
2018-12-09 01:17:33 +08:00
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../thumbnailManager.service';
2018-11-05 02:28:32 +08:00
import {MediaIcon} from '../../MediaIcon';
import {Media} from '../../Media';
2018-05-10 01:56:02 +08:00
import {PageHelper} from '../../../model/page.helper';
2018-11-02 17:40:09 +08:00
import {OrientationTypes} from 'ts-exif-parser';
2018-11-05 02:28:32 +08:00
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
2018-11-26 07:26:29 +08:00
import {FileDTO} from '../../../../../common/entities/FileDTO';
import {Utils} from '../../../../../common/Utils';
import {Config} from '../../../../../common/config/public/Config';
import {MapService} from '../map.service';
import {LatLng, Point} from 'leaflet';
import {MapComponent} from '@yaga/leaflet-ng2';
import {FixOrientationPipe} from '../../FixOrientationPipe';
2018-05-28 00:04:35 +08:00
2017-02-06 00:27:58 +08:00
@Component({
2018-05-04 07:17:08 +08:00
selector: 'app-gallery-map-lightbox',
styleUrls: ['./lightbox.map.gallery.component.css'],
templateUrl: './lightbox.map.gallery.component.html',
2017-02-06 00:27:58 +08:00
})
2018-05-28 00:04:35 +08:00
export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
2017-02-06 00:27:58 +08:00
2018-11-26 07:26:29 +08:00
@Input() photos: PhotoDTO[];
@Input() gpxFiles: FileDTO[];
2018-11-29 06:49:33 +08:00
private startPosition: Dimension = null;
public lightboxDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
public mapDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
public visible = false;
2018-05-28 00:04:35 +08:00
public controllersVisible = false;
public opacity = 1.0;
2017-07-21 02:07:19 +08:00
mapPhotos: MapPhoto[] = [];
paths: LatLng[][] = [];
2017-02-06 00:27:58 +08:00
2018-03-31 03:30:30 +08:00
@ViewChild('root') elementRef: ElementRef;
@ViewChild('yagaMap') yagaMap: MapComponent;
2017-02-06 00:27:58 +08:00
public smallIconSize = new Point(Config.Client.Thumbnail.iconSize * 0.75, Config.Client.Thumbnail.iconSize * 0.75);
public iconSize = new Point(Config.Client.Thumbnail.iconSize, Config.Client.Thumbnail.iconSize);
2017-02-06 00:27:58 +08:00
2017-07-24 04:36:53 +08:00
constructor(public fullScreenService: FullScreenService,
2018-05-28 00:04:35 +08:00
private thumbnailService: ThumbnailManagerService,
public mapService: MapService) {
}
2017-02-06 00:27:58 +08:00
ngOnChanges() {
2018-05-04 07:17:08 +08:00
if (this.visible === false) {
return;
2017-02-06 00:27:58 +08:00
}
this.showImages();
}
2018-05-28 00:04:35 +08:00
ngAfterViewInit() {
}
@HostListener('window:resize', ['$event'])
async onResize() {
this.lightboxDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
this.mapDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
await Utils.wait(0);
this.yagaMap.invalidateSize();
}
public async show(position: Dimension) {
2017-07-25 22:13:21 +08:00
this.hideImages();
this.visible = true;
this.opacity = 1.0;
this.startPosition = position;
this.lightboxDimension = position;
2018-05-27 09:47:39 +08:00
this.lightboxDimension.top -= PageHelper.ScrollY;
this.mapDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
this.showImages();
this.centerMap();
2018-05-10 01:56:02 +08:00
PageHelper.hideScrollY();
await Utils.wait(0);
this.lightboxDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
await Utils.wait(350);
this.yagaMap.invalidateSize();
this.centerMap();
this.controllersVisible = true;
}
public hide() {
this.fullScreenService.exitFullScreen();
2018-05-28 00:04:35 +08:00
this.controllersVisible = false;
2018-05-04 07:17:08 +08:00
const to = this.startPosition;
2018-05-04 07:17:08 +08:00
// iff target image out of screen -> scroll to there
2018-05-27 09:47:39 +08:00
if (PageHelper.ScrollY > to.top || PageHelper.ScrollY + this.getScreenHeight() < to.top) {
PageHelper.ScrollY = to.top;
2017-02-06 00:27:58 +08:00
}
this.lightboxDimension = this.startPosition;
2018-05-27 09:47:39 +08:00
this.lightboxDimension.top -= PageHelper.ScrollY;
2018-05-10 01:56:02 +08:00
PageHelper.showScrollY();
this.opacity = 0.0;
setTimeout(() => {
this.visible = false;
this.hideImages();
this.yagaMap.zoom = 2;
}, 500);
}
showImages() {
this.hideImages();
this.mapPhotos = this.photos.filter(p => {
2018-05-28 00:04:35 +08:00
return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData
&& p.metadata.positionData.GPSData.latitude
&& p.metadata.positionData.GPSData.longitude;
}).map(p => {
2017-07-21 02:07:19 +08:00
let width = 500;
let height = 500;
2018-11-05 02:28:32 +08:00
const rotatedSize = MediaDTO.getRotatedSize(p);
2018-11-02 18:44:13 +08:00
if (rotatedSize.width > rotatedSize.height) {
height = width * (rotatedSize.height / rotatedSize.width);
2017-07-21 02:07:19 +08:00
} else {
2018-11-02 18:44:13 +08:00
width = height * (rotatedSize.width / rotatedSize.height);
2017-07-21 02:07:19 +08:00
}
2018-11-05 02:28:32 +08:00
const iconTh = this.thumbnailService.getIcon(new MediaIcon(p));
2017-07-24 04:36:53 +08:00
iconTh.Visible = true;
2017-07-21 02:07:19 +08:00
const obj: MapPhoto = {
lat: p.metadata.positionData.GPSData.latitude,
lng: p.metadata.positionData.GPSData.longitude,
2017-07-21 02:07:19 +08:00
iconThumbnail: iconTh,
2018-11-02 17:40:09 +08:00
orientation: p.metadata.orientation,
2017-07-21 02:07:19 +08:00
preview: {
width: width,
height: height,
2018-11-05 02:28:32 +08:00
thumbnail: this.thumbnailService.getLazyThumbnail(new Media(p, width, height))
2017-07-21 02:07:19 +08:00
}
};
2018-05-04 07:17:08 +08:00
if (iconTh.Available === true) {
FixOrientationPipe.transform(iconTh.Src, p.metadata.orientation).then((icon) => {
obj.iconUrl = icon;
});
} else {
2017-07-21 02:07:19 +08:00
iconTh.OnLoad = () => {
FixOrientationPipe.transform(iconTh.Src, p.metadata.orientation).then((icon) => {
obj.iconUrl = icon;
});
};
}
return obj;
});
2018-11-26 07:26:29 +08:00
if (this.gpxFiles) {
this.loadGPXFiles().catch(console.error);
}
}
private centerMap() {
if (this.mapPhotos.length > 0) {
this.yagaMap.fitBounds(<any>this.mapPhotos);
2018-11-27 00:14:58 +08:00
}
}
2018-11-26 07:26:29 +08:00
private async loadGPXFiles(): Promise<void> {
this.paths = [];
for (let i = 0; i < this.gpxFiles.length; i++) {
const file = this.gpxFiles[i];
const path = await this.mapService.getMapPath(file);
if (file !== this.gpxFiles[i]) { // check race condition
return;
}
2018-11-27 00:14:58 +08:00
if (path.length === 0) {
continue;
}
this.paths.push(<LatLng[]>path);
2018-11-26 07:26:29 +08:00
}
}
2017-02-06 00:27:58 +08:00
2017-07-25 22:13:21 +08:00
2017-07-24 04:36:53 +08:00
public loadPreview(mp: MapPhoto) {
mp.preview.thumbnail.load();
2017-07-26 05:40:07 +08:00
mp.preview.thumbnail.CurrentlyWaiting = true;
2017-07-24 04:36:53 +08:00
}
hideImages() {
2017-07-24 04:36:53 +08:00
this.mapPhotos.forEach((mp) => {
mp.iconThumbnail.destroy();
mp.preview.thumbnail.destroy();
});
this.mapPhotos = [];
}
2017-03-20 07:01:41 +08:00
private getScreenWidth() {
return window.innerWidth;
}
2017-02-06 00:27:58 +08:00
private getScreenHeight() {
return window.innerHeight;
}
2017-02-06 00:27:58 +08:00
@HostListener('window:keydown', ['$event'])
onKeyPress(e: KeyboardEvent) {
2018-05-04 07:17:08 +08:00
if (this.visible !== true) {
return;
2017-02-06 00:27:58 +08:00
}
2018-05-04 07:17:08 +08:00
const event: KeyboardEvent = window.event ? <any>window.event : e;
switch (event.key) {
case 'f':
case 'F':
if (this.fullScreenService.isFullScreenEnabled()) {
this.fullScreenService.exitFullScreen();
} else {
this.fullScreenService.showFullScreen(this.elementRef.nativeElement);
}
break;
case 'Escape': // escape
this.hide();
break;
}
}
2017-02-06 00:27:58 +08:00
}
2017-07-21 02:07:19 +08:00
export interface MapPhoto {
lat: number;
lng: number;
2017-07-21 02:07:19 +08:00
iconUrl?: string;
iconThumbnail: IconThumbnail;
2018-11-02 17:40:09 +08:00
orientation: OrientationTypes;
2017-07-21 02:07:19 +08:00
preview: {
width: number;
height: number;
2017-07-24 04:36:53 +08:00
thumbnail: Thumbnail;
2018-05-04 07:17:08 +08:00
};
2017-07-21 02:07:19 +08:00
}