UNPKG

ng2-parallaxscroll

Version:

A parallax directive for Angular 2+, now with Universal support!

198 lines 14.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Directive, ElementRef, PLATFORM_ID, Inject, Input } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; export class ParallaxScrollDirective { /** * @param {?} element * @param {?} platformId */ constructor(element, platformId) { this.platformId = platformId; this.axis = 'Y'; this.speed = -.7; this.initialValue = 0; this.cssUnit = 'px'; this.parallaxPivot = '50%'; this.cssProperty = 'backgroundPosition'; this.onScroll = (/** * @return {?} */ () => { /** @type {?} */ let result; /** @type {?} */ let scrollPosition; // Read scroll position * speed + initial val if (this.testBrowser && this.scrollElement instanceof Window) { scrollPosition = this.scrollElement.scrollY * this.speed + this.initialValue; } else { scrollPosition = this.scrollElement.scrollTop * this.speed + this.initialValue; } // Set limits if (this.maxValue !== undefined && scrollPosition >= this.maxValue) { scrollPosition = this.maxValue; } else if (this.minValue !== undefined && scrollPosition <= this.minValue) { scrollPosition = this.minValue; } // Get output based on axis if (this.axis === 'X') { result = 'calc(' + this.parallaxPivot + ' + ' + scrollPosition + this.cssUnit + ') center'; } else { result = 'center calc(' + this.parallaxPivot + ' + ' + scrollPosition + this.cssUnit + ')'; } this.parallaxElement.style[(/** @type {?} */ (this.cssProperty))] = result; }); this.hostElement = element.nativeElement; this.testBrowser = isPlatformBrowser(this.platformId); // If the window exists, grab it, else set to hostElement to prevent errors this.backupElement = this.testBrowser ? window : this.hostElement; } /** * @return {?} */ ngOnInit() { // Read config for (const prop in this.config) { if (this.config.hasOwnProperty(prop)) { ((/** @type {?} */ (this)))[prop] = ((/** @type {?} */ (this.config)))[prop]; } } this.speed = +this.speed; this.initialValue = +this.initialValue; this.parallaxElement = this.parallaxElement || this.hostElement; // Grab scroll element if (this.scrollerId) { try { this.scrollElement = document.getElementById(this.scrollerId); if (!this.scrollElement) { throw new Error((`ID ('${this.scrollerId}') does not exist! Using default`)); } } catch (e) { this.scrollElement = this.backupElement; } } else { this.scrollElement = this.backupElement; } this.onScroll(); this.scrollElement.addEventListener('scroll', this.onScroll.bind(this)); } } ParallaxScrollDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[parallax]' },] } ]; /** @nocollapse */ ParallaxScrollDirective.ctorParameters = () => [ { type: ElementRef }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] } ]; ParallaxScrollDirective.propDecorators = { config: [{ type: Input }], axis: [{ type: Input }], speed: [{ type: Input }], initialValue: [{ type: Input }], maxValue: [{ type: Input }], minValue: [{ type: Input }], cssUnit: [{ type: Input }], scrollerId: [{ type: Input }], parallaxElement: [{ type: Input }], parallaxPivot: [{ type: Input }] }; if (false) { /** * @type {?} * @private */ ParallaxScrollDirective.prototype.config; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.axis; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.speed; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.initialValue; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.maxValue; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.minValue; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.cssUnit; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.scrollerId; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.parallaxElement; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.parallaxPivot; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.cssProperty; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.scrollElement; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.hostElement; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.backupElement; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.testBrowser; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.onScroll; /** * @type {?} * @private */ ParallaxScrollDirective.prototype.platformId; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmcyLXBhcmFsbGF4c2Nyb2xsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nMi1wYXJhbGxheHNjcm9sbC8iLCJzb3VyY2VzIjpbImxpYi9uZzItcGFyYWxsYXhzY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQU1wRCxNQUFNLE9BQU8sdUJBQXVCOzs7OztJQW1CaEMsWUFDSSxPQUFtQixFQUVVLFVBQWtCO1FBQWxCLGVBQVUsR0FBVixVQUFVLENBQVE7UUFuQmxDLFNBQUksR0FBYyxHQUFHLENBQUM7UUFDdEIsVUFBSyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ1osaUJBQVksR0FBRyxDQUFDLENBQUM7UUFHakIsWUFBTyxHQUFHLElBQUksQ0FBQztRQUdmLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRS9CLGdCQUFXLEdBQUcsb0JBQW9CLENBQUM7UUFnRG5DLGFBQVE7OztRQUFHLEdBQUcsRUFBRTs7Z0JBQ2hCLE1BQWM7O2dCQUNkLGNBQXNCO1lBRTFCLDZDQUE2QztZQUM3QyxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGFBQWEsWUFBWSxNQUFNLEVBQUU7Z0JBQzFELGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7YUFDaEY7aUJBQU07Z0JBQ0gsY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQzthQUNsRjtZQUVELGFBQWE7WUFDYixJQUFJLElBQUksQ0FBQyxRQUFRLEtB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LE1BQU0sU0FBQyxXQUFXOzs7cUJBcEJ0QixLQUFLO21CQUNMLEtBQUs7b0JBQ0wsS0FBSzsyQkFDTCxLQUFLO3VCQUNMLEtBQUs7dUJBQ0wsS0FBSztzQkFDTCxLQUFLO3lCQUNMLEtBQUs7OEJBQ0wsS0FBSzs0QkFDTCxLQUFLOzs7Ozs7O0lBVE4seUNBQStDOzs7OztJQUMvQyx1Q0FBdUM7Ozs7O0lBQ3ZDLHdDQUE2Qjs7Ozs7SUFDN0IsK0NBQWtDOzs7OztJQUNsQywyQ0FBa0M7Ozs7O0lBQ2xDLDJDQUFrQzs7Ozs7SUFDbEMsMENBQWdDOzs7OztJQUNoQyw2Q0FBb0M7Ozs7O0lBQ3BDLGtEQUE4Qzs7Ozs7SUFDOUMsZ0RBQXVDOzs7OztJQUV2Qyw4Q0FBMkM7Ozs7O0lBQzNDLGdEQUEyQjs7Ozs7SUFDM0IsOENBQWlDOzs7OztJQUNqQyxnREFBMkI7Ozs7O0lBQzNCLDhDQUE2Qjs7Ozs7SUE0QzdCLDJDQTBCQzs7Ozs7SUFqRUcsNkNBQStDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVBhcmFsbGF4U2Nyb2xsQ29uZmlnIH0gZnJvbSAnLi9uZzItcGFyYWxsYXhzY3JvbGwnO1xuaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBQTEFURk9STV9JRCwgSW5qZWN0LCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBEaXJlY3RpdmUoe1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkaXJlY3RpdmUtc2VsZWN0b3JcbiAgICBzZWxlY3RvcjogJ1twYXJhbGxheF0nXG59KVxuZXhwb3J0IGNsYXNzIFBhcmFsbGF4U2Nyb2xsRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcblxuICAgIEBJbnB1dCgpIHByaXZhdGUgY29uZmlnOiBJUGFyYWxsYXhTY3JvbGxDb25maWc7XG4gICAgQElucHV0KCkgcHJpdmF0ZSBheGlzOiAnWCcgfCAnWScgPSAnWSc7XG4gICAgQElucHV0KCkgcHJpdmF0ZSBzcGVlZCA9IC0uNztcbiAgICBASW5wdXQoKSBwcml2YXRlIGluaXRpYWxWYWx1ZSA9IDA7XG4gICAgQElucHV0KCkgcHJpdmF0ZSBtYXhWYWx1ZTogbnVtYmVyO1xuICAgIEBJbnB1dCgpIHByaXZhdGUgbWluVmFsdWU6IG51bWJlcjtcbiAgICBASW5wdXQoKSBwcml2YXRlIGNzc1VuaXQgPSAncHgnO1xuICAgIEBJbnB1dCgpIHByaXZhdGUgc2Nyb2xsZXJJZDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHByaXZhdGUgcGFyYWxsYXhFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBASW5wdXQoKSBwcml2YXRlIHBhcmFsbGF4UGl2b3QgPSAnNTAlJztcblxuICAgIHByaXZhdGUgY3NzUHJvcGVydHkgPSAnYmFja2dyb3VuZFBvc2l0aW9uJztcbiAgICBwcml2YXRlIHNjcm9sbEVsZW1lbnQ6IGFueTtcbiAgICBwcml2YXRlIGhvc3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIGJhY2t1cEVsZW1lbnQ6IGFueTtcbiAgICBwcml2YXRlIHRlc3RCcm93c2VyOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpiYW4tdHlwZXNcbiAgICAgICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3QpIHtcbiAgICAgICAgdGhpcy5ob3N0RWxlbWVudCA9IGVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy50ZXN0QnJvd3NlciA9IGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCk7XG4gICAgICAgIC8vIElmIHRoZSB3aW5kb3cgZXhpc3RzLCBncmFiIGl0LCBlbHNlIHNldCB0byBob3N0RWxlbWVudCB0byBwcmV2ZW50IGVycm9yc1xuICAgICAgICB0aGlzLmJhY2t1cEVsZW1lbnQgPSB0aGlzLnRlc3RCcm93c2VyID8gd2luZG93IDogdGhpcy5ob3N0RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICAgIC8vIFJlYWQgY29uZmlnXG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiB0aGlzLmNvbmZpZykge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICAgICAgKHRoaXMgYXMgYW55KVtwcm9wXSA9ICh0aGlzLmNvbmZpZyBhcyBhbnkpW3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zcGVlZCA9ICt0aGlzLnNwZWVkO1xuICAgICAgICB0aGlzLmluaXRpYWxWYWx1ZSA9ICt0aGlzLmluaXRpYWxWYWx1ZTtcblxuICAgICAgICB0aGlzLnBhcmFsbGF4RWxlbWVudCA9IHRoaXMucGFyYWxsYXhFbGVtZW50IHx8IHRoaXMuaG9zdEVsZW1lbnQ7XG5cbiAgICAgICAgLy8gR3JhYiBzY3JvbGwgZWxlbWVudFxuICAgICAgICBpZiAodGhpcy5zY3JvbGxlcklkKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuc2Nyb2xsZXJJZCk7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNjcm9sbEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKChgSUQgKCcke3RoaXMuc2Nyb2xsZXJJZH0nKSBkb2VzIG5vdCBleGlzdCEgVXNpbmcgZGVmYXVsdGApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50ID0gdGhpcy5iYWNrdXBFbGVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50ID0gdGhpcy5iYWNrdXBFbGVtZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vblNjcm9sbCgpO1xuXG4gICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLm9uU2Nyb2xsLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25TY3JvbGwgPSAoKSA9PiB7XG4gICAgICAgIGxldCByZXN1bHQ6IHN0cmluZztcbiAgICAgICAgbGV0IHNjcm9sbFBvc2l0aW9uOiBudW1iZXI7XG5cbiAgICAgICAgLy8gUmVhZCBzY3JvbGwgcG9zaXRpb24gKiBzcGVlZCArIGluaXRpYWwgdmFsXG4gICAgICAgIGlmICh0aGlzLnRlc3RCcm93c2VyICYmIHRoaXMuc2Nyb2xsRWxlbWVudCBpbnN0YW5jZW9mIFdpbmRvdykge1xuICAgICAgICAgICAgc2Nyb2xsUG9zaXRpb24gPSB0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsWSAqIHRoaXMuc3BlZWQgKyB0aGlzLmluaXRpYWxWYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNjcm9sbFBvc2l0aW9uID0gdGhpcy5zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCAqIHRoaXMuc3BlZWQgKyB0aGlzLmluaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBsaW1pdHNcbiAgICAgICAgaWYgKHRoaXMubWF4VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBzY3JvbGxQb3NpdGlvbiA+PSB0aGlzLm1heFZhbHVlKSB7XG4gICAgICAgICAgICBzY3JvbGxQb3NpdGlvbiA9IHRoaXMubWF4VmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5taW5WYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHNjcm9sbFBvc2l0aW9uIDw9IHRoaXMubWluVmFsdWUpIHtcbiAgICAgICAgICAgIHNjcm9sbFBvc2l0aW9uID0gdGhpcy5taW5WYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCBvdXRwdXQgYmFzZWQgb24gYXhpc1xuICAgICAgICBpZiAodGhpcy5heGlzID09PSAnWCcpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9ICdjYWxjKCcgKyB0aGlzLnBhcmFsbGF4UGl2b3QgKyAnICsgJyArIHNjcm9sbFBvc2l0aW9uICsgdGhpcy5jc3NVbml0ICsgJykgY2VudGVyJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdCA9ICdjZW50ZXIgY2FsYygnICsgdGhpcy5wYXJhbGxheFBpdm90ICsgJyArICcgKyBzY3JvbGxQb3NpdGlvbiArIHRoaXMuY3NzVW5pdCArICcpJztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucGFyYWxsYXhFbGVtZW50LnN0eWxlW3RoaXMuY3NzUHJvcGVydHkgYXMgYW55XSA9IHJlc3VsdDtcbiAgICB9XG59XG4iXX0=