Search code examples
javascriptprocessingp5.js

Text displayed twice in p5.js


When I try to add text to p5.js canvas, it got displayed twice for some reason. Attached code below:

let img;

function setup() {
    createCanvas(screen.availWidth, screen.availHeight);
    img = loadImage('https://mediumpurpleperfumeddegrees.boyuan12.repl.co/circuit1.webp');
    textOutput();
}

function draw() {
     image(img, screen.availWidth / 2 - img.width, 0, img.width * 1.25, img.height * 1.25);
     textSize(20);
     text('5V', screen.availWidth / 2 - img.width - 20, img.height / 2 + 30);
     text('50Ω', screen.availWidth / 2 - img.width + 100, img.height / 2 - 45);
     text('100Ω', screen.availWidth / 2 - img.width + 220, img.height / 2 + 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

Output p5.js sketch

I tried to look through documentation but found none too helpful.


Solution

  • draw() runs many times per second, intended for animation. Usually, you want to clear the screen before redrawing it, otherwise you can wind up with ghost images.

    You're loading the image in setup, which doesn't wait for the image to show up before starting the draw() loop. Initially, img.width is 1 for a few frames, then the image loads and it becomes whatever the image's width is, 200 or so. The combination of draw() running without clear and the asynchronous image load causes the text to show up in two places.

    Instead, use preload to avoid drawing anything until your image is ready and either disable the animation loop with noLoop() or use background() or clear() at the top of draw() to wipe stale drawings.

    let img;
    
    function preload() { // fix 1
      img = loadImage(
        "https://mediumpurpleperfumeddegrees.boyuan12.repl.co/circuit1.webp"
      );
    }
    
    function setup() {
      createCanvas(screen.availWidth, screen.availHeight);
      textOutput();
      noLoop(); // fix 2
    }
    
    function draw() {
      // clear() // alternative to noLoop() if you want animation
      image(img, screen.availWidth / 2 - img.width, 0, img.width * 1.25, img.height * 1.25);
      textSize(20);
      text("5V", screen.availWidth / 2 - img.width - 20, img.height / 2 + 30);
      text("50Ω", screen.availWidth / 2 - img.width + 100, img.height / 2 - 45);
      text("100Ω", screen.availWidth / 2 - img.width + 220, img.height / 2 + 50);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>