Hello!
In phaser 3, how can I change a color image completely? I mean the following:
Is this possible? Thanks!
Hello!
In phaser 3, how can I change a color image completely? I mean the following:
Is this possible? Thanks!
For WebGL: image.setTint(0)
For Canvas youâll have to look at Compositing or Pixel manipulation.
Iâm using CAVAS in my projetc.
The second option seems to better fit what Iâm looking for. Iâve investigating for a while, but I really donât understand how to start using âCompositingâ or âPixel manipulationâ on a image.
If you could give me a more precise example of how it works, I would appreciate it.
This is how Phaser2 used Pixi to do it:
With a Phaser3 CanvasTexture you can use all the standard Canvas operations, and if needed, access every pixel individually.
Thanks, Milton.
You were correct, and with this example I did exactly what I needed:
That is the Pixel manipulation way.
It is (very) slow, because of getImageData/putImageData. It does give you full control.
The much faster way (if you had to do it every frame), is using compositing.
Draw a filled rectangle in the color you want to tint with.
Then set context.globalCompositeOperation = 'multiply';
Now draw your image.
You now have a tinted image (rectangular).
To get rid of the rectangle, now set context.globalCompositeOperation = 'destination-atop';
And draw your image again. Only the overlap remains.
Thatâs very interesting. Iâm trying to test that way but Iâm constantly getting a âgetContextâ error in my code, I donât know why. And to be sure, I copied the code for the example that appeared in the link you left, but I keep getting that error.
This is the code:
> function draw() {
> var ctx = document.getElementById('canvas').getContext('2d');
> ctx.fillRect(0, 0, 150, 150);
> ctx.translate(75, 75);
>
> // Create a circular clipping path
> ctx.beginPath();
> ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
> ctx.clip();
>
> // draw background
> var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
> lingrad.addColorStop(0, '#232256');
> lingrad.addColorStop(1, '#143778');
>
> ctx.fillStyle = lingrad;
> ctx.fillRect(-75, -75, 150, 150);
>
> // draw stars
> for (var j = 1; j < 50; j++) {
> ctx.save();
> ctx.fillStyle = '#fff';
> ctx.translate(75 - Math.floor(Math.random() * 150),
> 75 - Math.floor(Math.random() * 150));
> drawStar(ctx, Math.floor(Math.random() * 4) + 2);
> ctx.restore();
> }
>
> }
>
> function drawStar(ctx, r) {
> ctx.save();
> ctx.beginPath();
> ctx.moveTo(r, 0);
> for (var i = 0; i < 9; i++) {
> ctx.rotate(Math.PI / 5);
> if (i % 2 === 0) {
> ctx.lineTo((r / 0.525731) * 0.200811, 0);
> } else {
> ctx.lineTo(r, 0);
> }
> }
> ctx.closePath();
> ctx.fill();
> ctx.restore();
> }
>
> draw();
Pixi obviously created a âcanvasâ element in the index.html.
Iâm guessing you didnât
Add something like this to index.html:
<canvas id="canvas"></canvas>
Yes, that was it. But now Iâm a bit confused, in my game, I use a parent container:
<div id = 'container'> </div>
So now I have two canvas that are separate, and I donât know how to do the compositing from this point.
Ah, you donât want separate canvases.
So forget about adding a canvas in index.html.
Just use
var ctx = game.canvas.getContext('2d');
assuming const game = new Phaser.Game(config);
Or use a Phaser Graphics Object.
Actually I tried that but I was getting the error I said before.
I will take a look at the Phaser Graphics Object.
game.canvas gives null?
Did you change
var ctx = document.getElementById('canvas').getContext('2d');
to
var ctx = game.canvas.getContext('2d');
It seems impossible that would be undefinedâŚ
Oh, that was because I had that code outside of my Function Create. .
Now, when I try to draw something, nothing shows up on my canvas.
function draw() {
var ctx = game.canvas.getContext('2d');
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' +
Math.floor(255 - 42.5 * j) + ')';
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
}
}
}
draw();
I guess Phaser doesnât like people meddling with the canvas outside of its own displaylist, scenegraph etc.
So use one of Phaserâs Canvas options, either CanvasTexture which lets you use it as a standard canvas, or Graphics, which is slightly different, using Blendmodes.
Well, does that mean I canât use the Compositing? Because Iâve trying for a while and I canât get it to work with the CanvasTexture.
Thank you for your patience.
function create() {
originalTexture = this.textures.get('dude').getSourceImage();
var newTexture = this.textures.createCanvas('dude_new', originalTexture.width, originalTexture.height);
var ctx = newTexture.context;
ctx.fillStyle = '#00ff00';
ctx.fillRect(0, 0, originalTexture.width, originalTexture.height);
ctx.globalCompositeOperation = 'multiply';
ctx.drawImage(originalTexture, 0, 0);
ctx.globalCompositeOperation = 'destination-atop';
ctx.drawImage(originalTexture, 0, 0);
dude = this.add.image(100, 100, 'dude');
dude2 = this.add.image(200, 100, 'dude_new');
}
Thanks a lot. Youâve been a great help