拖动滑块按钮时,颜色应该出现并改变,但什么也没有发生,屏幕右侧只有一个空白画布。我改变了一些东西,之前它甚至不是屏幕右侧的画布,但现在当有画布时,当我使用滑块选项(如颜色应该出现)时,不会发生任何事情。当我从下拉列表中选择一种颜色并使用滑块时,颜色也会发生变化:
# install.packages(c("shiny", "shinyjs"))
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
titlePanel("Drawing App"),
sidebarLayout(
sidebarPanel(
sliderInput("brushSize", "Brush Size", min = 1, max = 20, value = 5),
selectInput("brushColor", "Brush Color",
choices = c("Black", "Red", "Blue", "Green", "Eraser"),
selected = "Black")
),
mainPanel(
div(id = "canvas", style = "border:1px solid #000; height: 400px;"),
tags$script('
var isDrawing = false;
var context;
$(document).ready(function(){
var canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
$("#canvas").mousedown(function(e){
isDrawing = true;
context.beginPath();
context.moveTo(e.pageX - canvas.offsetLeft, e.pageY - canvas.offsetTop);
});
$("#canvas").mousemove(function(e){
if(isDrawing){
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
var color = $("#brushColor").val();
var size = $("#brushSize").val();
context.lineWidth = size;
if(color === "Eraser"){
context.strokeStyle = "#FFF"; // White color for eraser
} else {
context.strokeStyle = color.toLowerCase();
}
context.lineTo(x, y);
context.stroke();
}
});
$("#canvas").mouseup(function(){
isDrawing = false;
});
$("#canvas").mouseleave(function(){
isDrawing = false;
});
Shiny.setInputValue("canvasData", canvas.toDataURL());
});
Shiny.addCustomMessageHandler("clearCanvas", function(message) {
context.clearRect(0, 0, canvas.width, canvas.height);
});
')
)
)
)
server <- function(input, output, session) {
observe({
brush_color <- switch(input$brushColor,
"Black" = "black",
"Red" = "red",
"Blue" = "blue",
"Green" = "green",
"Eraser" = "white")
shinyjs::runjs(paste0('context.strokeStyle = "', brush_color, '";'))
})
observeEvent(input$canvasData, {
session$sendCustomMessage("clearCanvas", NULL)
shinyjs::runjs(paste0('var img = new Image(); img.src = "', input$canvasData, '"; context.drawImage(img, 0, 0);'))
})
}
shinyApp(ui, server)
请注意:
getContext()
上使用 div
,您必须使用 canvas
创建您的 tags$canvas(height="400px", id="canvas", style="border: 1px solid #000;")
。$(document).on("shiny:connected"
,否则当您尝试使用shiny
时,setInputValue
可能尚未准备好。canvas
和 width
的 height
属性: canvas.setAttribute("width", canvas.parentNode.offsetWidth); canvas.setAttribute("height", canvas.parentNode.offsetHeight);
var bounds = canvas.getBoundingClientRect();
并访问它们(例如 context.moveTo(e.pageX - bounds.left, e.pageY - bounds.top);
),否则光标位置将不匹配。然后就可以了。
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
titlePanel("Drawing App"),
sidebarLayout(
sidebarPanel(
sliderInput("brushSize", "Brush Size", min = 1, max = 20, value = 5),
selectInput("brushColor", "Brush Color",
choices = c("Black", "Red", "Blue", "Green", "Eraser"),
selected = "Black")
),
mainPanel(
tags$canvas(
height="400px", id="canvas", style="border: 1px solid #000;"
),
tags$script(HTML('
var isDrawing = false;
var context;
$(document).on("shiny:connected", function(){
var canvas = document.getElementById("canvas");
canvas.setAttribute("width", canvas.parentNode.offsetWidth);
canvas.setAttribute("height", canvas.parentNode.offsetHeight);
context = canvas.getContext("2d");
var bounds = canvas.getBoundingClientRect();
$("#canvas").mousedown(function(e){
isDrawing = true;
context.beginPath();
context.moveTo(e.pageX - bounds.left, e.pageY - bounds.top);
});
$("#canvas").mousemove(function(e){
if(isDrawing){
var x = e.pageX - bounds.left;
var y = e.pageY - bounds.top;
var color = $("#brushColor").val();
var size = $("#brushSize").val();
context.lineWidth = size;
if(color === "Eraser"){
context.strokeStyle = "#FFF"; // White color for eraser
} else {
context.strokeStyle = color.toLowerCase();
}
context.lineTo(x, y);
context.stroke();
}
});
$("#canvas").mouseup(function(){
isDrawing = false;
});
$("#canvas").mouseleave(function(){
isDrawing = false;
});
Shiny.setInputValue("canvasData", canvas.toDataURL());
});
Shiny.addCustomMessageHandler("clearCanvas", function(message) {
context.clearRect(0, 0, canvas.width, canvas.height);
});
'))
)
)
)
server <- function(input, output, session) {
observe({
brush_color <- switch(input$brushColor,
"Black" = "black",
"Red" = "red",
"Blue" = "blue",
"Green" = "green",
"Eraser" = "white")
shinyjs::runjs(paste0('context.strokeStyle = "', brush_color, '";'))
})
observeEvent(input$canvasData, {
session$sendCustomMessage("clearCanvas", NULL)
shinyjs::runjs(paste0('var img = new Image(); img.src = "', input$canvasData, '"; context.drawImage(img, 0, 0);'))
})
}
shinyApp(ui, server)