@@ -230,6 +230,11 @@ function attachListeners(gd, sliderGroup, sliderOpts) {
230230 value = Lib . nestedProperty ( data , updatevalue ) . get ( ) ;
231231 }
232232
233+ // If it's *currently* invoking a command an event is received,
234+ // then we'll ignore the event in order to avoid complicated
235+ // invinite loops.
236+ if ( sliderOpts . _invokingCommand ) return ;
237+
233238 setActiveByLabel ( gd , sliderGroup , sliderOpts , value , false , true ) ;
234239 } ;
235240 }
@@ -338,17 +343,38 @@ function setActiveByLabel(gd, sliderGroup, sliderOpts, label, doCallback, doTran
338343function setActive ( gd , sliderGroup , sliderOpts , index , doCallback , doTransition ) {
339344 sliderOpts . _input . active = sliderOpts . active = index ;
340345
341- sliderGroup . call ( setGripPosition , sliderOpts , sliderOpts . active / ( sliderOpts . steps . length - 1 ) , doTransition ) ;
342-
343346 var step = sliderOpts . steps [ sliderOpts . active ] ;
344347
348+ sliderGroup . call ( setGripPosition , sliderOpts , sliderOpts . active / ( sliderOpts . steps . length - 1 ) , doTransition ) ;
349+
345350 if ( step && step . method && doCallback ) {
346- var args = step . args ;
347- Plotly [ step . method ] ( gd , args [ 0 ] , args [ 1 ] , args [ 2 ] ) . catch ( function ( ) {
348- // This is not a disaster. Some methods like `animate` reject if interrupted
349- // and *should* nicely log a warning.
350- Lib . warn ( 'Warning: Plotly.' + step . method + ' was called and rejected.' ) ;
351- } ) ;
351+ if ( sliderGroup . _nextMethod ) {
352+ // If we've already queued up an update, just overwrite it with the most recent:
353+ sliderGroup . _nextMethod . step = step ;
354+ sliderGroup . _nextMethod . doCallback = doCallback ;
355+ sliderGroup . _nextMethod . doTransition = doTransition ;
356+ } else {
357+ sliderGroup . _nextMethod = { step : step , doCallback : doCallback , doTransition : doTransition } ;
358+ sliderGroup . _nextMethodRaf = window . requestAnimationFrame ( function ( ) {
359+ var _step = sliderGroup . _nextMethod . step ;
360+ var args = _step . args ;
361+ if ( ! _step . method ) return ;
362+
363+ sliderOpts . _invokingCommand = true ;
364+ Plotly [ _step . method ] ( gd , args [ 0 ] , args [ 1 ] , args [ 2 ] ) . then ( function ( ) {
365+ sliderOpts . _invokingCommand = false ;
366+ } , function ( ) {
367+ sliderOpts . _invokingCommand = false ;
368+
369+ // This is not a disaster. Some methods like `animate` reject if interrupted
370+ // and *should* nicely log a warning.
371+ Lib . warn ( 'Warning: Plotly.' + _step . method + ' was called and rejected.' ) ;
372+ } ) ;
373+
374+ sliderGroup . _nextMethod = null ;
375+ sliderGroup . _nextMethodRaf = null ;
376+ } ) ;
377+ }
352378 }
353379}
354380
@@ -428,7 +454,7 @@ function setGripPosition(sliderGroup, sliderOpts, position, doTransition) {
428454 var x = normalizedValueToPosition ( sliderOpts , position ) ;
429455
430456 var el = grip ;
431- if ( doTransition && sliderOpts . transition . duration > 0 ) {
457+ if ( doTransition && sliderOpts . transition . duration > 0 && ! sliderOpts . _invokingCommand ) {
432458 el = el . transition ( )
433459 . duration ( sliderOpts . transition . duration )
434460 . ease ( sliderOpts . transition . easing ) ;
0 commit comments