I'd like to know when a user clicks on an image in a Shiny app. My full app displays images in a kind of "Photo Hunt" game and I want to capture how long it takes the user to click on a relevant place in each image. However, I'm having a hard time capturing client-side time, which is important because server-side times can be delayed for various reasons. I think I would need something like the following javascript, but I do not know how to integrate it in the app.
- Find the element on the page
var image = document.getElementById('img');
- Listen for the click and capture the time
addEventListener("click", true,
click_time = new Date().getTime();)
- Send the captured time to shiny server with something like:
Shiny.onInputChange("new_click_time",click_time);
- Listen in shiny to get the click_time
observeEvent(input$new_click_time,{
# This should be the time the user clicked on the image:
input$new_click_time
})
Here's an example shiny app that gets server-time, but not client-time:
library(shiny)
library(shinyjs)
options(digits.secs = 3) # Modify default global time to show milleseconds
shinyApp(
ui = fluidPage(
useShinyjs(),
sidebarLayout(
sidebarPanel(
p("When clicking on the histogram, I'd like to capture the client-side computer's time"),
actionButton(inputId="new_image", label= "New Image")
),
mainPanel(
imageOutput("img", click = "photo_click"),
textOutput("client_time"),
textOutput("server_time")
)
)
),
server = function(input, output) {
output$img <- renderImage({
input$new_image
outfile <- tempfile(fileext='.png')
png(outfile, width=400, height=400)
hist(rnorm(100))
dev.off()
list(src = outfile,
alt = "This is alternate text")
},
deleteFile = TRUE)
output$server_time <- renderText({
req(input$photo_click)
server.time <- as.character(strptime(Sys.time(), "%Y-%m-%d %H:%M:%OS")) # Time with milliseconds
paste("SERVER TIME:", server.time)
})
output$client_time <- renderText({
# cat("\nI'd like to capture click-time, possibly here -- the time on the client's machine when a click is made")
req(input$photo_click)
client.time <- "???" # Time with milliseconds
paste("CLIENT TIME:", client.time)
})
}
)