I'm trying to load a page with a canvas and then save it as an image.
For example, this page. On Chrome, I can right click the canvas with a circle on the upper right side of the page and click save image. I want to do this exact same thing but through NodeJS and Puppeteer. Is this possible?
So far I'm trying to select it via
const express = require('express')
const router = express.Router()
const puppeteer = require('puppeteer')
const { Cluster } = require('puppeteer-cluster')
(async () => {
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 2,
})
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
await cluster.task(async({ page, data: url }) => {
// let starmapId = 'celestial-canvas'
await page.goto(url)
const canvas = await page.evaluate(() => document.querySelector('#myCanvas'))
return canvas // .toDataURL()
})
router.get('/export/canvas', function(req, res) {
// Get URL
var url = 'https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_canvas_tut_path2'
cluster.execute(url).then( canvas => {
console.log(canvas)
res.send(canvas)
})
})
})();
module.exports = router
But canvas is returning null.
In your example, the canvas is inside an iframe. So you need to get the frame first, then you will able to transfer the string with the data URL:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch(/* { headless: false, defaultViewport: null } */);
try {
const [page] = await browser.pages();
await page.goto('https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_canvas_tut_path2');
const frame = await (await page.$('#iframeResult')).contentFrame();
const data = await frame.evaluate(() => {
return document.querySelector('#myCanvas').toDataURL();
});
console.log(data); // data:image/png;base64,iVBORw0K...
} catch(err) { console.error(err); } finally { await browser.close(); }