Search code examples
javascriptfontsprocessingp5.jsopentype

Is there a way to put a box behind text in p5.js with the default font?


I want to make a box that tightly fits around my text in a p5.js canvas -- this can be done, but I can only figure out how to do it by loading a new font into the program.

Can creating a tight box behind text be done with the default font, thus avoiding having to load a new font?

Further explanation
To get a tight box around some text on a canvas, one uses the textBounds() method to obtain the, well, bounds of the text. You'll obtain the position of the corners of a box that fits tightly around your text. Now, in the p5.js example found at http://p5js.org/reference/#/p5.Font/textBounds that I have put in a Code Snippet below, it appears that you must load a font with loadFont() before using textBounds() to get the bounds of the box that contains the text. My question is, how is this done without loading a font and just using the default font?

For example, I had to use an externally hosted google font for the "Code Snippet" below. I'd rather just put a box behind the default font, to avoid having to load some font.

let font;
let textString = 'Lorem ipsum dolor sit amet.';

function preload() {
  font = loadFont('https://raw.githubusercontent.com/google/fonts/master/ofl/alikeangular/AlikeAngular-Regular.ttf');
}

function setup() {
  background(210);

  let bbox = font.textBounds(textString, 10, 30, 12);
  fill(255);
  stroke(0);
  rect(bbox.x, bbox.y, bbox.w, bbox.h);
  fill(0);
  noStroke();

  textFont(font);
  textSize(12);
  text(textString, 10, 30);
}
<script src="https://cdn.jsdelivr.net/npm/p5@0.9.0/lib/p5.min.js"></script>


Solution

  • It is by design that p5.Font.textBounds() will have to be called after defining a font - you will see the same thing with many other methods of the p5.Font class, e.g. textToPoints(). There is a reason for this -

    1. There is no way to retrieve the default font from a given browser using p5.js.
    2. It is anyway good practice to set the font you are using for your application, since the "default" would be different for different browsers. Same would apply if you're writing a Processing program on MacOS and then run it on Windows - the default font will be automatically mapped onto the most suitable "default" font available at a given platform.

    TL;DR - no, there is no way of running textBounds() without defining a font.