Estou construindo um aplicativo Shiny usando shinyscreenshot
. Meu aplicativo inclui um cartão "Pontuação" com uma lista de radioGroupButtons que os usuários podem selecionar. Os radioGroupButtons não são visíveis no aplicativo, no entanto, quando tiro uma captura de tela usando shinyscreenshot
, os radioGroupButtons ocorrem e se sobrepõem aos valores numéricos, deixando a captura de tela confusa.
Quero ocultar os radioGroupButtons ao tirar a captura de tela. Tentei usar shinyjs para alternar a visibilidade dos botões, mas não está funcionando como esperado.
Aqui está um exemplo mínimo reproduzível que demonstra minha configuração e abordagem:
library(shiny)
library(bs4Dash)
library(shinyWidgets)
library(shinyjs)
library(shinyscreenshot)
my_ids <- c("region_1", "region_2")
my_labels <- c("A", "B")
ui <- bs4DashPage(
title = "My Example",
header = bs4DashNavbar(),
sidebar = bs4DashSidebar(disable = TRUE),
body = bs4DashBody(
useShinyjs(),
# CSS for radio button styles and hiding elements
tags$style(HTML("
.btn-zero {background-color: white; color: black;}
.btn-zero.active {background-color: #a2ff45; color: black;}
.btn-one {background-color: white; color: black;}
.btn-one.active {background-color: #a2ff45; color: black;}
.btn-two {background-color: white; color: black;}
.btn-two.active {background-color: #a2ff45; color: black;}
.btn-three {background-color: white; color: black;}
.btn-three.active {background-color: #a2ff45; color: black;}
.region-label { line-height: 2.5; }
/* Hide elements during screenshot */
.hide-for-screenshot { display: none !important; }
")),
bs4Card(
title = "My Score",
width = 6,
style = "height: 200px; overflow: auto;",
tags$style(HTML("
.region-label { margin-top: -10px; }
")),
# Render radio buttons for each region
lapply(seq_along(my_ids), function(i) {
fluidRow(
column(6, h4(class = "region-label", paste(i-1, my_labels[i]))),
column(6, div(
style = "display: inline-block;",
shinyWidgets::radioGroupButtons(
inputId = my_ids[i],
label = NULL,
choices = 0:3,
selected = 0,
checkIcon = list(yes = icon("check")),
status = c("zero", "one", "two", "three"),
size = 'xs'
)
))
)
})
),
# Screenshot Button
actionButton("take_screenshot", "Take Screenshot", style = "margin-top: 10px;")
)
)
server <- function(input, output, session) {
observeEvent(input$take_screenshot, {
# Temporarily hide radio buttons
shinyjs::addClass(selector = ".radioGroupButtons", class = "hide-for-screenshot")
# Take screenshot and remove the hide class afterward
shinyscreenshot::screenshot()
# Show radio buttons again
shinyjs::removeClass(selector = ".radioGroupButtons", class = "hide-for-screenshot")
})
}
shinyApp(ui, server)
O que eu tentei
CSS personalizado: adicionei uma .hide-for-screenshot
classe CSS com display: none !important
; para ocultar elementos. A classe é aplicada logo antes de tirar a captura de tela e removida depois.
Usando shinyjs
: Estou usando shinyjs::addClass
e shinyjs::removeClass
para alternar a .hide-for-screenshot
classe no radioGroupButtons
.
Problema
Apesar de adicionar a hide-for-screenshot
classe e ocultá-la radioGroupButtons
antes de tirar a captura de tela, elas ainda aparecem na captura de tela. Suspeito que isso shinyscreenshot
pode não estar respeitando as alterações temporárias de CSS ou que o atraso não é suficiente para aplicar o estilo.
Pergunta
Como posso garantir que eles radioGroupButtons
fiquem completamente ocultos ao shinyscreenshot
capturar a tela?
Quaisquer sugestões ou abordagens alternativas seriam muito apreciadas! Obrigado.
Há alguns pontos a serem destacados sobre seu exemplo - primeiro, você está tentando ocultar o
radioGroupButton
objeto inteiro em vez de apenas o<input>
elemento que está causando o problema e também estava usando uma classe inválida - eles estão emradio-group-buttons
notradioGroupButtons
. Além disso, os eventos dentro de anobserveEvent
são acionados apenas no final, então seuaddClass
eremoveClass
cancelam um ao outro. Portanto, você precisa de trêsobserveEvents
, um para ocultá-los, um para tirar a captura de tela e outro para exibi-los. Observe que isso está ocultando todos os<input>
elementos no momento, o que provavelmente não é o que você deseja em seu caso de uso real, mas não consegui descobrir qual seletor usar.