I'm building a Shiny app that displays various pre-rendered .png and .svg images across multiple tabs, with some of the images being chosen through different types of input. To add some pizzazz, I'd like to add animations to the images that play whenever an image is displayed, either when the tab that it's on is selected or when it is chosen through an input.
I've tried using shinyjs::show/hide
and shinyjqui::jqui_effect
, but those functions seem to want to respond to some input, like a button press, rather than playing automatically and repeatedly.
I've managed to put together the code below that uses shinyanimate
to achieve the desired effect. However, my real app has many more tabs and images, and this method of having every animation react to any changes in the tabs or inputs seems inefficient. Is there a better way of doing this?
(N.B. I'm only using the "bounceInLeft" effect here because it makes the example clear, but I'd like to be able to use other animation effects such as "fadeIn").
library(shiny)
library(shinyanimate)
# Define UI
ui <- fluidPage(
withAnim(),
tabsetPanel(id = "tabs",
# Tab 1 ----
tabPanel("Tab 1",
fluidRow(
column(3,
imageOutput("tab1_img1")
),
column(3,
imageOutput("tab1_img2")
)
)
),
# Tab 2 ----
tabPanel("Tab 2",
selectInput("img_opts",
label = "Select image",
choices = c("img2", "img1")
),
imageOutput("tab2_imgs")
)
)
)
# Define server logic
server <- function(input, output) {
# Tab 1 image 1
output$tab1_img1 <- renderImage({
list(src = file.path("images/img1.png"), width = "95%")
}, deleteFile = FALSE)
# Tab 1 image 1 animation
observeEvent(input$tabs,
startAnim(session = getDefaultReactiveDomain(), "tab1_img1", "bounceInLeft")
)
# Tab 1 image 2
output$tab1_img2 <- renderImage({
list(src = file.path("images/img2.png"), width = "95%")
}, deleteFile = FALSE)
# Tab 1 image 2 animation
observeEvent(input$tabs,
startAnim(session = getDefaultReactiveDomain(), "tab1_img2", "bounceInLeft")
)
# Tab 2 images
output$tab2_imgs <- renderImage({
list(src = file.path(paste0("images/", input$img_opts, ".png")), width = "25%")
}, deleteFile = FALSE)
# Tab 2 animation
observeEvent(c(input$tabs, input$img_opts),
startAnim(session = getDefaultReactiveDomain(), "tab2_imgs", "bounceInLeft")
)
}
# Run the application
shinyApp(ui = ui, server = server)