How to draw using createGraphics in p5.js?

Viewed 756

I have written code that draws while moving using beginShape and endShape. Now I am trying to use createGraphics as the list gets accumulated and very likely making the code lag. But I was not able to succeed can anyone point out where I am doing wrong.

This is the code I have been trying to make work with createGraphics

class Particle{
    constructor(){
        this.center = createVector(0,0);
        this.radius = 20;
        this.theta = 0;
        this.line = createVector(0,0);
        this.history = [];
        this.velocity = createVector();
        this.vel = 0.0;
    }
  
    render(){
        translate(60,60);
        circle(this.center.x,this.center.y,this.radius);
        circle(this.line.x+this.center.x, this.line.y+this.center.y,10); 
        noFill();
        graphics.fill(255);
        graphics.stroke(10);

        
        
            

        graphics.circle(pos.x, pos.y, 10);

        
        
    }
  
    update(){
        this.line.x = this.radius*cos(this.theta);
        this.line.y = this.radius*sin(this.theta);


        if (mouseIsPressed){
            if (this.vel < 1.0) {
                this.vel += 0.001
            }
            this.center.x += this.line.x * this.vel;
            this.center.y += this.line.y * this.vel;
            let v = createVector(this.center.x, this.center.y);
            
            let h = this.history;
            if (h.length == 0 || Math.trunc(h[h.length-1].x) != Math.trunc(v.x) || Math.trunc(h[h.length-1].y) != Math.trunc(v.y)) { 
                this.history.push(v);
            }
        
        } else{
            this.vel = 0.0  
            this.theta += 0.01;
        } 
    }
}
let particle;
let graphics;

function setup() {
    let can = createCanvas(windowWidth-220, windowHeight-90);  
    graphics = createGraphics(windowWidth-220, windowHeight-90);
    graphics.background(220);
    can.position(210, 75);

    particle = new Particle();
}

function draw() {
    background(220);
    particle.render();
    image(graphics,0,0);
    particle.update();
}

I am attaching the code before the update.

class Particle{
    constructor(){
        this.center = createVector(0,0);
        this.radius = 20;
        this.theta = 0;
        this.line = createVector(0,0);
        this.history = [];
        this.velocity = createVector();
        this.vel = 0.0;
    }
  
    render(){
        translate(60,60);
        circle(this.center.x,this.center.y,this.radius);
        circle(this.line.x+this.center.x, this.line.y+this.center.y,10); 

        beginShape();
        for(let i=0;i < this.history.length; i++){
            let pos = this.history[i];
            noFill();
            vertex(pos.x, pos.y);
        }
        endShape();
    }
  
    update(){
        this.line.x = this.radius*cos(this.theta);
        this.line.y = this.radius*sin(this.theta);

        if (mouseIsPressed){
            if (this.vel < 1.0) {
                this.vel += 0.001
            }
            this.center.x += this.line.x * this.vel;
            this.center.y += this.line.y * this.vel;
            let v = createVector(this.center.x, this.center.y);
            
            let h = this.history;
            if (h.length == 0 || Math.trunc(h[h.length-1].x) != Math.trunc(v.x) || Math.trunc(h[h.length-1].y) != Math.trunc(v.y)) { 
                this.history.push(v);
            }
        
        } else{
            this.vel = 0.0  
            this.theta += 0.01;
        } 
    }
}
 
let particle;

function setup() {
    createCanvas(windowWidth, windowHeight);  
    particle = new Particle();
}

function draw() {
    background(220);
    particle.render();
    particle.update();
}
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script>
</body>
</html>

1 Answers

Create a p5.Renderer object the size of the screen and fill it with the background color:

let particle;
let particleGraphics;

function setup() {
    createCanvas(windowWidth, windowHeight); 
    particleGraphics = createGraphics(windowWidth, windowHeight);
    particleGraphics.background(220); 
    particle = new Particle();
}

Instead of filling the canvas background, draw the graphics:

function draw() {
    image(particleGraphics, 0, 0)
    particle.render();
    particle.update();
}

Remove the code that draws the lines:

// DELETE
//beginShape();
//for(let i=0;i < this.history.length; i++){
//    let pos = this.history[i];
//    noFill();
//    vertex(pos.x, pos.y);
//}
//endShape();

However, add a single line segment to the graphic as the object moves:

if (mouseIsPressed){
    // [...]
    
    let h = this.history;
    if (h.length == 0 || Math.trunc(h[h.length-1].x) != Math.trunc(v.x) || Math.trunc(h[h.length-1].y) != Math.trunc(v.y)) { 
        this.history.push(v);

        if (this.history.length > 1) {
            let v1 = this.history[this.history.length-2];
            let v2 = this.history[this.history.length-1];
            particleGraphics.line(60 + v1.x, 60 + v1.y, 60 + v2.x, 60 + v2.y);
        }
    }
    // [...]
} 

Complete example:

class Particle{
    constructor(){
        this.center = createVector(0,0);
        this.radius = 20;
        this.theta = 0;
        this.line = createVector(0,0);
        this.history = [];
        this.velocity = createVector();
        this.vel = 0.0;
    }
  
    render(){
        translate(60,60);
        fill(255)
        circle(this.center.x,this.center.y,this.radius);
        circle(this.line.x+this.center.x, this.line.y+this.center.y,10); 
    }
  
    update(){
        this.line.x = this.radius*cos(this.theta);
        this.line.y = this.radius*sin(this.theta);

        if (mouseIsPressed){
            if (this.vel < 1.0) {
                this.vel += 0.001
            }
            this.center.x += this.line.x * this.vel;
            this.center.y += this.line.y * this.vel;
            let v = createVector(this.center.x, this.center.y);
            
            let h = this.history;
            if (h.length == 0 || Math.trunc(h[h.length-1].x) != Math.trunc(v.x) || Math.trunc(h[h.length-1].y) != Math.trunc(v.y)) { 
                this.history.push(v);

                if (this.history.length > 1) {
                    let v1 = this.history[this.history.length-2];
                    let v2 = this.history[this.history.length-1];
                    particleGraphics.line(60 + v1.x, 60 + v1.y, 60 + v2.x, 60 + v2.y);
                }
            }

        } else{
            this.vel = 0.0  
            this.theta += 0.01;
        } 
    }
}
 
let particle;
let particleGraphics;

function setup() {
    createCanvas(windowWidth, windowHeight); 
    particleGraphics = createGraphics(windowWidth, windowHeight);
    particleGraphics.background(220); 
    particle = new Particle();
}

function draw() {
    image(particleGraphics, 0, 0)
    particle.render();
    particle.update();
}
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script>
</body>
</html>

Related