Preform fade using a button?

Is is possible to perform a MIDI CC fade using only a button?
To be able to set this (somehow):

FadeFrom: 0
FadeTo: 127
FadeDuration: 1000ms

It's not perfect, but i would do something like that :

if(value)
{
  set("fader",0)
   locals.Monte=setInterval(()=>{set("fader",get('fader')+1)},8) 
   locals.stop=setTimeout(()=>{set('this',0)},1000)
}
else if(value === 0) {clearInterval(locals.Monte);clearTimeout(locals.stop)}

HsH4eLjtJ5

locals.from = 0
locals.to = 127
locals.dur = 1000 // ms
locals.fps = 30 // frames per seconds

if (value) {
  // start fade when button is on

  locals.start = Date.now()

  setInterval(function(){
    var pos = (Date.now() - locals.start) / locals.dur
    if (pos >= 1) {
      clearInterval()
      pos = 1
    }
    var val  = pos * (locals.to - locals.from) + locals.from
    send('midi:port', '/control', 1, 10, val) // ch 1, cc 10, value
  }, 1000 / locals.fps)

} else {
  // cancel when button is off ?
  clearInterval()
}
1 Like

Great, that works - thanks!

This function will be implemented in 100-200 different buttons - could this be a problem performance wise? (there will never be more than a couple of simultaneous fades running though)

EDIT: Are the variables localized for each button, or does multiple buttons with the same variable names interfer with each other?

It shouldn't be a problem, but to avoid duplicating the code you could put it in a global function defined only once in a script (with event set to once):

globals.fade = function(btnValue, cc, from, to, dur) {

    var fps = 30,
        channel = 1

    if (btnValue) {
      // start fade when button is on

      var start = Date.now()

      setInterval(function(){
        var pos = (Date.now() - start) / dur
        if (pos >= 1) {
          clearInterval()
          pos = 1
        }
        var val  = pos * (to - from) + from
        
        send('midi:port', '/control', channel, cc, val)
        
      }, 1000 / fps)

    } else {
      // cancel when button is off ?
      clearInterval()
    }
}

and then in each button's script:

globals.fade(value, 10, 0, 127, 1000)

EDIT: Are the variables localized for each button, or does multiple buttons with the same variable names interfer with each other?

There a locals object for each widget, unlike globals which is shared. Variables created with var only live in the current execution context and are not shared.

1 Like

Great!

Does the setInterval() function handle the opposite direction as well?
(to perform a fade-out = decrementing loop)

setInterval calls a function at a periodic rate, the rest is just math :). In this case, inverting the to and from arguments in the function call should do the trick.

@jean-emmanuel : is Date.now a function that returns the object's value at each frame ?... Is there any other "Date" state (date.before... date.after... you see what i mean...) ?

Interesting. Thank you.