Animated lines with glow

Hello,

I’m trying to create an animation of this kind of image : This image

So far, here is what I accomplished : Link

The thing is I’m not drawing “lines” but dots in a renderTexture object and that’s why you can see dots when it speeds up. Do you know how I could figure it out ? I want to be able to control the x /y speed and rotation of the lines.

Another question, I did not manage to have a glow effect on my dots/renderTexture, so I created 3 dots with different alpha/color but it’s not really great. Can we put a glow effect on a renderTexture ?

Sorry I just came back to Phaser after some years and a lot of things changed :slight_smile:

Here is my code, thanks !

class MyScene extends Phaser.Scene {
            constructor() {
                super();
            }
            
            
            create() {
                this.width = 300;
                this.height = 250;
                this.isDrawing = true;
                
                this.mouvement = {speedX:.1, speedY: .05, rot:.01};
                
                // RenderTexture
                this.rt = this.add.renderTexture(150, 125, this.width, this.height);
                
                // Graphics for dots
                this.g = this.add.graphics();
                
                // initial position of dots/line                
                this.cx = 0;
                this.cy = 150;
                
                // dots offsets
                this.offsets = [-20, -15, -10, -5, 0, 5, 10, 15, 20];
                
                this.angle = Math.PI/2;
                
                // initial speed
                this.vx = .05;
                this.vy = .05; 
                
//Timelines to control X / Y / Rotation  (maybe not great but I want a specific shape)
                var timelineX = this.add.timeline([
                {
                    at:500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.12
                    }
                },
                {
                    at:1500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.09
                    }
                },
                {
                    at:3000,
                    tween:{
                        targets:this.mouvement,
                        speedX:.06
                    }
                },
                {
                    at:4500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.12
                    }
                },
                
                ]);
                
                var timelineY = this.add.timeline([
                {
                    at:100,
                    tween:{
                        targets:this.mouvement,
                        speedY:-.1
                    }
                },
                {
                    at:1000,
                    tween:{
                        targets:this.mouvement,
                        speedY:.1
                    }
                },
                {
                    at:2000,
                    tween:{
                        targets:this.mouvement,
                        speedY:-.2
                    }
                },
                {
                    at:3000,
                    tween:{
                        targets:this.mouvement,
                        speedY:.04
                    }
                },
                
                ]);
                
                var timelineRot = this.add.timeline([
                    {
                    at:500,
                    tween:{
                        targets:this.mouvement,
                        rot:.05
                    }
                },
                {
                    at:2000,
                    tween:{
                        targets:this.mouvement,
                        rot:-.05
                    }
                }                
                ]);


                timelineX.play();
                timelineY.play();
                timelineRot.play();
                
                
               
            }
            
            drawGlow(x, y) {                
                
                // big transparent halo
                this.g.fillStyle(0xffffff, 0.02);
                this.g.fillCircle(0, 0, 6);
                
                // normal halo
                this.g.fillStyle(0x3bfdfd, 0.01);
                this.g.fillCircle(0, 0, 3);
                
                // dot
                this.g.fillStyle(0x3bfdfd, .5);
                this.g.fillCircle(0, 0, 1);

                //this.g.postFX.addGlow(0x3bfdfd, 8, 8, true, 0.6, 24);
                
                this.rt.draw(this.g, x, y);
                this.g.clear();
                
                if(this.cx > 330) this.isDrawing = false;
            }
            
            update(time, delta) {
                
                if(this.isDrawing){
                    // update position
                    this.cx += this.mouvement.speedX * delta;
                    this.cy += this.mouvement.speedY * delta;   
                    
                    
                    
                    // rotation
                    this.angle += this.mouvement.rot;
                    
                    // direction
                    let dx = Math.cos(this.angle);
                    let dy = Math.sin(this.angle);
                    
                    // draw dots
                    for (let i = 0; i < this.offsets.length; i++) {
                        let x = this.cx + this.offsets[i] * dx;
                        let y = this.cy + this.offsets[i] * dy;
                        this.drawGlow(x, y);
                    }
                }
            }
        }
        
        const config = {
            type: Phaser.CANVAS,
            width: 300,
            height: 250,
            backgroundColor: "#01213A",
            scene: MyScene
        };
        
        new Phaser.Game(config);

I don’t know why the glow isn’t working, but I changed your code to use lines instead of dots. I made an array to store the previous offset positions, then on the next draw call, it will draw a line between the current dot and the previous corresponding dot from the previous frame. Also, I removed the renderTexture, not sure why it was being used. I kept your glow code.

