[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/js/core/ -> behavior-audio-source.js (source)

   1  /**
   2   * @provides javelin-behavior-audio-source
   3   * @requires javelin-behavior
   4   *           javelin-stratcom
   5   *           javelin-vector
   6   *           javelin-dom
   7   * @javelin
   8   */
   9  
  10  /**
  11   * Allows an element to behave as an audio source. It plays a sound either
  12   * when the user scrolls it into view, or loops a sound which gets louder and
  13   * louder as the user gets closer.
  14   */
  15  JX.behavior('audio-source', function(config, statics) {
  16    if (!window.Audio) {
  17      return;
  18    }
  19  
  20    var audio = new Audio();
  21    audio.setAttribute('src', config.audioURI);
  22  
  23    if (config.loop) {
  24      audio.setAttribute('loop', true);
  25    }
  26  
  27    audio.load();
  28  
  29    config.audio = audio;
  30  
  31    statics.items = statics.items || [];
  32    statics.items.push(config);
  33  
  34    if (statics.initialized) {
  35      return;
  36    }
  37    statics.initialized = true;
  38  
  39    var onupdate = function() {
  40      timeout = null;
  41  
  42      var scroll = JX.Vector.getScroll();
  43      var view = JX.Vector.getViewport();
  44      var view_mid = scroll.y + (view.y / 2);
  45  
  46      for (var ii = 0; ii < statics.items.length; ii++) {
  47        var item = statics.items[ii];
  48        if (!item.element) {
  49          try {
  50            item.element = JX.$(item.sourceID);
  51          } catch (ignored) {
  52            continue;
  53          }
  54        }
  55  
  56        var pos = JX.Vector.getPos(statics.items[ii].element);
  57        var dim = JX.Vector.getDim(statics.items[ii].element);
  58  
  59        var item_mid = pos.y + (dim.y / 2);
  60        var item_distance = Math.abs(item_mid - view_mid);
  61  
  62        // item_distance is the number of pixels between the vertical middle
  63        // of the macro and the vertical middle of the viewport. We divide it
  64        // by the viewport height to get the "number of viewports" away from
  65        // the middle we are, then map that to [0, 1], where 0 means that the
  66        // image is far away from the viewport and 1 means the image is pretty
  67        // much in the middle of the viewport.
  68  
  69        var near = 1.25 - ((item_distance / view.y) * 1.25);
  70        near = Math.max(0, near);
  71        near = Math.min(1, near);
  72  
  73        if (near === 0) {
  74          if (item.playing) {
  75            item.audio.pause();
  76            item.playing = false;
  77  
  78            // If this isn't an ambient/looping sound, it only gets to fire
  79            // once. Even if it didn't finish, throw it out.
  80            if (!item.loop) {
  81              statics.items.splice(ii, 1);
  82              ii--;
  83            }
  84          }
  85          continue;
  86        } else {
  87          if (!item.playing) {
  88            if (!item.loop && near < 1) {
  89              // Don't start playing one-shot items until they're solidly on
  90              // screen.
  91              continue;
  92            }
  93            item.audio.volume = near;
  94            item.playing = true;
  95            item.audio.play();
  96          } else {
  97            item.audio.volume = near;
  98          }
  99        }
 100      }
 101  
 102    };
 103  
 104    var timeout;
 105    var onadjust = function() {
 106      timeout && clearTimeout(timeout);
 107      timeout = setTimeout(onupdate, 200);
 108    };
 109  
 110    JX.Stratcom.listen(['scroll', 'resize'], null, onadjust);
 111    onadjust();
 112  
 113  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1