Page 1 of 1

[EOS/CODE] Fading an Audio play action's volume in and out

Posted: Wed May 19, 2021 3:17 pm
by fapnip
Here's a demo that adds a "fadeTo" method to Eos Sound objects allowing you to fade volume in and out:

Demo URL:
https://milovana.com/webteases/showteas ... d056925dc0

Demo JSON (right-click save-as):
https://milovana.com/webteases/geteossc ... d056925dc0

To install the fadeTo method in your own tease, you'll need the "1-minute-of-silence.mp3" file, and the first two IF actions in the start page of the demo.

Example use:

Code: Select all

// If we haven't loaded our sound into a global variable, do it now
if (!window.mySound) window.mySound = Sound.get('test')

mySound.fadeTo(1, 2000) // fade to full volume over 2 seconds
Changelog:
Spoiler: show
v1.0 - Initial release
v1.1 - Fixed bug in setVolume hook.
Source code (requires setTimeout/setInterval polyfill!):
Spoiler: show

Code: Select all

// Install Sound.prototype.fadeTo
(function() {
  // Get out if we're already installed
  if (Sound.prototype.fadeTo) return

  var defaultVolume = 0 // If we don't know the current volume, assume this
  var stepSize = 20 // ms between volume change steps

  // Hook existing setVolume to do some stuff
  Sound.prototype._ft_setVolume = Sound.prototype.setVolume
  Sound.prototype.setVolume = function(vol) {
    this._ft_cv = vol
    this._ft_setVolume(vol)
    clearInterval(this._ft_interval)
  }
  
  // Add a fadeTo function to Sound prototype
  Sound.prototype.fadeTo = function(volume, time) {
    volume = volume > 1 ? 1 : volume
    volume = volume < 0 ? 0 : volume
    this._ft_cv = this._ft_cv === undefined ? defaultVolume : this._ft_cv
    clearInterval(this._ft_interval)
    var step = 0
    var steps = time / stepSize
    var diff = volume - this._ft_cv
    var inc = diff / steps
    var _this = this
    function stepper() {
      step ++
      var v = _this._ft_cv + inc
      if ((inc > 0 && v >= volume) || 
        (inc < 0 && v <= volume) || 
        step >= steps) {
          v = volume
      }
      _this._ft_cv = v
      _this._ft_setVolume(v)
      if (step >= steps) {
        clearInterval(_this._ft_interval)
      }
    }
    this._ft_interval = setInterval(stepper, stepSize)
    stepper()
  }
})()