Download pixel art drawing as .png in PhaserJS



I need to download the created pixel drawing from this Phaser example as a .png image via FilesSaver.js but the canvas returns null.

Error:

Uncaught TypeError: Cannot read properties of null (reading ‘toBlob’)

This is the save function:

function save() { 
var canvasX = document.getElementById("canvas");
canvasX.toBlob(function(blob) { saveAs(blob, "image.png"); }); }

drawingArea: (PhaserJS 2)

function createDrawingArea() {

    game.create.grid('drawingGrid', 16 * canvasZoom, 16 * canvasZoom, canvasZoom, canvasZoom, 'rgba(0,191,243,0.8)');

    canvas = game.make.bitmapData(spriteWidth * canvasZoom, spriteHeight * canvasZoom);
    canvasBG = game.make.bitmapData(canvas.width + 2, canvas.height + 2);

    canvasBG.rect(0, 0, canvasBG.width, canvasBG.height, '#fff');
    canvasBG.rect(1, 1, canvasBG.width - 2, canvasBG.height - 2, '#3f5c67');

    var x = 10;
    var y = 64;

    canvasBG.addToWorld(x, y);
    canvasSprite = canvas.addToWorld(x + 1, y + 1);
    canvasGrid = game.add.sprite(x + 1, y + 1, 'drawingGrid');
    canvasGrid.crop(new Phaser.Rectangle(0, 0, spriteWidth * canvasZoom, spriteHeight * canvasZoom));

}

How to get the data of the drawing to create a .png out of it?

Answer

Well I don’t think the canvas has the ID canvas. That’s why, I asume that is the reason for the null Error. In any case I took the original example code, as a basis for this working solution.

Disclaimer: This Code will only create a image from the “drawn-image”, not the whole UI.

Main idea, On Save:

  1. create a new canvas
  2. draw the target area into the new canvas
  3. create the image, with filesave.js

Info: I’m getting information/values from the the globally defined variables canvasGrid and canvas, if your code, doesn’t contain them, this code will not work.

I hope this helps.

    function saveImage() { 
        // I assume there will be only one canvas on the page
        let realCanvas = document.querySelector('canvas');
        let ouputCanvas = document.createElement('canvas');
        let ctx = ouputCanvas.getContext('2d');

        // Get the target area (Details are from example code)
        let xOfGrid = canvasGrid.x - 1; // Info from Linie 267 from example
        let yOfGrid = canvasGrid.y - 1; // Info from Linie 267 from example

        // Info: this "canvas" is not a HTML Canvas Element
        let width = canvas.width;   // Info from Linie 256 from example
        let height = canvas.height; // Info from Linie 256 from example

        // Set initial Canvas Size
        ouputCanvas.width = width;
        ouputCanvas.height = height;

        // draw Image onto new Canvas
        ctx.drawImage(realCanvas, xOfGrid, yOfGrid, width, height, 0, 0, width, height);

        // Output Image, with filesaver.js
        ouputCanvas.toBlob(function onDone(blob) {
            saveAs(blob, "image.png");
        });
    }

    // An extra "Save Button", for testing
    window.addEventListener('DOMContentLoaded', function(){
        let btn = document.createElement('button');
        btn.innerText = 'SAVE FILE';
        btn.addEventListener('click', saveImage);
        document.body.prepend( btn );
    });
       


Source: stackoverflow