7
votes

I was wondering if there is a way to change the animation speed of a slider in shiny. So, for a slider that is (in ui.R) :

sliderInput("test_slider", 
            "Animation:", 
             min = 1, 
             max = 200, 
             value = 100, 
             animate = animationOptions(interval = ANIMATION SPEED))

I want to be able to change ANIMATION SPEED rather than keeping it at a static value that I set in the beginning. Also, the animation only works when I put it in the ui, so I can't make it a reactive UI in the server. For example, I can't do in server.R

output$test_slider <- renderUI({
   sliderInput("test_slider", 
               "Animation:", 
                min = 1, 
                max = 200, 
                value = 100, 
                animate = animationOptions(interval = ANIMATION SPEED))
})

and then add in ui.R

uiOutput("test_slider")

This would have been ideal since I customize things like min and max (and probably ANIMATION SPEED), but unfortunately doing it this way makes it so the play button doesn't work and the animation just doesn't start. I am at a loss for how to dynamically change slider input parameters. Even if your solution involves javascript, I would be totally fine with that. Thank you so much.


EDIT:

So I don't have an answer yet, but I've gotten closer. I looked through the javascript file and added something like this (in ui.R):

         numericInput("anim",
                      "interval: ",
                      value = 100),
         sliderInput("test_slider",
                    "Animation",
                     min = 1,
                     max = 200,
                     value = 100,
                     step = 1,
                     animate = animationOptions(interval = 700,
                               playButton = icon('play', "fa-3x"),
                               pauseButton = icon('pause', "fa-3x"))),
        singleton(
          tags$head(tags$script('Shiny.addCustomMessageHandler("testmessage",
                function(message) {$(this).attr("data-interval", message.interval); 
                                console.log($(this).attr("data-interval"))});'))
          )

I have the console.log just to show that I am sending the right thing since it is printing the correct value in the terminal. Then I do in server.R:

  observe({
    if(!is.null(input$anim)) {
      session$sendCustomMessage(type = "testmessage", 
                                message = list(interval = input$anim,
                                         controller = input$test_slider))
    }
  })

I am using both the documentation in the shiny repo here: https://github.com/rstudio/shiny/blob/a6cd0fdb85d5d2175ebc4fcb590386e4cedcbbd9/srcjs/input_binding_slider.js

as well as the documentation found on this blog here: https://ryouready.wordpress.com/2013/11/20/sending-data-from-client-to-server-and-back-using-shiny/

The one for the github repo I'm using the part below where it says

animInterval = self.attr("data-interval")

where

 var self = $(this)

I've never really used javascript before, so I could be missing something obvious. Any help is greatly appreciated!

1
In theory by using dot notation you can access input values in ui. So you create another slider and put interval = "input.SLIDERINPUTNAME" But for somereason I couldn't get that working. More info accessing input values in ui:Conditional panels - Mikael Jumppanen
Hey thanks for the help. I've posted something below as an "answer" so it can be viewed more clearly, and it may be closer. It's using some javascript, which I'm not really familiar with, but I thought it should have worked. Any suggestions? Thanks! - johnny838
I also think that renderUI should work so maybe it is bug. You can write bug report here: Issues - Mikael Jumppanen

1 Answers

2
votes

I'm not sure if I understand your issue but if I do the following will work :

In server.R :

output$slider_to_anim <- renderUI({
  sliderInput("slider", 
           "Animation:", 
            min = 1, 
            max = 200, 
            value = 100, 
            animate = animationOptions(interval = input$speed))
})

output$speed_value <- renderUI({
  numericInput("speed","Speed Value :",value = 100)
})

And add in ui.R :

uiOutpout("slider_to_anim"),
uiOutpout("speed_value")