I want some animation on my conditionalpanels. I've found the solution provided here: Animation/transition for Shiny conditionalPanel
I really like the solution, but I have a problem. Check the following example:
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
header = dashboardHeader(title = "test"),
sidebar = dashboardSidebar(),
shinydashboard::dashboardBody(
fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.compat.min.css"),
tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/animateCSS/1.2.2/jquery.animatecss.min.js")
),
fluidRow(
textOutput("test"),
column(2, offset = 2, actionButton("prev_box", "Previous")),
column(
4,
# conditionalPanel(condition = "output.phase_box_ui == 0",
# uiOutput("box_move1")),
# conditionalPanel(condition = "output.phase_box_ui > 0",
# uiOutput("box_move2"))
animatedConditionalPanel(
condition = "output.phase_box_ui == 0",
onShow = animateCSS("backInRight", duration = 1000),
onHide = animateCSS("backOutLeft", duration = 1000),
fadeIn = 0,
fadeOut = 0,
uiOutput("box_move1")
),
animatedConditionalPanel(
condition = "output.phase_box_ui == 1",
onShow = animateCSS("backInRight", duration = 1000),
onHide = animateCSS("backOutLeft", duration = 1000),
fadeIn = 0,
fadeOut = 0,
uiOutput("box_move2")
)
),
column(2, actionButton("next_box", "Next"))
)
)
)
)
server <- function(input, output,session) {
#### TEST BOX MOVING
phase_box = reactiveVal(0)
observeEvent(phase_box(),{
if(phase_box() == 0){
shinyjs::hide("prev_box")
}else{
shinyjs::show("prev_box")
}
})
observeEvent(input$prev_box,{
if(phase_box() > 0){
val = phase_box() - 1
phase_box(val)
}
})
observeEvent(input$next_box,{
if(phase_box() < 6){
val = phase_box() + 1
phase_box(val)
}
})
output$test = renderText({
phase_box()
})
output$phase_box_ui = reactive({return(phase_box())})
outputOptions(output, "phase_box_ui", suspendWhenHidden = F)
output$box_move1 = renderUI({
shinydashboard::infoBox(title = "First box", value = 0, color = "red")
})
output$box_move2 = renderUI({
shinydashboard::infoBox(title = "Second box", value = 1)
})
}
shinyApp(ui, server)
The problem is at startup where both of them appear for a second and then disappear, but at startup the first box should be visible. How I can fix it?
EDIT:
Now the first problem is solved. However check the gif below:
When the second box arrives, it arrives below the first box and then suddenly it goes up. The effect can be nice if the transition wasn't immediately (it simply pops up in the correct place). Do you know if there is a solution? It's seems like, just for a moment (during the transition), they are displayed both and so the second box goes below the first.
Here is the behaviour adding 1s delay for the inShow transition of the second box. Maybe is more clear the problem.
EDIT2:
I have a bigger problem on nested conditionalpanels. When I put another conditionalpanel (a simple one) inside the animated, every time is triggered the inside condition, the animated run again the animation. Here's a reproducible example:
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
header = dashboardHeader(title = "test"),
sidebar = dashboardSidebar(),
shinydashboard::dashboardBody(
fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.compat.min.css"),
tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/animateCSS/1.2.2/jquery.animatecss.min.js")
),
fluidRow(
textOutput("test"),
column(2, offset = 2, actionButton("prev_box", "Previous")),
column(
4,
animatedConditionalPanel(
condition = "output.phase_box_ui == 0",
onShow = animateCSS("backInRight", duration = 1000),
onHide = animateCSS("backOutLeft", duration = 1000),
fadeIn = 0,
fadeOut = 0,
uiOutput("box_move1")
),
animatedConditionalPanel(
condition = "output.phase_box_ui == 1",
onShow = animateCSS("backInRight", duration = 1000),
onHide = animateCSS("backOutLeft", duration = 1000),
fadeIn = 0,
fadeOut = 0,
uiOutput("box_move2")
)
),
column(2, actionButton("next_box", "Next"))
)
)
)
)
server <- function(input, output,session) {
#### TEST BOX MOVING
phase_box = reactiveVal(0)
observeEvent(phase_box(),{
if(phase_box() == 0){
shinyjs::hide("prev_box")
}else{
shinyjs::show("prev_box")
}
})
observeEvent(input$prev_box,{
if(phase_box() > 0){
val = phase_box() - 1
phase_box(val)
}
})
observeEvent(input$next_box,{
if(phase_box() < 6){
val = phase_box() + 1
phase_box(val)
}
})
output$test = renderText({
phase_box()
})
output$phase_box_ui = reactive({return(phase_box())})
outputOptions(output, "phase_box_ui", suspendWhenHidden = F)
output$box_move1 = renderUI({
fluidPage(
shinydashboard::infoBox(title = "First box", value = 0, color = "red"),
selectInput("step2", "Choose:", choices = c("one", "two")), br(),
conditionalPanel(style = "display: none",
condition = "input.step2 == 'two'",
h4(strong("2. This is the second step"))
)
)
})
output$box_move2 = renderUI({
shinydashboard::infoBox(title = "Second box", value = 1)
})
}
shinyApp(ui, server)