map performance improvement

This commit is contained in:
Patrik Braun 2017-07-23 22:36:53 +02:00
parent 116fd6328b
commit 1537efb5b5
5 changed files with 81 additions and 47 deletions

View File

@ -1,5 +1,5 @@
<div class="static" *ngIf="animate == false"> <div class="static" *ngIf="animate == false">
<span class="glyphicon glyphicon-picture" <span class="glyphicon"
[ngClass]="error ? 'glyphicon-warning-sign' : 'glyphicon-picture'" aria-hidden="true"> [ngClass]="error ? 'glyphicon-warning-sign' : 'glyphicon-picture'" aria-hidden="true">
</span> </span>
</div> </div>

View File

@ -63,3 +63,14 @@
.highlight:hover { .highlight:hover {
opacity: 1.0; opacity: 1.0;
} }
.preview-loading {
background-color: #bbbbbb;
color: #7f7f7f;
font-size: 50px;
}
.preview-loading span {
top: calc(50% - 25px);
left: calc(50% - 25px);
}

View File

@ -1,49 +1,60 @@
<div [hidden]="!visible" #root> <div [hidden]="!visible" #root>
<div class="lightbox" <div class="lightbox"
[style.width.px]="lightboxDimension.width" [style.width.px]="lightboxDimension.width"
[style.height.px]="lightboxDimension.height" [style.height.px]="lightboxDimension.height"
[style.top.px]="lightboxDimension.top" [style.top.px]="lightboxDimension.top"
[style.left.px]="lightboxDimension.left" [style.left.px]="lightboxDimension.left"
[style.opacity]="opacity"> [style.opacity]="opacity">
<agm-map <agm-map
[style.width.px]="mapDimension.width" [style.width.px]="mapDimension.width"
[style.height.px]="mapDimension.height" [style.height.px]="mapDimension.height"
[zoom]="5" [zoom]="5"
[latitude]="mapCenter.latitude" [latitude]="mapCenter.latitude"
[longitude]="mapCenter.longitude"> [longitude]="mapCenter.longitude">
<agm-marker <agm-marker
*ngFor="let photo of mapPhotos" *ngFor="let photo of mapPhotos"
[latitude]="photo.latitude" [latitude]="photo.latitude"
[longitude]="photo.longitude" [longitude]="photo.longitude"
[iconUrl]="photo.iconUrl"> [iconUrl]="photo.iconUrl"
<agm-info-window> (markerClick)="loadPreview(photo)">
<img [style.width.px]="photo.preview.width" <agm-info-window>
[style.height.px]="photo.preview.height" <img *ngIf="photo.preview.thumbnail.Src"
[src]="photo.preview.url"> [style.width.px]="photo.preview.width"
</agm-info-window> [style.height.px]="photo.preview.height"
</agm-marker> [src]="photo.preview.thumbnail.Src">
</agm-map> <div class="preview-loading"
</div> [style.width.px]="photo.preview.width"
[style.height.px]="photo.preview.height"
*ngIf="!photo.preview.thumbnail.Src">
<span class="glyphicon"
[ngClass]="photo.preview.thumbnail.Error ? 'glyphicon-warning-sign' : 'glyphicon-picture'"
aria-hidden="true">
</span>
</div>
</agm-info-window>
</agm-marker>
</agm-map>
</div>
<div id="controllers-container" #controls> <div id="controllers-container" *ngIf="visible">
<div id="controls"> <div id="controls">
<span> <span>
<span class=" glyphicon glyphicon-resize-small highlight" <span class=" glyphicon glyphicon-resize-small highlight"
*ngIf="fullScreenService.isFullScreenEnabled()" *ngIf="fullScreenService.isFullScreenEnabled()"
(click)="fullScreenService.exitFullScreen()" title="toggle fullscreen"></span> (click)="fullScreenService.exitFullScreen()" title="toggle fullscreen"></span>
</span> </span>
<span> <span>
<span class="glyphicon glyphicon-fullscreen highlight" <span class="glyphicon glyphicon-fullscreen highlight"
*ngIf="!fullScreenService.isFullScreenEnabled()" *ngIf="!fullScreenService.isFullScreenEnabled()"
(click)="fullScreenService.showFullScreen(root)" title="toggle fullscreen"></span> (click)="fullScreenService.showFullScreen(root)" title="toggle fullscreen"></span>
</span> </span>
<span> <span>
<span class="glyphicon glyphicon-remove highlight" (click)="hide()" title="close"></span> <span class="glyphicon glyphicon-remove highlight" (click)="hide()" title="close"></span>
</span> </span>
</div>
</div> </div>
</div>
</div> </div>

View File

