Resetting autoplay SlickR carousel to the beginning

76 Views Asked by At

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!!

2

There are 2 best solutions below

1
Stéphane Laurent On BEST ANSWER

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

1
Stéphane Laurent On

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