Fonts loaded by `loadFont()` cannot be used in CSS styles
p5.js version
1.9.0
What is your operating system?
Mac OS
Web browser and version
Chrome 120, Firefox 120, Safari 17.2
Actual Behavior
When I load a font with loadFont(), I can't use it to style HTML elements.
Expected Behavior
I should be able to set the font-family for HTML elements as shown in the last example.
Steps to reproduce
Here's a sketch that demonstrates the bug.
@raclim @lindapaiste @dhowe @paulaxisabel @SarveshLimaye @SkylerW99 @BamaCharanChhandogi @Obi-Engine10 @hannahvy @singshris @hiddenenigma I'm happy to help with this where I can!
let font;
// Load the font.
function preload() {
font = loadFont("assets/PressStart2P-Regular.ttf");
}
function setup() {
createCanvas(400, 400);
// Paint the background.
background(0);
// Use the font in the canvas.
fill(255);
textAlign(CENTER);
textFont(font, 22);
text("Are you in?", width / 2, height / 2);
// Create a <button> element.
let button = createButton("Yes");
button.size(100);
button.position(width / 2 - 50, height / 2 + 30);
// Style the button.
button.style("background-color", "black");
button.style("color", "white");
button.style("border-radius", "10px");
button.style("padding", "5px");
// Try to set the button's font-family.
// This works locally.
button.style("font-family", "PressStart2P-Regular");
// The code below makes the font-family work
// in the p5.js Web Editor.
// let f = new FontFace(
// "PressStart2P-Regular",
// "url(assets/PressStart2P-Regular.ttf)"
// );
// document.fonts.add(f);
}
I would guess that the problem is in the part of the code where we map relative url paths like "assets/PressStart2P-Regular.ttf" to the absolute URL of the file on our AWS server. That all happens in the EmbedFrame.jsx file.
I was hoping this was a trivial fix where all we need to do is add .ttf to the extensions array. It's not that, as we do have .ttf in the MEDIA_FILE_REGEX.
https://github.com/processing/p5.js-web-editor/blob/41529a3bb401e6516ef2d62d9fca9ba8aa21bf43/server/utils/fileUtils.js#L36
I'm looking through the EmbedFrame.jsx file but there's a lot going on there. We need to dig through this file and make sure that strings like loadFont("assets/PressStart2P-Regular.ttf") get replaced.
https://github.com/processing/p5.js-web-editor/blob/41529a3bb401e6516ef2d62d9fca9ba8aa21bf43/client/modules/Preview/EmbedFrame.jsx#L36-L270
Hi @nickmcintyre , I tried to replicate this issue and I was ablle to load the fonts mentioned. Attaching a video for the same. Attaching the font file and the code I used.
Please let me know if I am missing anything. Press_Start_2P.zip let font;
// Load the font. function preload() { font = loadFont("assets/PressStart2P-Regular.ttf"); }
function setup() { createCanvas(400, 400);
// Paint the background. background(0);
// Use the font in the canvas. fill(255); textAlign(CENTER); textFont(font, 22); text("Are you in?", width / 2, height / 2);
// Create a
// Style the button. button.style("background-color", "black"); button.style("color", "white"); button.style("border-radius", "10px"); button.style("padding", "5px");
// Try to set the button's font-family.
// This works locally. button.style("font-family", "PressStart2P-Regular");
// The code below makes the font-family work // in the p5.js Web Editor.
// let f = new FontFace( // "PressStart2P-Regular", // "url(assets/PressStart2P-Regular.ttf)" // ); // document.fonts.add(f); }
https://github.com/processing/p5.js-web-editor/assets/71766227/484ee51b-023f-48bb-bd95-2bd29f429b46
@PradeepJ4u thanks for looking into this. The issue is that the button's font-family isn't set.
I looked into this more and I can see the problem!
The core p5.js loadFont function should be adding the font to the HTML document, as seen in the code here:
https://github.com/processing/p5.js/blob/37d3324b457b177319ed65468201f2806a66eff5/src/typography/loading_displaying.js#L166-L177
But in the editor the <style> that it adds is this:
<style>
@font-face {
font-family: 6b2bb864-90a5-4af7-be93-e0e4b3578674;
src: url(https://assets.editor.p5js.org/5b50ea9119d9bab3715ea4ce/6b2bb864-90a5-4af7-be93-e0e4b3578674.ttf);
}
</style>
Where the src part is fine, but the font-family is a problem. It should be the name of the font, but instead it's the name of the file on the S3 bucket. The loadFont function assumes that the name of the font matches the name of the file. But the actual file that we are loading is https://assets.editor.p5js.org/5b50ea9119d9bab3715ea4ce/6b2bb864-90a5-4af7-be93-e0e4b3578674.ttf.
I'm not sure if we would consider making any changes to the core p5.js code to support this use case.
I think that we probably need to do something about it on our end, or with some sort of plugin around the p5 code. It cannot be handled with a simple find and replace because that <style> tag does not exist in the document until the JavaScript code is executed. It's a tricky one.
@nickmcintyre @lindapaiste @raclim i think the issue should open in P5.js core it is not related to web editor for the temparorary fix as the @lindapaiste explain that loadfont() just updating the font styling for Only canvas to update the Htlm tags we requires as default font enviroment for this which should be in the Browser so we need to update our code to this let font;
// Load the font.
let font ;
function preload() {
font = loadFont("assets/PressStart2P-Regular.ttf");
}
async function setup() {
createCanvas(400, 400);
background(0);
fill(255);
textFont(font,22);
textAlign(CENTER);
text("Are you in?", width / 2, height / 2);
const f = new FontFace("PressStart2P-Regular", "url(assets/PressStart2P-Regular.ttf)");
await f.load();
document.fonts.add(f);
const button = createButton("Yes");
button.size(100);
button.position(width / 2 - 50, height / 2 + 30);
button.style("background-color", "black");
button.style("color", "white");
button.style("border-radius", "10px");
button.style("padding", "5px");
button.style("font-family", "PressStart2P-Regular");
}
this is temoparay fix.
For a permanent fix, I suggest opening an issue on the main repository: 🔗 https://github.com/processing/p5.js
The core team might consider enhancing loadFont() to optionally register the font with document.fonts, or provide an API that makes it easier to use loaded fonts across both canvas and HTML elements.
Thanks!
Can someone test if this is still an issue in p5 v2.0 ?