I want some animation on my conditionalpanels. I've found the solution provided here: Animation/transition for Shiny conditionalPanel. This is a following of another question (Animation on conditionalpanel).
The problem is shown in the image below:
Two problems:
- When I put another conditionalpanel (also a simple one) inside the animated, every time is triggered the inside condition, the animation of the bigger box is animated again.
- When I change from step two to step one, nothing is displayed. (I have to click on Next and then on Previous).
Here's a reproducible example:
library(shiny)
library(shinyjs)
library(shinydashboard)
animateCSS <- function(effect, delay = 0, duration = 500, then = NULL){
effect <- match.arg(effect, c(
"bounce",
"flash",
"pulse",
"rubberBand",
"shakeX",
"shakeY",
"headShake",
"swing",
"tada",
"wobble",
"jello",
"heartBeat",
"backInDown",
"backInLeft",
"backInRight",
"backInUp",
"backOutDown",
"backOutLeft",
"backOutRight",
"backOutUp",
"bounceIn",
"bounceInDown",
"bounceInLeft",
"bounceInRight",
"bounceInUp",
"bounceOut",
"bounceOutDown",
"bounceOutLeft",
"bounceOutRight",
"bounceOutUp",
"fadeIn",
"fadeInDown",
"fadeInDownBig",
"fadeInLeft",
"fadeInLeftBig",
"fadeInRight",
"fadeInRightBig",
"fadeInUp",
"fadeInUpBig",
"fadeInTopLeft",
"fadeInTopRight",
"fadeInBottomLeft",
"fadeInBottomRight",
"fadeOut",
"fadeOutDown",
"fadeOutDownBig",
"fadeOutLeft",
"fadeOutLeftBig",
"fadeOutRight",
"fadeOutRightBig",
"fadeOutUp",
"fadeOutUpBig",
"fadeOutTopLeft",
"fadeOutTopRight",
"fadeOutBottomRight",
"fadeOutBottomLeft",
"flip",
"flipInX",
"flipInY",
"flipOutX",
"flipOutY",
"lightSpeedInRight",
"lightSpeedInLeft",
"lightSpeedOutRight",
"lightSpeedOutLeft",
"rotateIn",
"rotateInDownLeft",
"rotateInDownRight",
"rotateInUpLeft",
"rotateInUpRight",
"rotateOut",
"rotateOutDownLeft",
"rotateOutDownRight",
"rotateOutUpLeft",
"rotateOutUpRight",
"hinge",
"jackInTheBox",
"rollIn",
"rollOut",
"zoomIn",
"zoomInDown",
"zoomInLeft",
"zoomInRight",
"zoomInUp",
"zoomOut",
"zoomOutDown",
"zoomOutLeft",
"zoomOutRight",
"zoomOutUp",
"slideInDown",
"slideInLeft",
"slideInRight",
"slideInUp",
"slideOutDown",
"slideOutLeft",
"slideOutRight",
"slideOutUp"
))
js <- paste(
" $this.animateCSS('%s', {",
" delay: %d,",
" duration: %d,",
" callback: function(){",
" %s",
" }",
" });",
sep = "\n"
)
sprintf(js, effect, delay, duration, ifelse(is.null(then), "", then))
}
onShowJS <- function(animation, fadeDuration){
sprintf(paste(
"$('#%%s>div').on('show', function(){",
" var $this = $(this);",
" $this.css('opacity', 0).animate({opacity: 1}, %d, function(){",
animation,
" });",
"});",
sep = "\n"
), fadeDuration)
}
onHideJS <- function(animation, fadeDuration){
paste(
"$('#%s>div').on('hide', function(){",
" var $this = $(this);",
" setTimeout(function(){",
sub(
"^(\\s.*?\\$this\\.animateCSS)",
"$this.show().animateCSS",
sub(
"\\{\n \n \\}",
sprintf("{$this.hide(%d);}", fadeDuration),
animation
)
),
" }, 0);",
"});",
sep = "\n"
)
}
animatedConditionalPanel <-
function(condition, ..., onShow = NULL, fadeIn = 0, onHide = NULL, fadeOut = 0){
id <- paste0("animateCSS-", stringi::stri_rand_strings(1, 15))
jsShow <- ifelse(!is.null(onShow), sprintf(onShowJS(onShow, fadeIn), id), "")
jsHide <- ifelse(!is.null(onHide), sprintf(onHideJS(onHide, fadeOut), id), "")
script <- tags$script(HTML(paste(jsShow,jsHide,sep="\n")))
condPanel <- conditionalPanel(condition, style = "display: none", ...)
tags$div(id=id, tagList(condPanel, script))
}
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({
box(width = NULL, status = "primary", solidHeader = T, title = "First box",
h4(strong("This is the first box")),
selectInput("step2", "Choose a step:", 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({
box(width = NULL, status = "primary", solidHeader = T, title = "Second box",
h4("This is the second box"))
})
}
shinyApp(ui, server)