【问题标题】:Problem when reloading an animated GIF in Chrome在 Chrome 中重新加载动画 GIF 时出现问题
【发布时间】:2019-08-08 08:55:23
【问题描述】:

我有一个重新加载动画 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

【问题讨论】:

  • 您是否也在使用V8?我认为这是在shinyjs 文档中强烈推荐的
  • 直到你提到它,我才知道 V8。 V8 - Google 开源 JavaScript 引擎的 R 接口。
  • 因此,如果您检查?shinyjs::extendShinyjs,那么您会在底部的Note 中看到它。它不需要额外的函数调用,你只需要让它可用
  • 我认为更大的问题是我的 Javascript 不正确或者我调用不正确。

标签: javascript r shiny shinyjs


【解决方案1】:

我避免在这类事情上使用 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 专家,所以我不会尝试在此处添加,但如果您这样做,请随时将其添加到此处的信息中

附言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")
                  )
                )
)

【讨论】:

  • 我正在创建一个动画 gif 并将其存储在本地。当我切换到您的 renderUI 方法时,它会很好地显示第一个动画 gif。但是,即使我可以看到文件已正确创建,它也不会显示后续的动画 gif。这个问题是否与您的评论有关,“(外部 URL)我发现工作比本地存储的更好”?关于如何让本地 GIF 工作的任何想法?
  • 我建议你接受这个答案,然后用你描述的场景发布一个新问题。然后我会看看它,今天晚些时候我会用本地存储为你测试这个单一的 gif。正确创建是什么意思
  • 正确创建意味着这里引用的文件img(src = 'tmp/ani.gif')已经更新成功。
  • 啊,你的意思是在我假设的应用程序中呈现。您是否会针对您要求的具有超过 1 张图片的场景的另一部分发布新问题?
  • 我刚刚制作了一个包含 5 个本地存储 gif 的应用程序,它们对我来说都很好。代码在我的答案中的更新中。 p.s.我认为您必须手动分配赏金才能授予。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
相关资源
最近更新 更多