Jump to content

Updating existing texture with canvas content


unlink2
 Share

Recommended Posts

Hello,

As many of you I have recently started using Phaser 3. I've been trying to use a normal 2D canvas as a texture and update a texture in the TextureManager without recreating the canvas.
Is this possible?
My current approach works, but is leaking memory all over the place which I do not want of course.
Here's what I have tried so far.

this.canvasTexture = this.game.textures.createCanvas(this.id + '_aelu', 320, 200);
this.createScreen();
createScreen() {
        this.canvas = this.canvasTexture.getSourceImage();
        this.context = this.canvas.getContext('2d');
        this.imageData = this.context.getImageData(0, 0, 320, 200);
        this.pixelArray = this.imageData.data;

        this.context.clearRect(0, 0, 320, 200);
        for (var p = 0; p < this.pixelArray.length / 4; p++) {
            var index = 4 * p;

            this.pixelArray[index] = Math.random() * Math.floor(255); // r
            this.pixelArray[++index] = Math.random() * Math.floor(255); // g
            this.pixelArray[++index] = Math.random() * Math.floor(255); // b
            this.pixelArray[++index] = 255; // a
        }

        // this does not update the actual texture
        this.context.putImageData(this.imageData, 0, 0);

        // this would be nice, but it seems like it does not actually update the texture?
        // this.canvasTexture.setDataSource(this.canvas);

        // this updates the texture but causes huge memory issues
        /* this.game.textures.get(this.id + '_aelu_out').destroy();

        this.game.textures.addSpriteSheet(this.id + '_aelu_out', this.canvasTexture.getSourceImage(),          {
            frameWidth: 320,
            frameHeight: 200,
        });*/
 }

Thanks for any pointers in the right direction :>

Link to comment
Share on other sites

This changed in 3.7 so it now returns a CanvasTexture object, which is a lot easier to work with. Try the following:

var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: {
        create: create
    }
};

var texture;

var game = new Phaser.Game(config);

function create ()
{
    texture = this.textures.createCanvas('gradient', 16, 256);

    //  We can access the underlying Canvas context like this:
    var grd = texture.context.createLinearGradient(0, 0, 0, 256);

    grd.addColorStop(0, '#8ED6FF');
    grd.addColorStop(1, '#004CB3');

    texture.context.fillStyle = grd;
    texture.context.fillRect(0, 0, 16, 256);

    //  Call this if running under WebGL, or you'll see nothing change
    texture.refresh();

    //  Add a bunch of images that all use the same texture
    for (var i = 0; i < 64; i++)
    {
        var image = this.add.image(8 + i * 16, 0, 'gradient');

        this.tweens.add({
            targets: image,
            y: 650,
            duration: 2000,
            ease: 'Quad.easeInOut',
            delay: i * 62.5,
            yoyo: true,
            repeat: -1
        });
    }

    this.time.addEvent({ delay: 4000, callback: updateTexture, callbackScope: this, loop: true });
}

function updateTexture ()
{
    var grd = texture.context.createLinearGradient(0, 0, 0, 256);

    grd.addColorStop(0, generateHexColor());
    grd.addColorStop(1, generateHexColor());

    texture.context.fillStyle = grd;
    texture.context.fillRect(0, 0, 16, 256);

    //  Call this if running under WebGL, or you'll see nothing change
    texture.refresh();
}

function generateHexColor ()
{
    return '#' + ((0.5 + 0.5 * Math.random()) * 0xFFFFFF << 0).toString(16);
}

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...