Jump to content

fromCanvas as texture


Recommended Posts

Hello, guys! Who could help me with that issue? I want to update canvas background texture with a new image capturing full canvas with all elements trough reguestainmationframe on mousedown (bake canvas to image and replace the old texture with new bake canvas texture every time) achieve some kind of "smudge tool" like in Photoshop. But when I trying to call fromCanvas method I get an only black rectangle. I'm a little confused I mixed up something, but don't know what. Thank you!


Link to comment
Share on other sites

49 minutes ago, ivan.popelyshev said:

Ah, now I understand what you want. We need two separate renderTexture to do that trick :) Also, we need a loader instead of fromImage(). I'll write you code later. We'll make an example out of it.

@ivan.popelyshev Many thanks! I will be waiting, even a clue or direction in which way I need to dig will be great :-)

UPD. Sorry, I attached the wrong pen above that's why I removed it. I don't know why but my pen wasn't saved :-)

This is right pen :-)


Link to comment
Share on other sites

OK, put that thing into pixi-examples, or make fiddle out of it:

var app = new PIXI.Application(800, 600, {autoStart: false} );

var rt = [];
for (var i=0;i<2;i++) rt.push(PIXI.RenderTexture.create(app.screen.width, app.screen.height));
var current = 0;

var bg;
var brush;

app.loader.add('bg', 'https://raw.githubusercontent.com/pixijs/examples/gh-pages/required/assets/bkg-grass.jpg');
app.loader.add('one', 'https://raw.githubusercontent.com/PavelLaptev/test-rep/master/one.png');
app.loader.load(function(loader, resources) {
    var tempBg = new PIXI.Sprite(resources.bg.texture);
    tempBg.width = app.screen.width;
    tempBg.height = app.screen.height;

    app.renderer.render(tempBg, rt[0]);

    bg = new PIXI.Sprite(rt[0]);
    brush = new PIXI.Sprite(resources.one.texture);

    bg.filters = [new PIXI.filters.DisplacementFilter(brush)];

    app.stage.interactive = true;
    app.stage.on('pointerdown', onPointerDown);
    app.stage.on('pointerup', onPointerUp);
    app.stage.on('pointermove', onPointerMove);


function snap() {
    app.renderer.render(app.stage, rt[1 - current]);
    bg.texture = rt[1 - current];
    current = 1 - current;

var dragging = false;

function onPointerDown(event) {
    dragging = true;

function onPointerMove(event) {
    if (dragging) snap();

function onPointerUp() {
    dragging = false;


Now you can see that your texture doesnt have 0x808080 at the edge as its supposed too, and that's why whole grass field is moved too. I think you can deduce how it works without my help, if not please post the questions here.

Of course its not perfect: my demo makes snap() only on mouse move, and instead you should add something to ticker.

Link to comment
Share on other sites

@ivan.popelyshev Thank you again. I have nooby questions to better understand what's going on in code :-) Could you some things when you will have time. I marked questions on the picture below.

1) It's array where we push updated texture on mouse move?

2) We are pushing new textures here, but why i<2 ?

3) Why we need this current var?

4) Is it a texture for the very first canvas loading?

5) Here we are rendering updated texture?

Thank you!


Link to comment
Share on other sites

The issue I was trying to avoid is to render renderTexture on itself, that's why I used two of them. However, we use filter, and it uses one more temporary buffer, so, one texture will be enough for task :)

"current" is the number of the render texture we use right now.

4) is initialization of the texture, its possible only when bg is loaded , so we really need a loader there.

Link to comment
Share on other sites

@ivan.popelyshev Sorry for bothering you again :-) But I think you know answers for all PIXI questions :-) I made three containers with different RGB channels and applied for last two blend mode to achieve "normal" picture. But now I'm struggling how to snap all 3 containers into one. Might be I need to create the fourth container and capture all 3 containers into 4, but how? :-) Or use pixiRGBsplitFilter and mask it somehow :-) Might be you know in which direction I need to dig? Thank you!

I trying to achieve some kind of this effect


Link to comment
Share on other sites

Also, the easiest way to me seems like to render multiple containers, and then just blend them, but I didn't find how to do this.

app.renderer.render(containerRed, rt[1 - current]);
app.renderer.render(containerGreen, rt[1 - current]);
app.renderer.render(containerBlue, rt[1 - current]);


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

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