问题
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