How to move rendered image (uploaded by the user) using arrow keys/action button in R shiny?

Viewed 50

Hi I'm currently making a dashboard that renders an image when a user uploads an image in R Shiny. But, I want to move it around using the arrow keys and/or using an action button and the only solution I can find is by using Javascript, but I don't know how to properly integrate it with R shiny.

This is my code so far:

library(shiny)
library(shinydashboard)
library(base64enc)

shinyApp(
  ui = fluidPage(
    fluidRow(box(
      width = 12,
      fileInput(
        "image",
        "Choose an image:",
        accept = ".jpeg"
      ),
      
      
      column(12, actionButton("submit1", "Submit"), align = "right")
    )),
    uiOutput('avatar'),
    actionButton("left", "", icon = icon("arrow-left")),
    actionButton("right", "", icon = icon("arrow-right")),
    actionButton("up", "", icon = icon("arrow-up")),
    actionButton("down", "", icon = icon("arrow-down"))

  ),
  server = function(input, output, session) {
    base64 <- reactive(
      if (input$submit1 == TRUE)
        
      {inFile <- input$image
      if(!is.null(inFile)){
        dataURI(file = inFile$datapath, mime = "image/jpeg")
      }}
    )
    
    output$avatar <- renderUI({
      if(!is.null(base64())){
        tags$div(
          tags$img(src= base64(), width="100%"),
          style = "width: 100px;"
        )
      }
    })
  }
)

This is what I found regarding the Javascript code about moving images using arrow keys (I don't know how to code in JavaScript so I'm lost):

$(document).on('keydown', function(e) {
  // e stands for "event" - the event is the keypress 
  // e.key means the key that was pressed

  switch (e.key) {

    // left arrow pressed
    case "ArrowLeft":
      $('#zebra').animate({
        left: "-=10px"
      }, 'fast');
      break;
      // up arrow pressed
    case "ArrowUp":
      $('#zebra').animate({
        top: "-=10px"
      }, 'fast');
      break;
      // right arrow pressed
    case "ArrowRight":
      $('#zebra').animate({
        left: "+=10px"
      }, 'fast');
      break;
      // down arrow pressed
    case "ArrowDown":
      $('#zebra').animate({
        top: "+=10px"
      }, 'fast');
      break;
  }
});

The #zebra is the id of the image that is used by the user who wrote the Javascript code as an example.

Thank you!

1 Answers

You were so close. Really all that was needed is to add position: relative; to your div. Works with position: absolute as well. Looks like it needs to be positioned since you are doing a "relative" animation. I also see that e.preventDefault() is needed to avoid unexpected behavior.

Source

Make sure you click inside the RESULT box in the snippet before testing.

$(document).on('keydown', function(e) {
  // e stands for "event" - the event is the keypress 
  // e.key means the key that was pressed
  e.preventDefault();
  switch (e.key) {

    // left arrow pressed
    case "ArrowLeft":
      $('#zebra').animate({
        left: "-=10px"
      }, 'fast');
      break;
      // up arrow pressed
    case "ArrowUp":
      $('#zebra').animate({
        top: "-=10px"
      }, 'fast');
      break;
      // right arrow pressed
    case "ArrowRight":
      $('#zebra').animate({
        left: "+=10px"
      }, 'fast');
      break;
      // down arrow pressed
    case "ArrowDown":
      $('#zebra').animate({
        top: "+=10px"
      }, 'fast');
      break;
      default :
        console.log("fell through");
  }
});
#zebra {
  position: relative;
  left: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="zebra">ZEBRA</div>

Related