I have a Shiny application that generates one image after clicking an action button, and saves the screenshot of that image after pressing on another action button. The code is working, but I now need to do the same in a loop for 500 cases, in R but without Shiny, automatically, without clicking between plots, saving the screenshots in a folder. (I don't need to see the plots being generated but, for debugging purposes, it might help initially to see them.)
Currently the image is generated with a commercial plotting library, called by the nice.js files. The js files and the library are in the ./www folder.
I cannot put a proper reproducible example because of the commercial library.
Based on Stéphane's answer, I modified the question.
The code now reads ...
library(htmltools)
dep <- htmlDependency(
name = "html2canvas",
version = "1.4.1",
src = list(paste0(getwd(),"/www")),
script = "html2canvas.js",
all_files = FALSE
)
myscript <- HTML('
function takeshot(i) {
var captureElement = document.getElementById("myframe");
html2canvas(captureElement)
.then(function (canvas) {
canvas.style.display = "none";
document.body.appendChild(canvas);
return canvas;
})
.then(function (canvas) {
var image = canvas
.toDataURL("image/png")
.replace("image/png", "octet-stream");
var a = document.createElement("a");
a.setAttribute("download", "./www/my-image-" + i + ".png");
a.setAttribute("href", image);
a.click();
canvas.remove();
});
}
')
for(i in 1:500){
print(
browsable(
tagList(
dep,
tags$div(
#xxxxx plot goes here xxxxx
tags$script(src='commercial library goes here.js'),
id = 'myframe',
htmltools::includeScript(paste0(getwd(),'/www/nice_',i,'.js')),
),
# tags$button( 'Take screenshot', onclick = 'takeshot();' ),
# tags$h1('Screenshot:'),
tags$div(id = 'output'),
tags$script(myscript) # tags$script('takeshot(i);'), # <======= calling takeshot(i) here?
) # closes tagList
) # closes browsable
) # closes print
Sys.sleep(2)
}
The plotting part of the code works well and, if one has a single plot, will download the image after one clicks the "Take screenshot" button.
However, I have to do this for 500 files. Is there a way of downloading the screenshots automatically, without clicking? (Perhaps there must be some delay between the generation of the image and the screenshot.)
I tried to modify the 'takeshot' function to save the files as my-image-1.png, my-image-2.png, ..., my-image-500.png, but it doesn't download anything.
Thanks
You can do something like this:
library(htmltools)
# html2canvas: https://html2canvas.hertzen.com/
dep <- htmlDependency(
name = "html2canvas",
version = "1.4.1",
src = "path/to/html2canvas",
script = "html2canvas.js",
all_files = FALSE
)
myscript <- HTML('
function takeshot() {
var div = document.getElementById("myframe");
html2canvas(div).then(function (canvas) {
document.getElementById("output").appendChild(canvas);
});
}
')
app <- tagList(
dep,
tags$div(
id = "myframe",
#xxxxx plot goes here xxxxx
),
tags$button(
"Take screenshot",
onclick = "takeshot();"
),
tags$h1("Screenshot:"),
tags$div(id = "output"),
tags$script(myscript)
)
browsable(app)
You'll have to include the JavaScript library you use as dependency as well, and a script which generates your plot.
Sorry, rather use this function for the automatic download:
function takeshot() {
var captureElement = document.getElementById("myframe");
html2canvas(captureElement)
.then(function (canvas) {
canvas.style.display = "none";
document.body.appendChild(canvas);
return canvas;
})
.then(function (canvas) {
var image = canvas
.toDataURL("image/png")
.replace("image/png", "image/octet-stream");
var a = document.createElement("a");
a.setAttribute("download", "my-image.png");
a.setAttribute("href", image);
a.click();
canvas.remove();
});
}
Based on my tests this doesn't seem to function without the "click". Any way to automate it, seems this has not be resolved across multiple forums.