improving lightbox
bug fixes with new image loading and fullscreen mode
This commit is contained in:
parent
52544ae956
commit
f1d8364a2e
@ -30,6 +30,7 @@ import {Config} from "./config/Config";
|
||||
import {GalleryMapComponent} from "./gallery/map/map.gallery.component";
|
||||
import {GalleryMapLightboxComponent} from "./gallery/map/lightbox/lightbox.map.gallery.component";
|
||||
import {ThumbnailManagerService} from "./gallery/thumnailManager.service";
|
||||
import {OverlayService} from "./gallery/overlay.service";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -68,7 +69,8 @@ import {ThumbnailManagerService} from "./gallery/thumnailManager.service";
|
||||
AuthenticationService,
|
||||
ThumbnailLoaderService,
|
||||
ThumbnailManagerService,
|
||||
FullScreenService],
|
||||
FullScreenService,
|
||||
OverlayService],
|
||||
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Event} from "../../../common/event/Event";
|
||||
|
||||
@Injectable()
|
||||
export class FullScreenService {
|
||||
|
||||
|
||||
OnFullScreenChange = new Event<boolean>();
|
||||
|
||||
public isFullScreenEnabled(): boolean {
|
||||
return !!(document.fullscreenElement || document['mozFullScreenElement'] || document.webkitFullscreenElement);
|
||||
}
|
||||
@ -22,6 +25,7 @@ export class FullScreenService {
|
||||
} else if (element.msRequestFullscreen) {
|
||||
element.msRequestFullscreen();
|
||||
}
|
||||
this.OnFullScreenChange.trigger(true);
|
||||
}
|
||||
|
||||
public exitFullScreen() {
|
||||
@ -36,6 +40,7 @@ export class FullScreenService {
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
}
|
||||
this.OnFullScreenChange.trigger(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
ElementRef,
|
||||
OnChanges,
|
||||
ViewChild,
|
||||
ViewChildren,
|
||||
QueryList,
|
||||
AfterViewInit,
|
||||
HostListener
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
QueryList,
|
||||
ViewChild,
|
||||
ViewChildren
|
||||
} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {GridRowBuilder} from "./GridRowBuilder";
|
||||
@ -15,31 +16,33 @@ import {GalleryLightboxComponent} from "../lightbox/lightbox.gallery.component";
|
||||
import {GridPhoto} from "./GridPhoto";
|
||||
import {GalleryPhotoComponent} from "./photo/photo.grid.gallery.component";
|
||||
import {Config} from "../../config/Config";
|
||||
import {OverlayService} from "../overlay.service";
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-grid',
|
||||
templateUrl: 'app/gallery/grid/grid.gallery.component.html',
|
||||
styleUrls: ['app/gallery/grid/grid.gallery.component.css'],
|
||||
})
|
||||
export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
export class GalleryGridComponent implements OnChanges, AfterViewInit {
|
||||
|
||||
@ViewChild('gridContainer') gridContainer:ElementRef;
|
||||
@ViewChildren(GalleryPhotoComponent) gridPhotoQL:QueryList<GalleryPhotoComponent>;
|
||||
@ViewChild('gridContainer') gridContainer: ElementRef;
|
||||
@ViewChildren(GalleryPhotoComponent) gridPhotoQL: QueryList<GalleryPhotoComponent>;
|
||||
|
||||
@Input() photos: Array<PhotoDTO>;
|
||||
@Input() lightbox:GalleryLightboxComponent;
|
||||
@Input() lightbox: GalleryLightboxComponent;
|
||||
|
||||
photosToRender:Array<GridPhoto> = [];
|
||||
containerWidth:number = 0;
|
||||
photosToRender: Array<GridPhoto> = [];
|
||||
containerWidth: number = 0;
|
||||
|
||||
private IMAGE_MARGIN = 2;
|
||||
private TARGET_COL_COUNT = 5;
|
||||
private MIN_ROW_COUNT = 2;
|
||||
private MAX_ROW_COUNT = 5;
|
||||
|
||||
onScrollFired = false;
|
||||
private onScrollFired = false;
|
||||
private scrollbarWidth = 0;
|
||||
|
||||
constructor() {
|
||||
constructor(private overlayService: OverlayService, private changeDetector: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
@ -61,16 +64,17 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
}
|
||||
this.updateContainerWidth();
|
||||
this.sortPhotos();
|
||||
//render the same amount of images on resize
|
||||
let renderedIndex = this.renderedPhotoIndex;
|
||||
this.clearRenderedPhotos();
|
||||
setImmediate(() => {
|
||||
this.renderPhotos();
|
||||
});
|
||||
this.renderPhotos(renderedIndex);
|
||||
}
|
||||
|
||||
isAfterViewInit:boolean = false;
|
||||
|
||||
isAfterViewInit: boolean = false;
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.lightbox.gridPhotoQL = this.gridPhotoQL;
|
||||
this.lightbox.setGridPhotoQL(this.gridPhotoQL);
|
||||
|
||||
//TODO: implement scroll detection
|
||||
|
||||
@ -96,6 +100,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
private clearRenderedPhotos() {
|
||||
this.photosToRender = [];
|
||||
this.renderedPhotoIndex = 0;
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
private mergeNewPhotos() {
|
||||
@ -123,9 +128,9 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
}
|
||||
|
||||
|
||||
private renderedPhotoIndex:number = 0;
|
||||
private renderedPhotoIndex: number = 0;
|
||||
|
||||
private renderPhotos() {
|
||||
private renderPhotos(numberOfPhotos: number = 0) {
|
||||
if (this.containerWidth == 0 || this.renderedPhotoIndex >= this.photos.length || !this.shouldRenderMore()) {
|
||||
return;
|
||||
}
|
||||
@ -133,7 +138,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
|
||||
let renderedContentHeight = 0;
|
||||
|
||||
while (this.renderedPhotoIndex < this.photos.length && this.shouldRenderMore(renderedContentHeight) === true) {
|
||||
while (this.renderedPhotoIndex < this.photos.length && (this.shouldRenderMore(renderedContentHeight) === true || this.renderedPhotoIndex < numberOfPhotos)) {
|
||||
let ret = this.renderARow();
|
||||
if (ret === null) {
|
||||
throw new Error("Gridphotos rendering failed");
|
||||
@ -149,7 +154,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
* @param offset Add height to the client height (conent is not yet added to the dom, but calculate with it)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private shouldRenderMore(offset:number = 0):boolean {
|
||||
private shouldRenderMore(offset: number = 0): boolean {
|
||||
return Config.Client.enableOnScrollRendering === false ||
|
||||
window.scrollY >= (document.body.clientHeight + offset - window.innerHeight) * 0.7
|
||||
|| (document.body.clientHeight + offset) * 0.85 < window.innerHeight;
|
||||
@ -164,7 +169,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
this.renderPhotos();
|
||||
|
||||
if (Config.Client.enableOnScrollThumbnailPrioritising === true) {
|
||||
this.gridPhotoQL.toArray().forEach((pc:GalleryPhotoComponent) => {
|
||||
this.gridPhotoQL.toArray().forEach((pc: GalleryPhotoComponent) => {
|
||||
pc.onScroll();
|
||||
});
|
||||
}
|
||||
@ -174,15 +179,16 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
public renderARow():number {
|
||||
public renderARow(): number {
|
||||
if (this.renderedPhotoIndex >= this.photos.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
let photoRowBuilder = new GridRowBuilder(this.photos, this.renderedPhotoIndex, this.IMAGE_MARGIN, this.containerWidth - this.overlayService.getPhantomScrollbarWidth());
|
||||
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT);
|
||||
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight);
|
||||
|
||||
@ -198,7 +204,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
|
||||
return rowHeight;
|
||||
}
|
||||
|
||||
private updateContainerWidth():number {
|
||||
private updateContainerWidth(): number {
|
||||
if (!this.gridContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -37,9 +37,11 @@
|
||||
<span class="glyphicon glyphicon-remove highlight" (click)="hide()" title="close"></span>
|
||||
</div>
|
||||
|
||||
<div class="navigation-arrow highlight" *ngIf="navigation.hasPrev" id="leftArrow" (click)="prevImage()"><span
|
||||
<div class="navigation-arrow highlight" *ngIf="navigation.hasPrev" title="key: left arrow" id="leftArrow"
|
||||
(click)="prevImage()"><span
|
||||
class="glyphicon glyphicon-chevron-left"></span></div>
|
||||
<div class="navigation-arrow highlight" *ngIf="navigation.hasNext" id="rightArrow" (click)="nextImage()"><span
|
||||
<div class="navigation-arrow highlight" *ngIf="navigation.hasNext" title="key: right arrow" id="rightArrow"
|
||||
(click)="nextImage()"><span
|
||||
class="glyphicon glyphicon-chevron-right"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,19 @@
|
||||
import {Component, QueryList, Output, EventEmitter, HostListener, ElementRef, ViewChild} from "@angular/core";
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
Output,
|
||||
QueryList,
|
||||
ViewChild
|
||||
} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {GalleryPhotoComponent} from "../grid/photo/photo.grid.gallery.component";
|
||||
import {Dimension} from "../../model/IRenderable";
|
||||
import {FullScreenService} from "../fullscreen.service";
|
||||
import {OverlayService} from "../overlay.service";
|
||||
import {Subscription} from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-lightbox',
|
||||
@ -19,62 +30,80 @@ export class GalleryLightboxComponent {
|
||||
public blackCanvasOpacity: any = 0;
|
||||
|
||||
private activePhoto: GalleryPhotoComponent;
|
||||
public gridPhotoQL: QueryList<GalleryPhotoComponent>;
|
||||
private gridPhotoQL: QueryList<GalleryPhotoComponent>;
|
||||
|
||||
private visible = false;
|
||||
private changeSubscription: Subscription = null;
|
||||
|
||||
@ViewChild("root") elementRef: ElementRef;
|
||||
|
||||
|
||||
constructor(private fullScreenService: FullScreenService) {
|
||||
constructor(private fullScreenService: FullScreenService, private changeDetector: ChangeDetectorRef, private overlayService: OverlayService) {
|
||||
}
|
||||
|
||||
|
||||
//noinspection JSUnusedGlobalSymbols
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize() {
|
||||
if (this.activePhoto) {
|
||||
this.disableAnimation();
|
||||
this.lightboxDimension.width = this.getScreenWidth();
|
||||
this.lightboxDimension.height = this.getScreenHeight();
|
||||
this.updateActivePhoto(this.activePhotoId);
|
||||
}
|
||||
}
|
||||
|
||||
public nextImage() {
|
||||
|
||||
this.disableAnimation();
|
||||
let pcList = this.gridPhotoQL.toArray();
|
||||
for (let i = 0; i < pcList.length; i++) {
|
||||
if (pcList[i] === this.activePhoto) {
|
||||
if (i + 1 < pcList.length) {
|
||||
this.showPhoto(pcList[i + 1]);
|
||||
|
||||
if (i + 3 === pcList.length) {
|
||||
if (this.activePhotoId + 1 < this.gridPhotoQL.length) {
|
||||
this.showPhoto(this.activePhotoId + 1);
|
||||
if (this.activePhotoId + 3 >= this.gridPhotoQL.length) {
|
||||
this.onLastElement.emit({}); //trigger to render more photos if there are
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.warn("can't find photo to show next");
|
||||
}
|
||||
|
||||
public prevImage() {
|
||||
this.disableAnimation();
|
||||
let pcList = this.gridPhotoQL.toArray();
|
||||
for (let i = 0; i < pcList.length; i++) {
|
||||
if (pcList[i] === this.activePhoto) {
|
||||
if (i > 0) {
|
||||
this.showPhoto(pcList[i - 1]);
|
||||
}
|
||||
if (this.activePhotoId > 0) {
|
||||
this.showPhoto(this.activePhotoId - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.warn("can't find photo to show prev");
|
||||
}
|
||||
|
||||
|
||||
private showPhoto(photoComponent: GalleryPhotoComponent) {
|
||||
activePhotoId: number = null;
|
||||
|
||||
private showPhoto(photoIndex: number) {
|
||||
this.activePhoto = null;
|
||||
this.changeDetector.detectChanges();
|
||||
this.updateActivePhoto(photoIndex);
|
||||
}
|
||||
|
||||
private updateActivePhoto(photoIndex: number) {
|
||||
let pcList = this.gridPhotoQL.toArray();
|
||||
|
||||
let index = pcList.indexOf(photoComponent);
|
||||
if (index == -1) {
|
||||
|
||||
if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) {
|
||||
throw new Error("Can't find the photo");
|
||||
}
|
||||
this.activePhotoId = photoIndex;
|
||||
this.activePhoto = pcList[photoIndex];
|
||||
|
||||
this.photoDimension = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo);
|
||||
this.navigation.hasPrev = photoIndex > 0;
|
||||
this.navigation.hasNext = photoIndex + 1 < pcList.length;
|
||||
|
||||
let to = this.activePhoto.getDimension();
|
||||
|
||||
//if target image out of screen -> scroll to there
|
||||
if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getScreenHeight() < to.top) {
|
||||
this.setBodyScrollTop(to.top);
|
||||
}
|
||||
|
||||
this.photoDimension = this.calcLightBoxPhotoDimension(photoComponent.gridPhoto.photo);
|
||||
this.navigation.hasPrev = index > 0;
|
||||
this.navigation.hasNext = index + 1 < pcList.length;
|
||||
this.activePhoto = photoComponent;
|
||||
}
|
||||
|
||||
public show(photo: PhotoDTO) {
|
||||
@ -90,8 +119,8 @@ export class GalleryLightboxComponent {
|
||||
this.blackCanvasOpacity = 0;
|
||||
this.photoDimension = selectedPhoto.getDimension();
|
||||
|
||||
document.getElementsByTagName('body')[0].style.overflow = 'hidden';
|
||||
|
||||
//disable scroll
|
||||
this.overlayService.showOverlay();
|
||||
setImmediate(() => {
|
||||
this.lightboxDimension = <Dimension>{
|
||||
top: 0,
|
||||
@ -100,19 +129,13 @@ export class GalleryLightboxComponent {
|
||||
height: this.getScreenHeight()
|
||||
};
|
||||
this.blackCanvasOpacity = 1.0;
|
||||
this.showPhoto(selectedPhoto);
|
||||
this.showPhoto(this.gridPhotoQL.toArray().indexOf(selectedPhoto));
|
||||
});
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.enableAnimation();
|
||||
this.fullScreenService.exitFullScreen();
|
||||
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);
|
||||
}
|
||||
|
||||
this.lightboxDimension = this.activePhoto.getDimension();
|
||||
this.lightboxDimension.top -= this.getBodyScrollTop();
|
||||
@ -121,13 +144,24 @@ export class GalleryLightboxComponent {
|
||||
setTimeout(() => {
|
||||
this.visible = false;
|
||||
this.activePhoto = null;
|
||||
document.getElementsByTagName('body')[0].style.overflow = 'scroll';
|
||||
this.overlayService.hideOverlay();
|
||||
}, 500);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
setGridPhotoQL(value: QueryList<GalleryPhotoComponent>) {
|
||||
if (this.changeSubscription != null) {
|
||||
this.changeSubscription.unsubscribe();
|
||||
}
|
||||
this.gridPhotoQL = value;
|
||||
this.changeSubscription = this.gridPhotoQL.changes.subscribe(() => {
|
||||
if (this.activePhotoId != null && this.gridPhotoQL.length > this.activePhotoId) {
|
||||
this.updateActivePhoto(this.activePhotoId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private findPhotoComponent(photo: any) {
|
||||
let galleryPhotoComponents = this.gridPhotoQL.toArray();
|
||||
for (let i = 0; i < galleryPhotoComponents.length; i++) {
|
||||
@ -138,15 +172,26 @@ export class GalleryLightboxComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
//noinspection JSUnusedGlobalSymbols
|
||||
@HostListener('window:keydown', ['$event'])
|
||||
onKeyPress(e: KeyboardEvent) {
|
||||
if (this.visible != true) {
|
||||
return;
|
||||
}
|
||||
let event: KeyboardEvent = window.event ? <any>window.event : e;
|
||||
switch (event.keyCode) {
|
||||
case 37:
|
||||
if (this.activePhotoId > 0) {
|
||||
this.prevImage();
|
||||
}
|
||||
break;
|
||||
case 39:
|
||||
if (this.activePhotoId < this.gridPhotoQL.length - 1) {
|
||||
this.nextImage();
|
||||
}
|
||||
break;
|
||||
case 27: //escape
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,13 @@
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="thumbnailPath()"/>
|
||||
|
||||
<img *ngIf="gridPhoto"
|
||||
<img *ngIf="gridPhoto !== null"
|
||||
[style.width.%]="imageSize.width"
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="gridPhoto.getPhotoPath()"
|
||||
(load)="onImageLoad()"
|
||||
(error)="onImageError()"/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {Component, OnChanges, Input, ViewChild, ElementRef} from "@angular/core";
|
||||
import {Component, Input, OnChanges} from "@angular/core";
|
||||
import {GridPhoto} from "../../grid/GridPhoto";
|
||||
|
||||
@Component({
|
||||
@ -8,12 +8,11 @@ import {GridPhoto} from "../../grid/GridPhoto";
|
||||
})
|
||||
export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
|
||||
@Input() gridPhoto:GridPhoto;
|
||||
@Input() gridPhoto: GridPhoto;
|
||||
|
||||
public imageSize = {width: "auto", height: "100"};
|
||||
@ViewChild('imgContainer') nativeElement:ElementRef;
|
||||
|
||||
imageLoaded:boolean = false;
|
||||
imageLoaded: boolean = false;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
@ -48,12 +47,12 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
console.error("cant load image");
|
||||
}
|
||||
|
||||
public showThumbnail():boolean {
|
||||
public showThumbnail(): boolean {
|
||||
return this.gridPhoto && !this.imageLoaded &&
|
||||
(this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable());
|
||||
}
|
||||
|
||||
public thumbnailPath():string {
|
||||
public thumbnailPath(): string {
|
||||
if (this.gridPhoto.isThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getThumbnailPath();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Component, Input, OnChanges, ElementRef, ViewChild} from "@angular/core";
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../../common/entities/PhotoDTO";
|
||||
import {Dimension} from "../../../model/IRenderable";
|
||||
import {FullScreenService} from "../../fullscreen.service";
|
||||
import {SebmGoogleMap} from "angular2-google-maps/core";
|
||||
import {ThumbnailManagerService, IconThumbnail} from "../../thumnailManager.service";
|
||||
import {IconThumbnail, ThumbnailManagerService} from "../../thumnailManager.service";
|
||||
import {IconPhoto} from "../../IconPhoto";
|
||||
|
||||
@Component({
|
||||
@ -138,6 +138,20 @@ export class GalleryMapLightboxComponent implements OnChanges {
|
||||
return window.innerHeight;
|
||||
}
|
||||
|
||||
//noinspection JSUnusedGlobalSymbols
|
||||
@HostListener('window:keydown', ['$event'])
|
||||
onKeyPress(e: KeyboardEvent) {
|
||||
if (this.visible != true) {
|
||||
return;
|
||||
}
|
||||
let event: KeyboardEvent = window.event ? <any>window.event : e;
|
||||
switch (event.keyCode) {
|
||||
case 27: //escape
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
60
frontend/app/gallery/overlay.service.ts
Normal file
60
frontend/app/gallery/overlay.service.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Event} from "../../../common/event/Event";
|
||||
|
||||
@Injectable()
|
||||
export class OverlayService {
|
||||
|
||||
OnOverlayChange = new Event<boolean>();
|
||||
private scrollWidth: number = null;
|
||||
|
||||
public showOverlay() {
|
||||
|
||||
//disable scrolling
|
||||
document.getElementsByTagName('body')[0].style.overflow = 'hidden';
|
||||
this.OnOverlayChange.trigger(true);
|
||||
}
|
||||
|
||||
public hideOverlay() {
|
||||
|
||||
document.getElementsByTagName('body')[0].style.overflowY = 'scroll';
|
||||
this.OnOverlayChange.trigger(false);
|
||||
}
|
||||
|
||||
getScrollbarWidth() {
|
||||
if (this.scrollWidth == null) {
|
||||
|
||||
|
||||
let outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
|
||||
|
||||
document.body.appendChild(outer);
|
||||
|
||||
let widthNoScroll = outer.offsetWidth;
|
||||
// force scrollbars
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
// add innerdiv
|
||||
let inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
let widthWithScroll = inner.offsetWidth;
|
||||
|
||||
// remove divs
|
||||
outer.parentNode.removeChild(outer);
|
||||
this.scrollWidth = widthNoScroll - widthWithScroll;
|
||||
}
|
||||
|
||||
return this.scrollWidth;
|
||||
}
|
||||
|
||||
getPhantomScrollbarWidth() {
|
||||
if (document.getElementsByTagName('body')[0].style.overflow == 'hidden') {
|
||||
return this.getScrollbarWidth();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user