diff --git a/src/app/theme/baCard/baCardBlur.directive.ts b/src/app/theme/baCard/baCardBlur.directive.ts new file mode 100644 index 00000000..e5ae3f6f --- /dev/null +++ b/src/app/theme/baCard/baCardBlur.directive.ts @@ -0,0 +1,43 @@ +import {Directive, ElementRef, HostListener} from 'angular2/core'; +import {BaCardBlurHelper} from './baCardBlurHelper.service'; + +import {BgMetrics} from './bgMetrics'; + +@Directive({ + selector: '[baCardBlur]', + providers: [BaCardBlurHelper] +}) +export class BaCardBlur { + private _bodyBgSize:BgMetrics; + + constructor(private _baCardBlurHelper:BaCardBlurHelper, private _el:ElementRef) { + this._getBodyImageSizesOnBgLoad(); + this._recalculateCardStylesOnBgLoad(); + } + + @HostListener('window:resize') + _onWindowResize():void { + this._bodyBgSize = this._baCardBlurHelper.getBodyBgImageSizes(); + this._recalculateCardStyle(); + } + + private _getBodyImageSizesOnBgLoad():void { + this._baCardBlurHelper.bodyBgLoad().then(function() { + this._bodyBgSize = this._baCardBlurHelper.getBodyBgImageSizes(); + }); + } + + private _recalculateCardStylesOnBgLoad():void { + this._baCardBlurHelper.bodyBgLoad().then(() => { + setTimeout(this._recalculateCardStyle); + }); + } + + private _recalculateCardStyle():void { + if (!this._bodyBgSize) { + return; + } + this._el.nativeElement.style.backgroundSize = Math.round(this._bodyBgSize.width) + 'px ' + Math.round(this._bodyBgSize.height) + 'px'; + this._el.nativeElement.style.backgroundPosition = Math.floor(this._bodyBgSize.positionX) + 'px ' + Math.floor(this._bodyBgSize.positionY) + 'px'; + } +} diff --git a/src/app/theme/baCard/baCardBlurHelper.service.ts b/src/app/theme/baCard/baCardBlurHelper.service.ts new file mode 100644 index 00000000..69cb7a9d --- /dev/null +++ b/src/app/theme/baCard/baCardBlurHelper.service.ts @@ -0,0 +1,51 @@ +import {Injectable} from 'angular2/core' + +import {BgMetrics} from './bgMetrics'; + +@Injectable() +export class BaCardBlurHelper { + private image:HTMLImageElement; + private imageLoadDeferred = Promise.defer(); //TODO: Promises or Observables refactor + + constructor() { + this._genBgImage(); + this._setImageLoadResolves() + } + + private _genBgImage():void { + this.image = new Image(); + let computedStyle = getComputedStyle(document.body, ':before'); + this.image.src = computedStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2'); + } + + private _setImageLoadResolves():void { + this.image.onerror = () => { + this.imageLoadDeferred.reject(); + }; + this.image.onload = () => { + this.imageLoadDeferred.resolve(); + }; + } + + public bodyBgLoad():Promise { + return this.imageLoadDeferred.promise; + } + + public getBodyBgImageSizes():BgMetrics { + let elemW = document.documentElement.clientWidth; + let elemH = document.documentElement.clientHeight; + if(elemW <= 640) return; + let imgRatio = (this.image.height / this.image.width); // original img ratio + let containerRatio = (elemH / elemW); // container ratio + + let finalHeight, finalWidth; + if (containerRatio > imgRatio) { + finalHeight = elemH; + finalWidth = (elemH / imgRatio); + } else { + finalWidth = elemW; + finalHeight = (elemW * imgRatio); + } + return { width: finalWidth, height: finalHeight, positionX: (elemW - finalWidth)/2, positionY: (elemH - finalHeight)/2}; + } +} diff --git a/src/app/theme/baCard/bgMetrics.ts b/src/app/theme/baCard/bgMetrics.ts new file mode 100644 index 00000000..acc460bd --- /dev/null +++ b/src/app/theme/baCard/bgMetrics.ts @@ -0,0 +1,6 @@ +export interface BgMetrics { + width:number; + height:number; + positionX:number; + positionY:number; +} \ No newline at end of file diff --git a/src/app/theme/baCard/index.ts b/src/app/theme/baCard/index.ts index 4890b0a2..66478bc9 100644 --- a/src/app/theme/baCard/index.ts +++ b/src/app/theme/baCard/index.ts @@ -1 +1,2 @@ -export * from './baCard.component'; \ No newline at end of file +export * from './baCard.component'; +export * from './baCardBlur.directive'; \ No newline at end of file