controllers/element-visible-controller.js
function ElementVisibleController(elem, options) {
  if (!(this instanceof ElementVisibleController)) {
    return new ElementVisibleController(elem, options);
  }

  Emitter.mixin(this);

  options = options || {};

  this.elem = elem;
  this.buffer = Util.getOption(options.buffer, 0);
  this.isVisible = false;
  this.rect = null;
  this.scrollTarget = options.scrollTarget;

  // Auto trigger if the last value on the stream is what we're looking for.
  var oldOn = this.on;
  this.on = function wrappedOn(eventName, callback, scope) {
    oldOn.apply(this, arguments);

    if (('enter' === eventName) && this.isVisible) {
      scope ? callback.call(scope) : callback();
    }
  };

  var sc = new ScrollController({
    scrollTarget: this.scrollTarget
  });

  sc.on('scroll', this.didScroll, this);
  sc.on('scrollEnd', this.recalculatePosition, this);

  Stream.onValue(ResizeStream.create(), Util.functionBind(this.didResize, this));

  this.viewportRect = {
    height: window.innerHeight,
    top: 0
  };

  this.recalculateOffsets();
  setTimeout(Util.functionBind(this.recalculateOffsets, this), 100);
}
function ElementVisibleController(elem, options) {
  if (!(this instanceof ElementVisibleController)) {
    return new ElementVisibleController(elem, options);
  }

  Emitter.mixin(this);

  options = options || {};

  this.elem = elem;
  this.buffer = Util.getOption(options.buffer, 0);
  this.isVisible = false;
  this.rect = null;
  this.scrollTarget = options.scrollTarget;

  // Auto trigger if the last value on the stream is what we're looking for.
  var oldOn = this.on;
  this.on = function wrappedOn(eventName, callback, scope) {
    oldOn.apply(this, arguments);

    if (('enter' === eventName) && this.isVisible) {
      scope ? callback.call(scope) : callback();
    }
  };

  var sc = new ScrollController({
    scrollTarget: this.scrollTarget
  });

  sc.on('scroll', this.didScroll, this);
  sc.on('scrollEnd', this.recalculatePosition, this);

  Stream.onValue(ResizeStream.create(), Util.functionBind(this.didResize, this));

  this.viewportRect = {
    height: window.innerHeight,
    top: 0
  };

  this.recalculateOffsets();
  setTimeout(Util.functionBind(this.recalculateOffsets, this), 100);
}
function ElementVisibleController ( elem , options ) { if ( ! ( this instanceof ElementVisibleController ) ) { return new ElementVisibleController ( elem , options ) ; } Emitter . mixin ( this ) ; options = options || { } ; this . elem = elem ; this . buffer = Util . getOption ( options . buffer , 0 ) ; this . isVisible = false ; this . rect = null ; this . scrollTarget = options . scrollTarget ; // Auto trigger if the last value on the stream is what we're looking for. var oldOn = this . on ; this . on = function wrappedOn ( eventName , callback , scope ) { oldOn . apply ( this , arguments ) ; if ( ( 'enter' === eventName ) && this . isVisible ) { scope ? callback . call ( scope ) : callback ( ) ; } } ; var sc = new ScrollController ( { scrollTarget : this . scrollTarget } ) ; sc . on ( 'scroll' , this . didScroll , this ) ; sc . on ( 'scrollEnd' , this . recalculatePosition , this ) ; Stream . onValue ( ResizeStream . create ( ) , Util . functionBind ( this . didResize , this ) ) ; this . viewportRect = { height : window . innerHeight , top : 0 } ; this . recalculateOffsets ( ) ; setTimeout ( Util . functionBind ( this . recalculateOffsets , this ) , 100 ) ; }
Provides a familiar OO-style API for tracking element position.
@constructor
@param {Element} elem The element to track
@param {Object=} options The options passed to the position tracker.
@return {Object} The API with a `on` function to attach scrollEnd
callbacks and an `observeElement` function to detect when elements
enter and exist the viewport.
Provides a familiar OO - style API for tracking element position .