Problem when reloading an animated GIF in Chrome

半腔热情 提交于 2019-12-23 16:51:55

问题


I have an app that reloads an animated gif. It works all the time in Safari and intermittently in Chrome. I believe the problem is similar to one mentioned here.

My knowledge of Javascript is negligible. However, reading this, I came up with this example, which still doesn't work. Using Chrome, if you click again enough times you will see that sometimes the image reload fails.

library(shiny)
library(shinyjs)

jsCode <- '
shinyjs.reset_anim = function() {
  var div_elem = document.getElementById("anim_plot");
  var img_elem = div_elem.getElementsByTagName("img")[0];
  var src_value = img_elem.getAttribute("src");
  img_elem.setAttribute("src", "");
  img_elem.setAttribute("src", src_value);
}
'


# Define UI ----
ui <- fluidPage(useShinyjs(),
                extendShinyjs(text = jsCode),

                plotOutput("anim_plot",
                           width = "900px",
                           height = "200px"),

                fluidRow(
                  column(3,  
                    actionButton("do_again", "Again")
                  )
                )
)

# Define server logic ----
server <- function(input, output) {
  observeEvent(input$do_again, {
    js$reset_anim()
    output$anim_plot <- renderImage({
      list(src = "www/tmp/ani.gif",
           contentType = 'image/gif',
           width = 900,
           alt = "Text"
      )
    }, deleteFile = FALSE)
  })
}

shinyApp(ui = ui, server = server)  

You can find an animated gif here.


回答1:


I avoid using renderImage for this kind of things. In the past I struggled with this function myself for a while (it's great for plots, but not for real png, jpeg, gif etc it seems) so here is a working alternative using html img() tag as renderUI output object. Seems your javascript works fine. Also, you can just use the online image, which I find works better than a locally stored one

library(shiny)
library(shinyjs)

jsCode <- '
shinyjs.reset_anim = function() {
  var div_elem = document.getElementById("anim_plot");
  var img_elem = div_elem.getElementsByTagName("img")[0];
  var src_value = img_elem.getAttribute("src");
  img_elem.setAttribute("src", "");
  img_elem.setAttribute("src", src_value);
}
'


# Define UI ----
ui <- fluidPage(useShinyjs(),
                extendShinyjs(text = jsCode),
                uiOutput('anim_plot'),
                fluidRow(
                  column(3,  
                         actionButton("do_again", "Again")
                  )
                )
)

# Define server logic ----
server <- function(input, output) {
  output$anim_plot <- renderUI({
    img(src='https://uc290691998b0891615b1f3e9397.previews.dropboxusercontent.com/p/orig/AAae6QYO7VLEEUVYdUuL985gwFGGVQ_RJ0mjLtfJt0bk3UO1ThezW4YO7R5LUzN9_m6moBjubhfX2AAnYmEkwDEjnwIw1gLOWUrOw4q_pKYYtXW-JCgghu4NuCgPKCm3RXxt3rNULvlUg-cP_Oj2vnItglJchP6a6a_lyApxTdZHwPk4Yv6jWxiYANVdFAVKxiTeHWVC5J3PYDeW8yOnaj4VGDj92eJCIXYtjpmznffo0tPUdUovNJMMW5nzsgT0L38w_5h39bcBxIwoCBmZ95iC8SRd9BGHxJMGCM4HUVh_Ly0VW3lwBxUx3O__VD5Ind-lahJwVkZjmet-HzP6XnUB/p.gif?size_mode=5', align = "right")
  })

  observeEvent(input$do_again, {
    js$reset_anim()

  })
}

shinyApp(ui = ui, server = server)  

UPDATE:
App with server file, ui file and 5 gifs in the www folder: I just downloaded 5 random gifs from giphy, and made one to not loop with ezgif.com, stored them as gif1.gif, gif2.gif etc.

@OP: Keep in mind that your javascript targets 1 particular gif object. If you want to reload another gif, you would have to rewrite your javascript to take an input argument, which would be the name of your anim_plot n you wish to restart I guess. I'm no javascript expert, so I'm not going to attempt to add that here, but if you do, feel free to add it to the information here

p.s. 1: do not put 'www/' in your src argument. Shiny automatically looks inside the www folder. .

p.s 2: keep in mind that some things don't work in the internal interface of RStudio, and set it to run shiny apps externally by clicking "run external" under the tiny arrow menu that is on the right of the "Run App" play button.

# File of the server.
server <- function(input, output) {

  lapply(1:5, function(image_id) { 
  output[[paste('anim_plot', image_id, sep = '')]] <- renderUI({
    img(src=paste('gif', image_id, '.gif', sep = ''), align = "right")

    })
  })

  observeEvent(input$do_again, {
    js$reset_anim()

  })
}


# File of UI ----
library(shiny)
library(shinyjs)

jsCode <- '
shinyjs.reset_anim = function(anim_plot2) {
  var div_elem = document.getElementById("anim_plot2");
  var img_elem = div_elem.getElementsByTagName("img")[0];
  var src_value = img_elem.getAttribute("src");
  img_elem.setAttribute("src", "");
  img_elem.setAttribute("src", src_value);
}
'


ui <- fluidPage(useShinyjs(),
                extendShinyjs(text = jsCode),
                uiOutput('anim_plot1'),
                uiOutput('anim_plot2'),
                uiOutput('anim_plot3'),
                uiOutput('anim_plot4'),
                uiOutput('anim_plot5'),

                fluidRow(
                  column(3,  
                         actionButton("do_again", "Again")
                  )
                )
)



来源:https://stackoverflow.com/questions/55213748/problem-when-reloading-an-animated-gif-in-chrome

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!