code: 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);
  }
docs: 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.