在Chrome中重新加载动画GIF时出现问题

时间:2019-03-18 01:46:12

标签: javascript r shiny shinyjs

我有一个重新加载动画gif的应用程序。它始终在Safari中运行,并在Chrome中间歇性地运行。我认为问题类似于提到的here

我对Javascript的了解可以忽略不计。但是,在阅读this时,我想到了这个示例,但仍然无法使用。使用Chrome浏览器,如果再次单击几次,您会发现有时图像重新加载失败。

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)  

您可以找到动画gif here

1 个答案:

答案 0 :(得分:3)

我避免将renderImage用于此类事情。在过去,我自己为此功能苦苦挣扎了一段时间(这对绘图非常有用,但对于真正的png,jpeg,gif等似乎不那么有用),因此这是使用html img()标记作为renderUI输出对象的可行替代方法。似乎您的JavaScript正常运行。另外,您可以只使用在线图像,我发现它比本地存储的图像效果更好

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)  

更新:
带有服务器文件,ui文件和www文件夹中的5 gif的应用程序: 我刚刚从giphy下载了5张随机gif文件,并制作了一个不要与ezgif.com循环的gif文件,将它们存储为gif1.gif,gif2.gif等。

@OP:请记住,您的JavaScript的目标是1个特定的gif对象。如果要重新加载另一个gif,则必须重写JavaScript以接受输入参数,我想这就是您要重新启动的anim_plot n的名称。我不是javascript专家,所以我不会尝试在此处添加它,但是如果您愿意,可以随时将其添加到此处的信息中

p.s。 1:请勿在您的src参数中添加“ www /”。 Shiny会自动在www文件夹中查找。

ps 2:请记住,某些事情在RStudio的内部界面中不起作用,并通过单击“右侧”小箭头菜单下的“外部运行”将其设置为在外部运行闪亮的应用程序运行应用”播放按钮。

# 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")
                  )
                )
)

screenshot