How to save a canvas as an image using puppeteer?

5k Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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(); }