Colors should appear and change when dragging the slider button but nothing happens, there is just a blank canvas in the right hand side of the screen. I changed some things before it was not even a canvas on the right hand side of the screen but now when there is a canvas nothing happens when I use slider option like color should appear. When I select a color from the dropdown and use slider then the color should also change:
# 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)
Note that:
getContext()on adiv, you have to create yourcanvasusingtags$canvas(height="400px", id="canvas", style="border: 1px solid #000;").$(document).on("shiny:connected", otherwiseshinymay not be ready when you try to usesetInputValue.canvasattributes forwidthandheightshould be set up correctly:canvas.setAttribute("width", canvas.parentNode.offsetWidth); canvas.setAttribute("height", canvas.parentNode.offsetHeight);var bounds = canvas.getBoundingClientRect();and access them (e.g.context.moveTo(e.pageX - bounds.left, e.pageY - bounds.top);), otherwise the cursor position won't match.Then it will work.