class MyScene extends Phaser.Scene {
            constructor() {
                super();
            }
            
            
            create() {
                this.width = 300;
                this.height = 250;
                this.isDrawing = true;
                
                this.mouvement = {speedX:.1, speedY: .05, rot:.01};
                
                // RenderTexture
                // this.rt = this.add.renderTexture(150, 125, this.width, this.height);
                
                // Graphics for dots
                this.g = this.add.graphics();

                // this.g.postFX.addGlow(0xffffff, 4, 0, false, 0.1, 24);
                
                // initial position of dots/line                
                this.cx = 0;
                this.cy = 150;
                
                // dots offsets
                this.offsets = [-20, -15, -10, -5, 0, 5, 10, 15, 20];
                
                this.angle = Math.PI/2;
                
                // initial speed
                this.vx = .05;
                this.vy = .05; 
                
//Timelines to control X / Y / Rotation  (maybe not great but I want a specific shape)
                var timelineX = this.add.timeline([
                {
                    at:500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.12
                    }
                },
                {
                    at:1500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.09
                    }
                },
                {
                    at:3000,
                    tween:{
                        targets:this.mouvement,
                        speedX:.06
                    }
                },
                {
                    at:4500,
                    tween:{
                        targets:this.mouvement,
                        speedX:.12
                    }
                },
                
                ]);
                
                var timelineY = this.add.timeline([
                {
                    at:100,
                    tween:{
                        targets:this.mouvement,
                        speedY:-.1
                    }
                },
                {
                    at:1000,
                    tween:{
                        targets:this.mouvement,
                        speedY:.1
                    }
                },
                {
                    at:2000,
                    tween:{
                        targets:this.mouvement,
                        speedY:-.2
                    }
                },
                {
                    at:3000,
                    tween:{
                        targets:this.mouvement,
                        speedY:.04
                    }
                },
                
                ]);
                
                var timelineRot = this.add.timeline([
                    {
                    at:500,
                    tween:{
                        targets:this.mouvement,
                        rot:.05
                    }
                },
                {
                    at:2000,
                    tween:{
                        targets:this.mouvement,
                        rot:-.05
                    }
                }                
                ]);


                timelineX.play();
                timelineY.play();
                timelineRot.play();
                
                
               
            }
            
            drawGlow(px, py, x, y) {                
                
                // big transparent halo
                this.g.lineStyle(8, 0xffffff, 0.1);
                this.g.lineBetween(px, py, x, y)
                
                // normal halo
                this.g.lineStyle(3, 0x3bfdfd, 0.2);
                this.g.lineBetween(px, py, x, y)
                
                // dot
                this.g.lineStyle(1, 0x3bfdfd, 1);
                this.g.lineBetween(px, py, x, y)

                if(this.cx > 330) this.isDrawing = false;
            }
            
            update(time, delta) {
                
                if(this.isDrawing){
                    // update position
                    this.cx += this.mouvement.speedX * delta;
                    this.cy += this.mouvement.speedY * delta;

                    
                    // rotation
                    this.angle += this.mouvement.rot;
                    
                    // direction
                    let dx = Math.cos(this.angle);
                    let dy = Math.sin(this.angle);
                    
                    // draw dots
                    if(!this.prev) {
                        this.prev = [];
                        for (let i = 0; i < this.offsets.length; i++) {
                            let x = this.cx + this.offsets[i] * dx;
                            let y = this.cy + this.offsets[i] * dy;
                            this.prev[i] = [x,y];
                        }
                    } else {
                        for (let i = 0; i < this.offsets.length; i++) {
                            let x = this.cx + this.offsets[i] * dx;
                            let y = this.cy + this.offsets[i] * dy;
                            this.drawGlow(this.prev[i][0], this.prev[i][1], x, y);
                            this.prev[i] = [x,y];
                        }
                    }
                }
            }
        }
        
        const config = {
            type: Phaser.CANVAS,
            width: 300,
            height: 250,
            backgroundColor: "#01213A",
            scene: MyScene
        };
        
        new Phaser.Game(config);
```

You have these two lines commented out:

this.rt = this.add.renderTexture(150, 125, this.width, this.height);
this.g.postFX.addGlow(0xffffff, 4, 0, false, 0.1, 24);

Are these the lines you’re trying to get to work? It does look different if you enable those, but you have to change to type:Phaser.WEBGL in your config object for them to work.

EDIT: Sorry, I was looking at the wrong code snippet. To get the postFX and renderTexture to work, I believe you have to use type:Phaser.WEBGL