I am trying to capture a screenshot of this game but when I try it simply return a blank image.
var data = document.getElementsByTagName("canvas")[0].toDataURL('image/png');
var out = document.createElement('img');
out.id = "sc";
out.src = data;
var link = document.createElement("a");
link.download = "sc.png";
link.href = out.src;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
The image downloads perfectly fine but it is simply blank.
I have tried a number of other methods including just printing the base64 to the console with console.log(document.querySelector("#openfl-content > canvas").toDataURL("image/png").split(',')[1]);
but when I put it into a decoder its blank once again.
EDIT: The above code works perfectly fine on my MacBook but does not work on my Windows PC regardless of the browser. I have no idea why.
Your original code wasn't giving you the output you expected, for a couple of reasons.
You are not appending the out
child to the DOM - there is no document.body.appendChild(out)
.
var data = document.getElementsByTagName("canvas")[0].toDataURL('image/png');
var out = document.createElement('img');
out.id = "sc";
out.src = data;
document.body.appendChild(out); // this is new
var link = document.createElement("a");
link.download = "sc.png";
link.href = out.src;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
document.body.removeChild(out); // this is new
Or you can avoid creating an img
element, and just use a
, with its href
set to the base64 image.
var data = document.getElementsByTagName("canvas")[0].toDataURL(); // specifying the type of image is not needed
var link = document.createElement("a");
link.download = "sc.png";
link.href = data;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
However, the previous will work under certain conditions:
The following code addresses both of these issues. I'm also using your initial coding style - var
for variables (instead of, const
or let
), Javascript specific selectors (instead of a generic querySelector(<selector>)
)
// This is where the actual game is
var gameIframe = document.getElementById("gameBox");
// The other one is a fallback, if you're clicking about in the code
// while inspecting the source, and changing your focus to different elements
// Based on what I've seen, there's only one canvas, and that's why this
// solution will work. If there were more canvases or iframes, the code would
// have to be different
var canvasElem = document.getElementsByTagName("canvas")[0];
// Let's check if you're in the main document
if(gameIframe) {
// Let's get the frame's document
var gameIframeContent = gameIframe.contentWindow.document;
// Once we have this, we can finally use the initial code to get the screenshot
// For this, I'm using requestAnimationFrame
// https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
// This will execute the initial screengrabbing code before the frame is repainted
gameIframeContent.defaultView.requestAnimationFrame(function() {
var data = gameIframeContent.getElementsByTagName("canvas")[0].toDataURL();
var link = gameIframeContent.createElement("a");
link.download = "sc.png";
link.href = data;
gameIframeContent.body.appendChild(link);
link.click();
gameIframeContent.body.removeChild(link);
});
// All is fine and dandy when we are witihn the main document
// But when we're not there, we won't get the screenshot
// The else if will check if we're focused (in the source)
// on the canvas element within the iframe
} else if(canvasElem) {
// Repeat the logic from the first if check
document.defaultView.requestAnimationFrame(function() {
// We already have the canvas
var data = canvasElem.toDataURL();
var link = document.createElement("a");
link.download = "sc.png";
link.href = data;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}
While this is working, it's actually not a very good way of doing things - we're repeating some bits of our code. This would be one way of optimizing:
function getElement(doc,selector) {
return doc.querySelector(selector);
}
function createScreenshot(canvasDocument, canvasElement) {
canvasDocument.defaultView.requestAnimationFrame(function() {
let data = canvasElement.toDataURL();
let link = canvasDocument.createElement("a");
link.download = "sc.png";
link.href = data;
canvasDocument.body.appendChild(link);
link.click();
canvasDocument.body.removeChild(link);
});
}
let gameIframe = getElement(document,"#gameBox");
let canvasElem = getElement(document,"canvas");
if(gameIframe) {
let gameIframeContent = gameIframe.contentWindow.document;
let gameIframeCanvas = getElement(gameIframeContent,"canvas");
createScreenshot(gameIframeContent,gameIframeCanvas);
} else if(canvasElem) {
createScreenshot(document,canvas);
} else {
alert("Sorry, nothing found!");
}