Connect with:
About Me
Alessandro Annini
I'm a freelance developer currently working at Leaff.it/ I really love famo.us framework and its amazing potential and if you're like me, and you want the web to win, please share some snippet of code for the community and grow faster with us
Categories
Meta
Famo.us Code | Sidepanel-swiper component
274
post-template-default,single,single-post,postid-274,single-format-standard,ajax_updown_fade,page_not_loaded,,qode-theme-ver-6.2.1

Sidepanel-swiper component

30 Jun Sidepanel-swiper component

Thanks to markmarijnissen

 

The Complete gist from markmarijnissen

var View          = require('famous/core/View');
var Engine        = require('famous/core/Engine');
var Modifier        = require('famous/core/Modifier');
var Transform       = require('famous/core/Transform');
var StateModifier   = require('famous/modifiers/StateModifier');
var Easing          = require('famous/transitions/Easing');
var Transitionable  = require('famous/transitions/Transitionable');
var GenericSync     = require('famous/inputs/GenericSync');

/**
 A typical sidepanel that swipes from the left.

 emits:
    'sidepanel': true (opened) | false (closed)
    'opening'
    'closing'
  

 listens to & public API:
    open(<boolean> value): true (open) | false (close) | null (toggle)

 **/
function SidepanelLayout(options) {
    View.apply(this, arguments);
    Engine.emit('created',this);

    // show sidepanel or not...
    this.opened = false;
    // position content X
    this.contentPos = new Transitionable(0);

    window.contentPos = this.contentPos;

    // Add sidepanel and content
    if(!!options.sidepanel) {
      _addSidepanel.call(this,options.sidepanel);
    } else {
      Engine.emit('error',{target:this,message:'No sidepanel!'});
    }
    if(!!options.content) {
      _addContent.call(this,options.content);
    } else {
      Engine.emit('error',{target:this,message:'No content!'});
    }

    // handle Swipe
    _handleSwipe.call(this);

    // handle events
    this._eventInput.on('open',this.open);

}
SidepanelLayout.prototype = Object.create(View.prototype);
SidepanelLayout.prototype.constructor = SidepanelLayout;

SidepanelLayout.DEFAULT_OPTIONS = {
  sidepanel: null,    //RenderNode for sidepanel
  content: null,      //Rendernode for content

  maxPos: 1e4,
  width: 225,  //How much should content move?
  transition: {
      duration: 300,
      curve: 'easeOut'
  },
  posThreshold: 138,  //When should sidepanel open?
  velThreshold: 0.75  //When should sidepanel open?

};

SidepanelLayout.prototype.open = function(value) {
  if(value !== false && value !== true) value = !this.opened;
  if(value !== this.opened) {
    if(value) {
      _open.call(this);
    } else {
      _close.call(this);
    }
  }
};

function _open() {
  this._eventOutput.emit('opening');
  this.contentPos.set(this.options.width, this.options.transition, function() {
      this.opened = true;
      this._eventOutput.emit('sidepanel',true);
  }.bind(this));
}

function _close() {
  this._eventOutput.emit('closing');
  this.contentPos.set(0, this.options.transition, function() {
      this.opened = false;
      this._eventOutput.emit('sidepanel',false);
  }.bind(this));
}

function _handleSwipe() {
  var sync = new GenericSync(
      ['mouse', 'touch'],
      {direction : GenericSync.DIRECTION_X}
  );

  // Listen to touch events from CONTENT to swipe to Sidepanel!
  this.content.pipe(sync);

  sync.on('update', function(data) {
      var currentPosition = this.contentPos.get();
      var position = Math.max(0, currentPosition + data.delta);
      position = Math.min(this.options.maxPos,position);
      this.contentPos.set(position);
  }.bind(this));

  sync.on('end', (function(data) {
      var velocity = data.velocity;
      var position = this.contentPos.get();

      if(this.contentPos.get() > this.options.posThreshold) {
          if(velocity < -this.options.velThreshold) {
              _close.call(this);
          } else {
              _open.call(this);
          }
      } else {
          if(velocity > this.options.velThreshold) {
              _open.call(this);
          } else {
              _close.call(this);
          }
      }
  }).bind(this));
}

function _addContent(content) {
  this.content = content;
  this.contentMod = new Modifier({
    transform: function() {
        return Transform.translate(this.contentPos.get(), 0, 0);
    }.bind(this)
  });
  this.add(this.contentMod).add(content);
}

function _addSidepanel(sidepanel) {
  this.sidepanel = sidepanel;
  this.sidepanelMod = new StateModifier({
    transform: Transform.behind,
    size: [undefined,undefined]
  });
  this.add(this.sidepanelMod).add(sidepanel);
}



module.exports = SidepanelLayout;