Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ionic 2: How to make a sliding menu from the bottom

Well, I'm not sure if it would exactly be considered a sliding menu. It isn't for navigation, it would hold data. My inspiration came from Apple Maps:

Example 1

Example 2

So I want to be able to slide it up and down as needed and to be able to scroll through the content that is shown in the first picture. Also, is there any way to do that diffusing light/blur effect with a map?

like image 238
Sam McC Avatar asked Mar 14 '17 18:03

Sam McC


People also ask

How do I add the menu bar in ionic?

To add a menu to an app, the <ion-menu> element should be added as a sibling to the ion-nav it will belongs to. A local variable should be added to the ion-nav and passed to the ion-menu s content property.


1 Answers

There's an awesome post from Josh Morony about something very similar to that here. This is the result:

enter image description here

Here you can find the source code and how to use it. The most relevant parts are:

Component code:

import { Component, Input, ElementRef, Renderer } from '@angular/core';
import { Platform, DomController } from 'ionic-angular';

@Component({
  selector: 'content-drawer',
  templateUrl: 'content-drawer.html'
})
export class ContentDrawer {

  @Input('options') options: any;

  handleHeight: number = 50;
  bounceBack: boolean = true;
  thresholdTop: number = 200;
  thresholdBottom: number = 200;

  constructor(public element: ElementRef, public renderer: Renderer, public domCtrl: DomController, public platform: Platform) {

  }

  ngAfterViewInit() {

    if(this.options.handleHeight){
      this.handleHeight = this.options.handleHeight;
    }

    if(this.options.bounceBack){
      this.bounceBack = this.options.bounceBack;
    }

    if(this.options.thresholdFromBottom){
      this.thresholdBottom = this.options.thresholdFromBottom;
    }

    if(this.options.thresholdFromTop){
      this.thresholdTop = this.options.thresholdFromTop;
    }

    this.renderer.setElementStyle(this.element.nativeElement, 'top', this.platform.height() - this.handleHeight + 'px');
    this.renderer.setElementStyle(this.element.nativeElement, 'padding-top', this.handleHeight + 'px');

    let hammer = new window['Hammer'](this.element.nativeElement);
    hammer.get('pan').set({ direction: window['Hammer'].DIRECTION_VERTICAL });

    hammer.on('pan', (ev) => {
      this.handlePan(ev);
    });

  }

  handlePan(ev){

    let newTop = ev.center.y;

    let bounceToBottom = false;
    let bounceToTop = false;

    if(this.bounceBack && ev.isFinal){

      let topDiff = newTop - this.thresholdTop;
      let bottomDiff = (this.platform.height() - this.thresholdBottom) - newTop;      

      topDiff >= bottomDiff ? bounceToBottom = true : bounceToTop = true;

    }

    if((newTop < this.thresholdTop && ev.additionalEvent === "panup") || bounceToTop){

      this.domCtrl.write(() => {
        this.renderer.setElementStyle(this.element.nativeElement, 'transition', 'top 0.5s');
        this.renderer.setElementStyle(this.element.nativeElement, 'top', '0px');
      });

    } else if(((this.platform.height() - newTop) < this.thresholdBottom && ev.additionalEvent === "pandown") || bounceToBottom){

      this.domCtrl.write(() => {
        this.renderer.setElementStyle(this.element.nativeElement, 'transition', 'top 0.5s');
        this.renderer.setElementStyle(this.element.nativeElement, 'top', this.platform.height() - this.handleHeight + 'px');
      });

    } else {

      this.renderer.setElementStyle(this.element.nativeElement, 'transition', 'none');

      if(newTop > 0 && newTop < (this.platform.height() - this.handleHeight)) {

        if(ev.additionalEvent === "panup" || ev.additionalEvent === "pandown"){

          this.domCtrl.write(() => {
            this.renderer.setElementStyle(this.element.nativeElement, 'top', newTop + 'px');
          });

        }

      }

    }

  }

}

View:

<ion-content>
    <ng-content></ng-content>
</ion-content>

Styles:

.ios, .md {

    content-drawer {

        width: 100%;
        height: 100%;
        position: absolute;
        z-index: 10 !important;
        box-shadow: 0px -4px 22px -8px rgba(0,0,0,0.75);

    }

}

An then use it in your page like this:

HomePage:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

    drawerOptions: any;

    constructor(public navCtrl: NavController) {

        this.drawerOptions = {
            handleHeight: 50,
            thresholdFromBottom: 200,
            thresholdFromTop: 200,
            bounceBack: true
        };

    }

}

View:

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  The world is your oyster.
  <p>
    If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide.
  </p>
</ion-content>

<content-drawer [options]="drawerOptions">
    <div class="content">
      The world is your oyster.
      <p>
        If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide.
      </p>
    </div>
</content-drawer>

Styles:

.ios, .md {

    page-home {

        content-drawer {
            background-color: #34495e !important;
        }

        content-drawer .content {
            padding: 20px;
        }

    }

}
like image 184
sebaferreras Avatar answered Sep 30 '22 05:09

sebaferreras