1

I have a SlickR carousel in a Navbar Shiny UI that lops through several slides with autoplay. I would like to reset it to start again at the beginning after switching tabs (and returning to the tab with the carousel). At the moment, it seems that the carousel keeps autoplaying in the background. I have an action button for switching tabs as part of the carousel, but the problem occurs independently of switching tabs by clicking on the button or directly on the other tab. After switching tabs, it also initially shows the image embedded in the carousel not properly centered and the action button is shown on a different slide. As expected, the latter problem does not occur if autoplay is turned off (but the carousel obviously return to whichever slide was last selected and I would like to use autoplay while the tab is active).

Is there a way of stopping autoplay when the tab is not active and returning to the beginning of the carousel?

Here is a minimal example based on code that @Stéphane Laurent kindly helped me with in this question: Shiny Slick R carousel with internal links to tab panels

library(shiny)
library(slickR)

ui <- navbarPage(
  title = "Navbar",
  id = "navbar",
  
  tabsetPanel(id="tabs",
              
              tabPanel(
                title= "Tab1", value = "tab1",
                
                fluidRow(
                  slickR(slick_list(
                    tags$div(height=600,
                             tags$img(
                               src = nba_player_logo$uri[1],
                               width = "100%",
                               height = 600,
                               style="display:inline-block, padding:0"
                             ),
                             actionButton(
                               "action1", "Tabswitch", style = "position: relative; margin-top: -35em;"
                             ),
                             align = "center"
                    ),
                    tags$div(
                      tags$img(
                        src = nba_player_logo$uri[2],
                        width = "100%",
                        height = 600,
                        style="display:inline-block, padding:0"
                      ),
                      align = "center"
                    ),
                    tags$div(
                      tags$img(
                        src = nba_player_logo$uri[3],
                        width = "100%",
                        height = 600,
                        style="display:inline-block, padding:0"
                      ),
                      align = "center"
                    )
                  )) + settings(autoplay = F, dots = TRUE)
                ),
              ),
              
              tabPanel(
                title = "Tab2", value = "tab2"
              )
  )
  
)

server <- function(input, output, session) {
  observeEvent(input$action1, {
    updateNavbarPage(session, "tabs", selected = "tab2")
  })
}

shinyApp(ui, server)

Thanks so much!!

DanB
  • 163
  • 5

2 Answers2

1

Ok like this ?

library(shiny)
library(slickR)
library(shinyjs)

js <- function(bool) {
  sprintf(
    '$("#my_slick").slick("slickSetOption", {
      "autoplay": %s
    }, false);',
    tolower(bool)
  )
}

my_images <- c("image1.png", "image2.png", "image3.png")

ui <- shiny::basicPage(
  useShinyjs(),
  
  tabsetPanel(
    id = "tabset",
    tabPanel(
      "Carousel",
      value = "tab1",
      slickROutput("my_slick", width = "90%", height = "200px"), 
    ),
    tabPanel(
      "Nothing",
      value = "tab2"
    )
  )
  
)

server <- function(input, output) {
  
  output[["my_slick"]] <- renderSlickR({
    slickR(
      my_images,
      width = "80%",
    ) + settings(autoplay = TRUE, autoplaySpeed = 500)
  })
  
  observeEvent(input[["tabset"]], {
    runjs(js(input[["tabset"]] == "tab1"))  
  }, ignoreInit = TRUE)
  
}

shinyApp(ui, server)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Thanks so much for looking into this! It seems that turning off autoplay does not actually solve the problem that motivated my post. When I click on the "Nothing" tab and return to the "Carousel" tab, only a portion of the image initially displays (on the right side) and it then flicks back to the full image. Do you have any idea what might be the issue and how to fix it? – DanB Jul 17 '23 at 22:10
1

I don't know with slickR. Here is a solution with swipeR.

library(shiny)
library(swipeR)
library(shinyjs)

js <- function(bool) {
  paste(
    "var swpr = document.getElementById('CAROUSEL').swiper;",
    sprintf(
      "var istab1 = %s;", tolower(bool)
    ),
    "if(istab1) {",
    "  swpr.slideTo(0, 100, false);",
    "  swpr.start();",
    "} else {",
    "  swpr.stop();",
    "}",
    sep = "\n"
  )
}

wrapper <- swipeRwrapper(
  tags$img(src = "img1.png", width = "300", height = "300"),
  tags$img(src = "img2.png", width = "300", height = "300"),
  tags$img(src = "img3.png", width = "300", height = "300"),
  tags$img(src = "img4.png", width = "300", height = "300")
)


ui <- shiny::basicPage(
  useShinyjs(),

  tabsetPanel(
    id = "tabset",
    tabPanel(
      "Carousel",
      value = "tab1",
      swipeR(
        wrapper, height = "500px", width = "500px",
        autoplay = list(delay = 1500, disableOnInteraction = FALSE),
        id = "CAROUSEL"
      ),
    ),
    tabPanel(
      "Nothing",
      value = "tab2"
    )
  )
)

server <- function(input, output) {

  observeEvent(input[["tabset"]], {
    runjs(js(input[["tabset"]] == "tab1"))
  }, ignoreInit = TRUE)

}

shinyApp(ui, server)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Works like a charm! Can you let me know how to add other elements, e.g. text and action buttons, to the individual slides? – DanB Jul 26 '23 at 04:21