New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ionic-header-parallax

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ionic-header-parallax - npm Package Compare versions

Comparing version 3.0.0-dev to 3.0.2

esm2015/lib/ionic-header-parallax.directive.js

262

bundles/ionic-header-parallax.umd.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core')) :
typeof define === 'function' && define.amd ? define('ionic-header-parallax', ['exports', '@angular/core'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ionic-header-parallax'] = {}, global.ng.core));
}(this, (function (exports, i0) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@ionic/angular')) :
typeof define === 'function' && define.amd ? define('ionic-header-parallax', ['exports', '@angular/core', '@ionic/angular'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ionic-header-parallax'] = {}, global.ng.core, global.angular));
}(this, (function (exports, i0, angular) { 'use strict';

@@ -33,190 +33,140 @@ function _interopNamespace(e) {

this.renderer = renderer;
this.maximumHeight = 300;
this.height = 300;
this.bgPosition = 'top';
this.originalToolbarHeight = 0;
this.ticking = false;
}
ParallaxDirective.prototype.ngAfterViewInit = function () {
ParallaxDirective.prototype.ngAfterContentInit = function () {
var _this = this;
setTimeout(function () {
try {
_this.initElements();
_this.initStyles();
_this.initEvents();
if (_this.initElements()) {
_this.setupContentPadding();
_this.setupImageOverlay();
_this.setupEvents();
_this.updateProgress();
}
}
catch (e) {
_this.ngAfterViewInit();
_this.ngAfterContentInit();
}
}, 100);
};
Object.defineProperty(ParallaxDirective.prototype, "header", {
get: function () {
return this.headerRef.nativeElement;
},
enumerable: false,
configurable: true
});
/**
* Return the value of the input parameter `height` as a string with units.
* If no units were provided, it will default to 'px'.
*/
ParallaxDirective.prototype.getMaxHeightWithUnits = function () {
return !isNaN(+this.height) || typeof this.height === 'number'
? this.height + 'px'
: this.height;
};
ParallaxDirective.prototype.initElements = function () {
var _this = this;
var parentElement = this.headerRef.nativeElement.parentElement;
this.header = this.headerRef.nativeElement;
this.toolbar = this.header.querySelector('ion-toolbar');
if (!this.toolbar) {
throw new Error('Parallax directive requires a toolbar or navbar element on the page to work.');
if (!this.ionToolbar) {
console.error('A <ion-toolbar> element is needed inside <ion-header>');
return false;
}
this.ionTitle = this.toolbar.querySelector('ion-title');
this.toolbarBackground = this.toolbar.shadowRoot.querySelector('.toolbar-background');
this.barButtons = this.headerRef.nativeElement.querySelector('ion-buttons');
var parentElement = this.header.parentElement;
var ionContent = parentElement.querySelector('ion-content');
this.scrollContent = ionContent.shadowRoot.querySelector('.inner-scroll');
if (!this.scrollContent) {
throw new Error('Parallax directive requires an <ion-content> element on the page to work.');
if (!ionContent) {
console.error('A <ion-content> element is needed');
return false;
}
// Create image overlay
this.innerScroll = ionContent.shadowRoot.querySelector('.inner-scroll');
this.originalToolbarHeight = this.ionToolbar.el.offsetHeight;
this.toolbarContainer =
this.ionToolbar.el.shadowRoot.querySelector('.toolbar-container');
this.toolbarBackground = this.ionToolbar.el.shadowRoot.querySelector('.toolbar-background');
this.color = this.color || window.getComputedStyle(this.toolbarBackground).backgroundColor;
this.renderer.setStyle(this.header, 'pointer-events', 'none');
this.renderer.setStyle(this.toolbarContainer, 'pointer-events', 'all');
this.renderer.setStyle(this.toolbarContainer, 'align-items', 'baseline');
return true;
};
ParallaxDirective.prototype.setupContentPadding = function () {
var parentElement = this.header.parentElement;
var ionContent = parentElement.querySelector('ion-content');
var mainContent = ionContent.shadowRoot.querySelector('main');
var paddingTop = window.getComputedStyle(mainContent).paddingTop;
var calc = "calc(" + paddingTop + " + " + this.getMaxHeightWithUnits() + ")";
this.renderer.setStyle(this.header, 'position', 'absolute');
this.renderer.setStyle(this.innerScroll, 'padding-top', calc);
};
ParallaxDirective.prototype.setupImageOverlay = function () {
this.imageOverlay = this.renderer.createElement('div');
this.renderer.addClass(this.imageOverlay, 'image-overlay');
this.colorOverlay = this.renderer.createElement('div');
this.renderer.addClass(this.colorOverlay, 'color-overlay');
this.colorOverlay.appendChild(this.imageOverlay);
this.header.appendChild(this.colorOverlay);
// Copy title and buttons
this.overlayTitle = this.ionTitle && this.ionTitle.cloneNode(true);
if (this.overlayTitle) {
this.renderer.addClass(this.overlayTitle, 'parallax-title');
setTimeout(function () {
var toolbarTitle = _this.overlayTitle.shadowRoot.querySelector('.toolbar-title');
_this.renderer.setStyle(toolbarTitle, 'pointer-events', 'unset');
});
}
if (this.overlayTitle) {
this.imageOverlay.appendChild(this.overlayTitle);
}
if (this.barButtons) {
this.imageOverlay.appendChild(this.barButtons);
}
};
ParallaxDirective.prototype.initStyles = function () {
var _this = this;
this.headerHeight = this.scrollContent.clientHeight;
this.ticking = false;
if (!this.scrollContent || !toolbar) {
return;
}
// fetch styles
this.maximumHeight = parseFloat(this.maximumHeight.toString());
this.headerMinHeight = this.toolbar.offsetHeight;
this.scrollContentPaddingTop = window.getComputedStyle(this.scrollContent, null).paddingTop.replace('px', '');
this.scrollContentPaddingTop = parseFloat(this.scrollContentPaddingTop);
this.originalToolbarBgColor = window.getComputedStyle(this.toolbarBackground, null).backgroundColor;
if (!this.originalToolbarBgColor) {
throw new Error('Error: toolbarBackround is null.');
}
// header and title
this.renderer.setStyle(this.header, 'position', 'relative');
if (this.overlayTitle) {
this.renderer.setStyle(this.overlayTitle, 'color', this.titleColor);
this.renderer.setStyle(this.overlayTitle, 'position', 'absolute');
this.renderer.setStyle(this.overlayTitle, 'width', '100%');
this.renderer.setStyle(this.overlayTitle, 'height', '100%');
this.renderer.setStyle(this.overlayTitle, 'text-align', 'center');
}
// color overlay
this.renderer.setStyle(this.colorOverlay, 'background-color', this.originalToolbarBgColor);
this.renderer.setStyle(this.colorOverlay, 'height', this.maximumHeight + "px");
this.renderer.setStyle(this.colorOverlay, 'position', 'absolute');
this.renderer.setStyle(this.colorOverlay, 'top', -this.headerMinHeight * 0 + "px");
this.renderer.setStyle(this.colorOverlay, 'left', '0');
this.renderer.setStyle(this.colorOverlay, 'width', '100%');
this.renderer.setStyle(this.colorOverlay, 'z-index', '10');
this.renderer.setStyle(this.colorOverlay, 'pointer-events', 'none');
// image overlay
this.renderer.setStyle(this.imageOverlay, 'background-color', this.expandedColor);
this.renderer.setStyle(this.imageOverlay, 'background-color', this.color);
this.renderer.setStyle(this.imageOverlay, 'background-image', "url(" + (this.imageUrl || '') + ")");
this.renderer.setStyle(this.imageOverlay, 'height', "100%");
this.renderer.setStyle(this.imageOverlay, 'width', '100%');
this.renderer.setStyle(this.imageOverlay, 'pointer-events', 'none');
this.renderer.setStyle(this.imageOverlay, 'background-size', 'cover');
this.renderer.setStyle(this.imageOverlay, 'background-position', 'center');
// .toolbar-background
this.renderer.setStyle(this.toolbarBackground, 'background-color', this.originalToolbarBgColor);
// .bar-buttons
if (this.barButtons) {
this.renderer.setStyle(this.barButtons, 'pointer-events', 'all');
Array.from(this.barButtons.children).forEach(function (btn) {
_this.renderer.setStyle(btn, 'color', _this.titleColor);
});
}
// .scroll-content
if (this.scrollContent) {
this.renderer.setAttribute(this.scrollContent, 'parallax', '');
this.renderer.setStyle(this.scrollContent, 'padding-top', this.maximumHeight + this.scrollContentPaddingTop - this.headerMinHeight + "px");
}
this.renderer.setStyle(this.imageOverlay, 'background-position', this.bgPosition);
this.toolbarBackground.appendChild(this.imageOverlay);
};
ParallaxDirective.prototype.initEvents = function () {
ParallaxDirective.prototype.setupEvents = function () {
var _this = this;
window.addEventListener('resize', function () {
_this.headerHeight = _this.scrollContent.clientHeight;
}, false);
if (this.scrollContent) {
this.scrollContent.addEventListener('scroll', function (e) {
if (!_this.ticking) {
window.requestAnimationFrame(function () {
_this.updateElasticHeader();
});
}
_this.ticking = true;
});
}
};
ParallaxDirective.prototype.updateElasticHeader = function () {
var _this = this;
if (!this.scrollContent || !toolbar) {
return;
}
this.scrollTop = this.scrollContent.scrollTop;
if (this.scrollTop >= 0) {
this.translateAmt = this.scrollTop / 2;
this.scaleAmt = 1;
}
else {
this.translateAmt = 0;
this.scaleAmt = -this.scrollTop / this.headerHeight + 1;
}
// Parallax total progress
this.headerMinHeight = this.toolbar.offsetHeight;
var progress = (this.maximumHeight - this.scrollTop - this.headerMinHeight) / (this.maximumHeight - this.headerMinHeight);
progress = Math.max(progress, 0);
// ion-header: set height
var targetHeight = this.maximumHeight - this.scrollTop;
targetHeight = Math.max(targetHeight, this.headerMinHeight);
// .toolbar-background: change color
this.renderer.setStyle(this.imageOverlay, 'height', targetHeight + "px");
this.renderer.setStyle(this.imageOverlay, 'opacity', "" + progress);
this.renderer.setStyle(this.colorOverlay, 'height', targetHeight + "px");
this.renderer.setStyle(this.colorOverlay, 'opacity', targetHeight > this.headerMinHeight ? '1' : '0');
this.renderer.setStyle(this.toolbarBackground, 'background-color', targetHeight > this.headerMinHeight ? 'transparent' : this.originalToolbarBgColor);
// .bar-buttons
if (this.barButtons) {
if (targetHeight > this.headerMinHeight) {
this.imageOverlay.append(this.barButtons);
Array.from(this.barButtons.children).forEach(function (btn) {
_this.renderer.setStyle(btn, 'color', _this.titleColor);
this.innerScroll.addEventListener('scroll', function (_event) {
if (!_this.ticking) {
window.requestAnimationFrame(function () {
_this.updateProgress();
_this.ticking = false;
});
}
else {
this.toolbar.append(this.barButtons);
Array.from(this.barButtons.children).forEach(function (btn) {
_this.renderer.setStyle(btn, 'color', 'unset');
});
}
}
this.ticking = false;
_this.ticking = true;
});
};
/** Update the parallax effect as per the current scroll of the ion-content */
ParallaxDirective.prototype.updateProgress = function () {
var progress = this.calcProgress(this.innerScroll, +this.height);
this.progressLayerHeight(progress);
this.progressLayerOpacity(progress);
};
ParallaxDirective.prototype.progressLayerHeight = function (progress) {
var h = Math.max(+this.height * (1 - progress), this.originalToolbarHeight);
this.renderer.setStyle(this.toolbarContainer, 'height', h + "px");
this.renderer.setStyle(this.imageOverlay, 'height', h + "px");
};
ParallaxDirective.prototype.progressLayerOpacity = function (progress) {
var op = 1 - progress;
this.renderer.setStyle(this.imageOverlay, 'opacity', op);
// this.renderer.setStyle(this.toolbarContainer, 'opacity', progress);
};
ParallaxDirective.prototype.calcProgress = function (scrollingElement, maxHeight) {
var scroll = +scrollingElement.scrollTop;
var progress = Math.min(1, Math.max(0, scroll / maxHeight));
return progress;
};
return ParallaxDirective;
}());
ParallaxDirective.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0__namespace, type: ParallaxDirective, deps: [{ token: i0__namespace.ElementRef }, { token: i0__namespace.Renderer2 }], target: i0__namespace.ɵɵFactoryTarget.Directive });
ParallaxDirective.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ParallaxDirective, selector: "ion-header[parallax]", inputs: { imageUrl: "imageUrl", expandedColor: "expandedColor", titleColor: "titleColor", maximumHeight: "maximumHeight" }, ngImport: i0__namespace });
ParallaxDirective.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ParallaxDirective, selector: "ion-header[parallax]", inputs: { imageUrl: "imageUrl", color: "color", height: "height", bgPosition: "bgPosition" }, queries: [{ propertyName: "ionTitle", first: true, predicate: angular.IonTitle, descendants: true }, { propertyName: "ionToolbar", first: true, predicate: angular.IonToolbar, descendants: true }, { propertyName: "ionButtons", predicate: angular.IonButtons }], ngImport: i0__namespace });
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0__namespace, type: ParallaxDirective, decorators: [{
type: i0.Directive,
args: [{
selector: 'ion-header[parallax]'
selector: 'ion-header[parallax]',
}]
}], ctorParameters: function () { return [{ type: i0__namespace.ElementRef }, { type: i0__namespace.Renderer2 }]; }, propDecorators: { imageUrl: [{
type: i0.Input
}], expandedColor: [{
}], color: [{
type: i0.Input
}], titleColor: [{
}], height: [{
type: i0.Input
}], maximumHeight: [{
}], bgPosition: [{
type: i0.Input
}], ionTitle: [{
type: i0.ContentChild,
args: [angular.IonTitle, { static: false }]
}], ionToolbar: [{
type: i0.ContentChild,
args: [angular.IonToolbar, { static: false }]
}], ionButtons: [{
type: i0.ContentChildren,
args: [angular.IonButtons]
}] } });

@@ -223,0 +173,0 @@

import { NgModule } from '@angular/core';
import { ParallaxDirective } from './parallax.directive';
import { ParallaxDirective } from './ionic-header-parallax.directive';
import * as i0 from "@angular/core";

@@ -21,2 +21,2 @@ export class IonicHeaderParallaxModule {

}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW9uaWMtaGVhZGVyLXBhcmFsbGF4Lm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2lvbmljLWhlYWRlci1wYXJhbGxheC9zcmMvbGliL2lvbmljLWhlYWRlci1wYXJhbGxheC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7QUFZekQsTUFBTSxPQUFPLHlCQUF5Qjs7c0hBQXpCLHlCQUF5Qjt1SEFBekIseUJBQXlCLGlCQVJsQyxpQkFBaUIsYUFLakIsaUJBQWlCO3VIQUdSLHlCQUF5QixZQU4zQixFQUNSOzJGQUtVLHlCQUF5QjtrQkFWckMsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUU7d0JBQ1osaUJBQWlCO3FCQUNsQjtvQkFDRCxPQUFPLEVBQUUsRUFDUjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsaUJBQWlCO3FCQUNsQjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQYXJhbGxheERpcmVjdGl2ZSB9IGZyb20gJy4vcGFyYWxsYXguZGlyZWN0aXZlJztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgUGFyYWxsYXhEaXJlY3RpdmVcbiAgXSxcbiAgaW1wb3J0czogW1xuICBdLFxuICBleHBvcnRzOiBbXG4gICAgUGFyYWxsYXhEaXJlY3RpdmVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBJb25pY0hlYWRlclBhcmFsbGF4TW9kdWxlIHsgfVxuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW9uaWMtaGVhZGVyLXBhcmFsbGF4Lm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2lvbmljLWhlYWRlci1wYXJhbGxheC9zcmMvbGliL2lvbmljLWhlYWRlci1wYXJhbGxheC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7QUFZdEUsTUFBTSxPQUFPLHlCQUF5Qjs7c0hBQXpCLHlCQUF5Qjt1SEFBekIseUJBQXlCLGlCQVJsQyxpQkFBaUIsYUFLakIsaUJBQWlCO3VIQUdSLHlCQUF5QixZQU4zQixFQUNSOzJGQUtVLHlCQUF5QjtrQkFWckMsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUU7d0JBQ1osaUJBQWlCO3FCQUNsQjtvQkFDRCxPQUFPLEVBQUUsRUFDUjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsaUJBQWlCO3FCQUNsQjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQYXJhbGxheERpcmVjdGl2ZSB9IGZyb20gJy4vaW9uaWMtaGVhZGVyLXBhcmFsbGF4LmRpcmVjdGl2ZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFBhcmFsbGF4RGlyZWN0aXZlXG4gIF0sXG4gIGltcG9ydHM6IFtcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIFBhcmFsbGF4RGlyZWN0aXZlXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgSW9uaWNIZWFkZXJQYXJhbGxheE1vZHVsZSB7IH1cbiJdfQ==
/*
* Public API Surface of ionic-header-parallax
*/
export * from './lib/ionic-header-parallax.directive';
export * from './lib/ionic-header-parallax.module';
export * from './lib/parallax.directive';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2lvbmljLWhlYWRlci1wYXJhbGxheC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYywwQkFBMEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2YgaW9uaWMtaGVhZGVyLXBhcmFsbGF4XG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9saWIvaW9uaWMtaGVhZGVyLXBhcmFsbGF4Lm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9wYXJhbGxheC5kaXJlY3RpdmUnOyJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2lvbmljLWhlYWRlci1wYXJhbGxheC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyxvQ0FBb0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2YgaW9uaWMtaGVhZGVyLXBhcmFsbGF4XG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9saWIvaW9uaWMtaGVhZGVyLXBhcmFsbGF4LmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9pb25pYy1oZWFkZXItcGFyYWxsYXgubW9kdWxlJztcbiJdfQ==
import * as i0 from '@angular/core';
import { Directive, Input, NgModule } from '@angular/core';
import { Directive, Input, ContentChild, ContentChildren, NgModule } from '@angular/core';
import { IonTitle, IonToolbar, IonButtons } from '@ionic/angular';

@@ -8,184 +9,133 @@ class ParallaxDirective {

this.renderer = renderer;
this.maximumHeight = 300;
this.height = 300;
this.bgPosition = 'top';
this.originalToolbarHeight = 0;
this.ticking = false;
}
ngAfterViewInit() {
ngAfterContentInit() {
setTimeout(() => {
try {
this.initElements();
this.initStyles();
this.initEvents();
if (this.initElements()) {
this.setupContentPadding();
this.setupImageOverlay();
this.setupEvents();
this.updateProgress();
}
}
catch (e) {
this.ngAfterViewInit();
this.ngAfterContentInit();
}
}, 100);
}
get header() {
return this.headerRef.nativeElement;
}
/**
* Return the value of the input parameter `height` as a string with units.
* If no units were provided, it will default to 'px'.
*/
getMaxHeightWithUnits() {
return !isNaN(+this.height) || typeof this.height === 'number'
? this.height + 'px'
: this.height;
}
initElements() {
const parentElement = this.headerRef.nativeElement.parentElement;
this.header = this.headerRef.nativeElement;
this.toolbar = this.header.querySelector('ion-toolbar');
if (!this.toolbar) {
throw new Error('Parallax directive requires a toolbar or navbar element on the page to work.');
if (!this.ionToolbar) {
console.error('A <ion-toolbar> element is needed inside <ion-header>');
return false;
}
this.ionTitle = this.toolbar.querySelector('ion-title');
this.toolbarBackground = this.toolbar.shadowRoot.querySelector('.toolbar-background');
this.barButtons = this.headerRef.nativeElement.querySelector('ion-buttons');
const parentElement = this.header.parentElement;
const ionContent = parentElement.querySelector('ion-content');
this.scrollContent = ionContent.shadowRoot.querySelector('.inner-scroll');
if (!this.scrollContent) {
throw new Error('Parallax directive requires an <ion-content> element on the page to work.');
if (!ionContent) {
console.error('A <ion-content> element is needed');
return false;
}
// Create image overlay
this.innerScroll = ionContent.shadowRoot.querySelector('.inner-scroll');
this.originalToolbarHeight = this.ionToolbar.el.offsetHeight;
this.toolbarContainer =
this.ionToolbar.el.shadowRoot.querySelector('.toolbar-container');
this.toolbarBackground = this.ionToolbar.el.shadowRoot.querySelector('.toolbar-background');
this.color = this.color || window.getComputedStyle(this.toolbarBackground).backgroundColor;
this.renderer.setStyle(this.header, 'pointer-events', 'none');
this.renderer.setStyle(this.toolbarContainer, 'pointer-events', 'all');
this.renderer.setStyle(this.toolbarContainer, 'align-items', 'baseline');
return true;
}
setupContentPadding() {
const parentElement = this.header.parentElement;
const ionContent = parentElement.querySelector('ion-content');
const mainContent = ionContent.shadowRoot.querySelector('main');
const { paddingTop } = window.getComputedStyle(mainContent);
const calc = `calc(${paddingTop} + ${this.getMaxHeightWithUnits()})`;
this.renderer.setStyle(this.header, 'position', 'absolute');
this.renderer.setStyle(this.innerScroll, 'padding-top', calc);
}
setupImageOverlay() {
this.imageOverlay = this.renderer.createElement('div');
this.renderer.addClass(this.imageOverlay, 'image-overlay');
this.colorOverlay = this.renderer.createElement('div');
this.renderer.addClass(this.colorOverlay, 'color-overlay');
this.colorOverlay.appendChild(this.imageOverlay);
this.header.appendChild(this.colorOverlay);
// Copy title and buttons
this.overlayTitle = this.ionTitle && this.ionTitle.cloneNode(true);
if (this.overlayTitle) {
this.renderer.addClass(this.overlayTitle, 'parallax-title');
setTimeout(() => {
const toolbarTitle = this.overlayTitle.shadowRoot.querySelector('.toolbar-title');
this.renderer.setStyle(toolbarTitle, 'pointer-events', 'unset');
});
}
if (this.overlayTitle) {
this.imageOverlay.appendChild(this.overlayTitle);
}
if (this.barButtons) {
this.imageOverlay.appendChild(this.barButtons);
}
}
initStyles() {
this.headerHeight = this.scrollContent.clientHeight;
this.ticking = false;
if (!this.scrollContent || !toolbar) {
return;
}
// fetch styles
this.maximumHeight = parseFloat(this.maximumHeight.toString());
this.headerMinHeight = this.toolbar.offsetHeight;
this.scrollContentPaddingTop = window.getComputedStyle(this.scrollContent, null).paddingTop.replace('px', '');
this.scrollContentPaddingTop = parseFloat(this.scrollContentPaddingTop);
this.originalToolbarBgColor = window.getComputedStyle(this.toolbarBackground, null).backgroundColor;
if (!this.originalToolbarBgColor) {
throw new Error('Error: toolbarBackround is null.');
}
// header and title
this.renderer.setStyle(this.header, 'position', 'relative');
if (this.overlayTitle) {
this.renderer.setStyle(this.overlayTitle, 'color', this.titleColor);
this.renderer.setStyle(this.overlayTitle, 'position', 'absolute');
this.renderer.setStyle(this.overlayTitle, 'width', '100%');
this.renderer.setStyle(this.overlayTitle, 'height', '100%');
this.renderer.setStyle(this.overlayTitle, 'text-align', 'center');
}
// color overlay
this.renderer.setStyle(this.colorOverlay, 'background-color', this.originalToolbarBgColor);
this.renderer.setStyle(this.colorOverlay, 'height', `${this.maximumHeight}px`);
this.renderer.setStyle(this.colorOverlay, 'position', 'absolute');
this.renderer.setStyle(this.colorOverlay, 'top', `${-this.headerMinHeight * 0}px`);
this.renderer.setStyle(this.colorOverlay, 'left', '0');
this.renderer.setStyle(this.colorOverlay, 'width', '100%');
this.renderer.setStyle(this.colorOverlay, 'z-index', '10');
this.renderer.setStyle(this.colorOverlay, 'pointer-events', 'none');
// image overlay
this.renderer.setStyle(this.imageOverlay, 'background-color', this.expandedColor);
this.renderer.setStyle(this.imageOverlay, 'background-color', this.color);
this.renderer.setStyle(this.imageOverlay, 'background-image', `url(${this.imageUrl || ''})`);
this.renderer.setStyle(this.imageOverlay, 'height', `100%`);
this.renderer.setStyle(this.imageOverlay, 'width', '100%');
this.renderer.setStyle(this.imageOverlay, 'pointer-events', 'none');
this.renderer.setStyle(this.imageOverlay, 'background-size', 'cover');
this.renderer.setStyle(this.imageOverlay, 'background-position', 'center');
// .toolbar-background
this.renderer.setStyle(this.toolbarBackground, 'background-color', this.originalToolbarBgColor);
// .bar-buttons
if (this.barButtons) {
this.renderer.setStyle(this.barButtons, 'pointer-events', 'all');
Array.from(this.barButtons.children).forEach(btn => {
this.renderer.setStyle(btn, 'color', this.titleColor);
});
}
// .scroll-content
if (this.scrollContent) {
this.renderer.setAttribute(this.scrollContent, 'parallax', '');
this.renderer.setStyle(this.scrollContent, 'padding-top', `${this.maximumHeight + this.scrollContentPaddingTop - this.headerMinHeight}px`);
}
this.renderer.setStyle(this.imageOverlay, 'background-position', this.bgPosition);
this.toolbarBackground.appendChild(this.imageOverlay);
}
initEvents() {
window.addEventListener('resize', () => {
this.headerHeight = this.scrollContent.clientHeight;
}, false);
if (this.scrollContent) {
this.scrollContent.addEventListener('scroll', (e) => {
if (!this.ticking) {
window.requestAnimationFrame(() => {
this.updateElasticHeader();
});
}
this.ticking = true;
});
}
}
updateElasticHeader() {
if (!this.scrollContent || !toolbar) {
return;
}
this.scrollTop = this.scrollContent.scrollTop;
if (this.scrollTop >= 0) {
this.translateAmt = this.scrollTop / 2;
this.scaleAmt = 1;
}
else {
this.translateAmt = 0;
this.scaleAmt = -this.scrollTop / this.headerHeight + 1;
}
// Parallax total progress
this.headerMinHeight = this.toolbar.offsetHeight;
let progress = (this.maximumHeight - this.scrollTop - this.headerMinHeight) / (this.maximumHeight - this.headerMinHeight);
progress = Math.max(progress, 0);
// ion-header: set height
let targetHeight = this.maximumHeight - this.scrollTop;
targetHeight = Math.max(targetHeight, this.headerMinHeight);
// .toolbar-background: change color
this.renderer.setStyle(this.imageOverlay, 'height', `${targetHeight}px`);
this.renderer.setStyle(this.imageOverlay, 'opacity', `${progress}`);
this.renderer.setStyle(this.colorOverlay, 'height', `${targetHeight}px`);
this.renderer.setStyle(this.colorOverlay, 'opacity', targetHeight > this.headerMinHeight ? '1' : '0');
this.renderer.setStyle(this.toolbarBackground, 'background-color', targetHeight > this.headerMinHeight ? 'transparent' : this.originalToolbarBgColor);
// .bar-buttons
if (this.barButtons) {
if (targetHeight > this.headerMinHeight) {
this.imageOverlay.append(this.barButtons);
Array.from(this.barButtons.children).forEach(btn => {
this.renderer.setStyle(btn, 'color', this.titleColor);
setupEvents() {
this.innerScroll.addEventListener('scroll', (_event) => {
if (!this.ticking) {
window.requestAnimationFrame(() => {
this.updateProgress();
this.ticking = false;
});
}
else {
this.toolbar.append(this.barButtons);
Array.from(this.barButtons.children).forEach(btn => {
this.renderer.setStyle(btn, 'color', 'unset');
});
}
}
this.ticking = false;
this.ticking = true;
});
}
/** Update the parallax effect as per the current scroll of the ion-content */
updateProgress() {
const progress = this.calcProgress(this.innerScroll, +this.height);
this.progressLayerHeight(progress);
this.progressLayerOpacity(progress);
}
progressLayerHeight(progress) {
const h = Math.max(+this.height * (1 - progress), this.originalToolbarHeight);
this.renderer.setStyle(this.toolbarContainer, 'height', `${h}px`);
this.renderer.setStyle(this.imageOverlay, 'height', `${h}px`);
}
progressLayerOpacity(progress) {
const op = 1 - progress;
this.renderer.setStyle(this.imageOverlay, 'opacity', op);
// this.renderer.setStyle(this.toolbarContainer, 'opacity', progress);
}
calcProgress(scrollingElement, maxHeight) {
const scroll = +scrollingElement.scrollTop;
const progress = Math.min(1, Math.max(0, scroll / maxHeight));
return progress;
}
}
ParallaxDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ParallaxDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
ParallaxDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ParallaxDirective, selector: "ion-header[parallax]", inputs: { imageUrl: "imageUrl", expandedColor: "expandedColor", titleColor: "titleColor", maximumHeight: "maximumHeight" }, ngImport: i0 });
ParallaxDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ParallaxDirective, selector: "ion-header[parallax]", inputs: { imageUrl: "imageUrl", color: "color", height: "height", bgPosition: "bgPosition" }, queries: [{ propertyName: "ionTitle", first: true, predicate: IonTitle, descendants: true }, { propertyName: "ionToolbar", first: true, predicate: IonToolbar, descendants: true }, { propertyName: "ionButtons", predicate: IonButtons }], ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ParallaxDirective, decorators: [{
type: Directive,
args: [{
selector: 'ion-header[parallax]'
selector: 'ion-header[parallax]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { imageUrl: [{
type: Input
}], expandedColor: [{
}], color: [{
type: Input
}], titleColor: [{
}], height: [{
type: Input
}], maximumHeight: [{
}], bgPosition: [{
type: Input
}], ionTitle: [{
type: ContentChild,
args: [IonTitle, { static: false }]
}], ionToolbar: [{
type: ContentChild,
args: [IonToolbar, { static: false }]
}], ionButtons: [{
type: ContentChildren,
args: [IonButtons]
}] } });

@@ -192,0 +142,0 @@

import * as i0 from "@angular/core";
import * as i1 from "./parallax.directive";
import * as i1 from "./ionic-header-parallax.directive";
export declare class IonicHeaderParallaxModule {

@@ -4,0 +4,0 @@ static ɵfac: i0.ɵɵFactoryDeclaration<IonicHeaderParallaxModule, never>;

{
"name": "ionic-header-parallax",
"version": "3.0.0-dev",
"version": "3.0.2",
"description": "This directive enables parallax effect on `ion-header` elements to display a cover photo while on top of the page and transition it to the normal navbar when content is scrolled down.",
"main": "bundles/ionic-header-parallax.umd.js",
"peerDependencies": {

@@ -29,2 +28,3 @@ "@angular/common": "^12.0.2",

"homepage": "https://github.com/raschidJFR/ionic-header-parallax#readme",
"main": "bundles/ionic-header-parallax.umd.js",
"module": "fesm2015/ionic-header-parallax.js",

@@ -31,0 +31,0 @@ "es2015": "fesm2015/ionic-header-parallax.js",

@@ -0,2 +1,2 @@

export * from './lib/ionic-header-parallax.directive';
export * from './lib/ionic-header-parallax.module';
export * from './lib/parallax.directive';

@@ -1,13 +0,13 @@

# Parallax Header Directive for Ionic v4 #
# Parallax Header Directive for Ionic
This directive enables parallax effect on `ion-header` elements to display a cover photo while on top of the page and transition it to the normal navbar when content is scrolled down.
> For Ionic 3 use version [1.1.0](https://www.npmjs.com/package/ionic-header-parallax/v/1.1.0) of this package: `$ npm i ionic-header-parallax@1.1.0`.
> For Ionic versions `< 5`, check the [previous tags](https://www.npmjs.com/package/ionic-header-parallax?activeTab=versions) of this packate.
* [Live Demo](https://raschidjfr.github.io/ionic-header-parallax)
* [Code Playground](https://stackblitz.com/github/raschidjfr/ionic-header-parallax?file=src%2Fapp%2Fhome%2Fhome.page.html)
- [Live Demo](https://raschidjfr.github.io/ionic-header-parallax)
- [Code Playground](https://stackblitz.com/github/raschidjfr/ionic-header-parallax?file=src%2Fapp%2Fhome%2Fhome.page.html)
![alt text](https://raw.githubusercontent.com/raschidJFR/ionic-header-parallax/master/gif.gif)
## Set Up ##
## Set Up

@@ -26,3 +26,3 @@ 1. Install package: `$ npm i ionic-header-parallax`.

## Usage ##
## Usage

@@ -32,30 +32,20 @@ Just add the attribute `parallax` to any `<ion-header>` element:

```html
<ion-header parallax></ion-header>
```
Optional attributes:
* `imageUrl (string)`: The background image to show while expanded.
* `maximumHeight (number)`: The height for the header when expanded. Default is `200`.
* `expandedColor (string)`: The color (web hex formatted) to show while the header is expanded when no `imageUrl` is set. When scrolled it will fade to the navbar/toolbar's color or the one configured in `<toolbar color="">` attribute.
* `titleColor (string)`: The text color (web hex formatted) for `<ion-title>` and `<ion-back-button>` elements when expanded. They will turn to their default color on cover collapse.
Example:
```html
<ion-header parallax imageUrl="https://picsum.photos/350" maximumHeight="350" expandedColor="#AAA" titleColor="white">
<ion-header parallax imageUrl="https://picsum.photos/350" height="350" bgPosition="top">
<ion-toolbar color="primary">
<ion-title>
Parallax Header
</ion-title>
<ion-title> Parallax Header </ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
Some content here
</ion-content>
<ion-content> Some content here </ion-content>
```
## Modifying the Source Code / Contributing ##
| Parameter | Description |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `imageUrl (string)` | The background image to show while expanded. |
| `height (number \| string)` | The height for the header when expanded. If the value is a number, it will be set in `px`. If the value is a string it will be passed as is (eg: `"20rem"`) |
| `color (string)` | The color (web hex formatted) to show while the header is expanded when no `imageUrl` is set. When scrolled it will fade to the toolbar's color. |
| `bgPosition ('top' \| 'center' \| 'bottom')` | The position of the image in the header. This parameter slightly changes the feeling of the animation. |
## Source Code / Contributing
I don't plan to be maintaining this package full-time, but as I'm usually developing in Ionic I'll be glad to update it any time I make some upgrades for myself.

@@ -66,9 +56,8 @@ Contributions are very welcome. Find the instructions in the [CONTRIBUTING.md](CONTRIBUTING.md) file.

## Credits ##
## Credits
Raschid JF. Rafaelly
<me@raschidjfr.dev>
<hello@raschidjfr.dev>
<https://raschidjfr.dev>
This is an adaptation of this awesome tutorial on v2 by [Josh Morony](https://www.joshmorony.com/how-to-create-a-directive-in-ionic-2-parallax-header/). Thanks.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc