Search code examples
rshinyslidercountdown

make animated slider go backwards (right to left) to simulate a countdown?


I want to animate a shiny slider so that it goes backwards automatically when the play button is hit, from right to left. I can't find a way to do this. The slider would mimic a time countdown of 10 seconds, this is my current code, it goes the wrong way. I tried unsuccessfully to mess with the step, min, max, etc. Is it even possible?

library(shiny); library(shinyjs); library(shinyWidgets)
jscode <- "shinyjs.play = function() {$('.slider-animate-button').trigger('click');}"
ui <- fluidPage(useShinyjs(), extendShinyjs(text = jscode),
  tags$head(tags$style(HTML('.irs-from, .irs-to, .irs-min, .irs-max, .irs-grid-text, .irs-grid-pol, .irs-slider {visibility:hidden !important;}'))),
  h3("countdown"),
  sliderInput("countdown", label = "", width = '300px',min = 0, max = 10,value = 0, step = 0.1, post="secs",
              animate = animationOptions(interval = 50, playButton = "", pauseButton = "")),
  actionButton("start", "start"))
server <- function(input, output,session) {
  disable("slider")
  observeEvent(input$start, priority=10, {js$play()})
}
shinyApp(ui, server)

Thanks for your help.. enter image description here

Note: in fact the main problem is not so much that is goes the wrong way, but that it should start completed and finish empty, for a countdown!


Solution

  • I worked out a rather satisfactory solution combining two ideas:

    1. the above answer from @phalteman that allows the text label to be counting backwards thanks to a sliderTextInput
    2. since we can't make the slider starting from the right, at least we can make it look like the bar is diminishing (otherwise it would not make sense for a countdown). A CSS trick to make the slider appear like it's diminishing even though it's still increasing: I invert the colors of the slider bar with the color of the background, so what appears to be the bar is actually the empty background being consumed gradually (in red in the picture below).

    css code to place instead in the tags$head section:

    .irs-bar {
        height: 20px !important;
        border-top: 1px solid #CCC !important;
        border-bottom: 1px solid #CCC !important;
        background: #CCC !important;
    }
    
    .irs-bar-edge {
        height: 20px !important;
        border: 1px solid #CCC !important;
        background: #CCC !important;
    }
    
    .irs-line {
        height: 20px !important;
        border: 1px solid #FF5964 !important;
        background: #FF5964 !important;
    }
    
    .irs-single {
        background: #FF5964 !important;
    }
    
    .irs-from, .irs-to, .irs-min, .irs-max, .irs-grid-text, .irs-grid-pol, .irs-slider {
        visibility:hidden !important;
    }
    

    The CSS stylesheet would be like this (I Added an important label because for some Reason the changes were not taken into account…?

    enter image description here