@ -3,7 +3,7 @@ import {PhotoDTO} from "../../../../../common/entities/PhotoDTO";
import {Dimension} from "../../../model/IRenderable"; import {Dimension} from "../../../model/IRenderable";
import {FullScreenService} from "../../fullscreen.service"; import {FullScreenService} from "../../fullscreen.service";
import {AgmMap} from "@agm/core"; import {AgmMap} from "@agm/core";
import {IconThumbnail, ThumbnailManagerService} from "../../thumnailManager.service"; import {IconThumbnail, Thumbnail, ThumbnailManagerService} from "../../thumnailManager.service";
import {IconPhoto} from "../../IconPhoto"; import {IconPhoto} from "../../IconPhoto";
import {Photo} from "../../Photo"; import {Photo} from "../../Photo";
@ -28,7 +28,8 @@ export class GalleryMapLightboxComponent implements OnChanges {
@ViewChild(AgmMap) map: AgmMap; @ViewChild(AgmMap) map: AgmMap;
constructor(public fullScreenService: FullScreenService, private thumbnailService: ThumbnailManagerService) { constructor(public fullScreenService: FullScreenService,
private thumbnailService: ThumbnailManagerService) {
} }
@ -85,8 +86,6 @@ export class GalleryMapLightboxComponent implements OnChanges {
this.visible = false; this.visible = false;
this.hideImages(); this.hideImages();
}, 500); }, 500);
} }
showImages() { showImages() {
@ -103,6 +102,7 @@ export class GalleryMapLightboxComponent implements OnChanges {
width = height * (p.metadata.size.width / p.metadata.size.height); width = height * (p.metadata.size.width / p.metadata.size.height);
} }
const iconTh = this.thumbnailService.getIcon(new IconPhoto(p)); const iconTh = this.thumbnailService.getIcon(new IconPhoto(p));
iconTh.Visible = true;
const obj: MapPhoto = { const obj: MapPhoto = {
latitude: p.metadata.positionData.GPSData.latitude, latitude: p.metadata.positionData.GPSData.latitude,
longitude: p.metadata.positionData.GPSData.longitude, longitude: p.metadata.positionData.GPSData.longitude,
@ -110,7 +110,7 @@ export class GalleryMapLightboxComponent implements OnChanges {
preview: { preview: {
width: width, width: width,
height: height, height: height,
url: (new Photo(p, width, height)).getThumbnailPath() thumbnail: this.thumbnailService.getLazyThumbnail(new Photo(p, width, height))
} }
}; };
@ -129,8 +129,15 @@ export class GalleryMapLightboxComponent implements OnChanges {
} }
} }
public loadPreview(mp: MapPhoto) {
mp.preview.thumbnail.load();
}
hideImages() { hideImages() {
this.mapPhotos.forEach((mp) => mp.iconThumbnail.destroy()); this.mapPhotos.forEach((mp) => {
mp.iconThumbnail.destroy();
mp.preview.thumbnail.destroy();
});
this.mapPhotos = []; this.mapPhotos = [];
} }
@ -176,7 +183,7 @@ export interface MapPhoto {
preview: { preview: {
width: number; width: number;
height: number; height: number;
url: string; thumbnail: Thumbnail;
} }
} }

View File

@ -18,6 +18,10 @@ export class ThumbnailManagerService {
return new Thumbnail(photo, this.thumbnailLoader); return new Thumbnail(photo, this.thumbnailLoader);
} }
public getLazyThumbnail(photo: Photo): Thumbnail {
return new Thumbnail(photo, this.thumbnailLoader, false);
}
public getIcon(photo: IconPhoto) { public getIcon(photo: IconPhoto) {
return new IconThumbnail(photo, this.thumbnailLoader); return new IconThumbnail(photo, this.thumbnailLoader);
@ -32,7 +36,7 @@ export abstract class ThumbnailBase {
protected loading: boolean = false; protected loading: boolean = false;
protected error: boolean = false; protected error: boolean = false;
protected onLoad: Function = null; protected onLoad: Function = null;
protected thumbnailTask: ThumbnailTaskEntity; protected thumbnailTask: ThumbnailTaskEntity = null;
constructor(protected thumbnailService: ThumbnailLoaderService) { constructor(protected thumbnailService: ThumbnailLoaderService) {
@ -126,7 +130,7 @@ export class IconThumbnail extends ThumbnailBase {
export class Thumbnail extends ThumbnailBase { export class Thumbnail extends ThumbnailBase {
constructor(private photo: Photo, thumbnailService: ThumbnailLoaderService) { constructor(private photo: Photo, thumbnailService: ThumbnailLoaderService, autoLoad: boolean = true) {
super(thumbnailService); super(thumbnailService);
if (this.photo.isThumbnailAvailable()) { if (this.photo.isThumbnailAvailable()) {
this.src = this.photo.getThumbnailPath(); this.src = this.photo.getThumbnailPath();
@ -136,10 +140,14 @@ export class Thumbnail extends ThumbnailBase {
this.src = this.photo.getReplacementThumbnailPath(); this.src = this.photo.getReplacementThumbnailPath();
this.available = true; this.available = true;
} }
if (autoLoad) {
this.load();
}
}
if (!this.photo.isThumbnailAvailable()) { public load() {
if (!this.photo.isThumbnailAvailable() && this.thumbnailTask == null) {
setTimeout(() => { setTimeout(() => {
let listener: ThumbnailLoadingListener = { let listener: ThumbnailLoadingListener = {
onStartedLoading: () => { //onLoadStarted onStartedLoading: () => { //onLoadStarted
this.loading = true; this.loading = true;
@ -162,11 +170,8 @@ export class Thumbnail extends ThumbnailBase {
} else { } else {
this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener); this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener);
} }
}, 0); }, 0);
} }
} }
set Visible(visible: boolean) { set Visible(visible: boolean) {