блестящий интерактивный сюжет со смартфона не понимает движений пальцев - PullRequest
9 голосов
/ 28 июня 2019

У меня есть приложение R-Shiny с графиком, который реализует интерактивные действия: щелчок, зависание (зависание - это наведение мыши на график, который можно обнаружить по блеску). Чтобы дать идею, я выкладываю ниже упрощенный shinyapp с функциональностью, которая проблематична для меня, интерактивный сюжет для рисования. (взято из моего старого ответа здесь )

На самом деле он работает нормально, однако мне нужно, чтобы люди использовали его со своих смартфонов . Проблема: движения пальцев, которые мы делаем в смартфоне, интерпретируются телефоном как увеличение на странице или прокрутка на странице, а не как выбор мыши или движение мыши над сюжет (зависание).

Существует ли модификация кода (java? Css?), Которую я могу внедрить в приложение, чтобы превратить сенсорные события в события мыши, или параметр / жест на смартфоне для включения движения, похожего на мышь?

Большое спасибо. Код:

library(shiny)
ui <- fluidPage(
  h4("Click on plot to start drawing, click again to pause"),
  sliderInput("mywidth", "width of the pencil", min=1, max=30, step=1, value=10),
  actionButton("reset", "reset"),
  plotOutput("plot", width = "500px", height = "500px",
             hover=hoverOpts(id = "hover", delay = 100, delayType = "throttle", clip = TRUE, nullOutside = TRUE),
             click="click"))
server <- function(input, output, session) {
  vals = reactiveValues(x=NULL, y=NULL)
  draw = reactiveVal(FALSE)
  observeEvent(input$click, handlerExpr = {
    temp <- draw(); draw(!temp)
    if(!draw()) {
      vals$x <- c(vals$x, NA)
      vals$y <- c(vals$y, NA)
    }})
  observeEvent(input$reset, handlerExpr = {
    vals$x <- NULL; vals$y <- NULL
  })
  observeEvent(input$hover, {
    if (draw()) {
      vals$x <- c(vals$x, input$hover$x)
      vals$y <- c(vals$y, input$hover$y)
    }})
  output$plot= renderPlot({
    plot(x=vals$x, y=vals$y, xlim=c(0, 28), ylim=c(0, 28), ylab="y", xlab="x", type="l", lwd=input$mywidth)
  })}
shinyApp(ui, server)

1 Ответ

1 голос
/ 20 июля 2019

Я заметил, что это вторая награда за этот вопрос за последнюю неделю, так что она кажется неотложной.

Хотя я не могу полностью решить вопрос, возможно, грязный обходной путь также может иметь некоторую ценность для вас. Или кто-то еще может опираться на этот ответ.

Я мог воспроизвести ошибку, заключающуюся в том, что клики на графике не фиксируются на мобильном телефоне. Но я заметил, что могу добавить дополнительные кликвенты с помощью javascript / smoothjs.

Один из способов будет:

  onevent(event = "click", id = "plot", function(e){
    global$clickx = c(global$clickx, e$pageX - 88)
    global$clicky = c(global$clicky, 540 - e$pageY)
  })

Имеет несколько недостатков:

  • фигуры нарисованы только линиями, это не захватывает все зависание на графике
  • позиция довольно неточная, так как вы должны учитывать границы и поля (очень грязные, но потенциальные здесь)

Через несколько часов у меня немного вышло время, его наверняка можно улучшить, но, может быть, оно все равно вас заинтересует.

Проверьте здесь: (ссылка может измениться в течение следующих недель)

http://ec2 -35-158-220-30.eu-central-1.compute.amazonaws.com / блестящий / rstudio / образец-приложения / мобильный /

Код воспроизводимого файла: (проверено на смартфоне: Mi A2)

library(shiny)
library(shinyjs)
ui <- fluidPage(
  useShinyjs(),
  h4("Click on plot to start drawing, click again to pause"),

  plotOutput(outputId = "plot", width = "500px", height = "500px")
)


server <- function(input, output, session) {

  onevent(event = "click", id = "plot", function(e){
    global$clickx = c(global$clickx, e$pageX - 88)
    global$clicky = c(global$clicky, 540 - e$pageY)
  })

  global <- reactiveValues(clickx = NULL, clicky = NULL)

  output$plot= renderPlot({
    plot(x = NULL, y = NULL, xlim=c(0, 440), ylim=c(0, 440), ylab="y", xlab="x", type="l")
    len <- length(global$clickx)
    lines(x = global$clickx, y = global$clicky, type = "p")      
    if(len > 1){
      for(nr in 2:len){
        lines(x = global$clickx[(nr - 1):nr], y = global$clicky[(nr - 1):nr], type = "l")
      }
    }
  })
}
shinyApp(ui, server)
...