0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

p5.jsでloadFontでロードしたフォントにtextStyleでイタリックを適用する小ネタ

Last updated at Posted at 2025-03-30

はじめに

 textFontでフォントを指定した場合でも、textStyleでITALICを指定すると斜体にできる。

イタリックを指定しない場合
nonItalic.png

指定する場合
italic.png

しかしloadFontでロードしたフォントには適用されない。

italic2.png

これはtextStyleのレファレンスにも書いてある。This function doesn't affect fonts loaded with loadFont().

しかし別のやり方でフォントをロードすると、適用されるようになるので、それを紹介する。

通常のやり方

 hui italic font failure

let hui;

function preload(){
  hui = loadFont("https://inaridarkfox4231.github.io/assets/HuiFont29.ttf");
}

function setup() {
  createCanvas(400, 400);
  draw = () => {
    background(255);
    textFont(hui);
  	textAlign(CENTER, CENTER);
    textSize(36);

  	drawingContext.letterSpacing = "-5px";
    textStyle(ITALIC);
    text("italic font",200,50);
  	textStyle(NORMAL);
  	text("non italic font", 200, 150);

  	drawingContext.letterSpacing = "0px";
    textStyle(ITALIC);
    text("italic font",200,250);
  	textStyle(NORMAL);
  	text("non italic font", 200, 350);
  }
}

nonitalis.png

フリーフォントであるふい字フォントのダウンロードはこちらで実行できる(提供感謝!):

ちなみにこのフォントは洞窟物語のリメイクでも使われている。自分がこのフォントを知ったのは「ジェム」というフリーゲームです。気になった人は「#ジェムフリゲ」で検索してみてください。

当時はフリーだったんですが現在は支援者様限定の特典となっているようです。ユニークなアクションRPGで、ファンシーなキャラクターとダークな世界観が魅力の楽しい作品なのでぜひ!

脱線しすぎた

loadFontで普通にふい字をロードして、textFontで適用する。描画をITALICとNORMALの2種類で実行しているが、いずれも見た目は一緒である。また、letterSpacingも適用できない。ふい字のアルファベットは文字間隔が広いので、これを負の数に設定すると見栄えが良くなるが、それもできない仕様である。
 そこで、次の方法。

FontFace

 FontFaceというのを使う。次のコードでは、ちゃんとtextStyle(ITALIC)が機能する。もちろんBOLDなども機能する。
 hui italic font

function setup() {
  createCanvas(400, 400);
  loadingFont("hui", "https://inaridarkfox4231.github.io/assets/HuiFont29.ttf").then((res) => {
    document.fonts.add(res);
    draw = () => {
      background(255);
      textFont("hui");
      textAlign(CENTER, CENTER);
      textSize(36);

      drawingContext.letterSpacing = "-5px";
      textStyle(ITALIC);
      text("italic font",200,50);
      textStyle(NORMAL);
      text("non italic font", 200, 150);

      drawingContext.letterSpacing = "0px";
      textStyle(ITALIC);
      text("italic font",200,250);
      textStyle(NORMAL);
      text("non italic font", 200, 350);
    }
  });
}

async function loadingFont(name, url){
  const fontFile = new FontFace(name, `url(${url})`);
  await fontFile.load();
  return fontFile;
}

italic!.png

このように、イタリックになる。文字間隔調整も適用される。

 使っているのは非同期関数のloadingFontである。ここでFontFaceというクラスを使ってファイルを用意している。

loadで読み込みが実行される。その結果を受け取り、draw関数を定義している。document.fontsにaddしていて、これがポイントになる。

document.fonts.add(res);

こうしてフォントを用意すると、textStyleを使ってITALICやBOLDを指定できるようになる。非同期であるので、普通にやると最初の数フレームは適用されなかったりする。それが気になる場合はこのようにPromise構文でdrawを用意する必要があるが、気にならないなら普通に書けばいいと思う。

どういうことかというと、非同期で書かないとこうなる。

function setup() {
  createCanvas(400, 400);
  loadingFont("hui", "https://inaridarkfox4231.github.io/assets/HuiFont29.ttf");
   // draw = () => {
      background(255);
      textFont("hui");
      textAlign(CENTER, CENTER);
      textSize(36);

      drawingContext.letterSpacing = "-5px";
      textStyle(ITALIC);
      text("italic font",200,50);
      textStyle(NORMAL);
      text("non italic font", 200, 150);

      drawingContext.letterSpacing = "0px";
      textStyle(ITALIC);
      text("italic font",200,250);
      textStyle(NORMAL);
      text("non italic font", 200, 350);
  //  }
}

function loadingFont(name, url){
  const fontFile = new FontFace(name, `url(${url})`);
  fontFile.load();
  document.fonts.add(fontFile);
}

failure (1).png

このように最初の数フレームは適用されないので、失敗する。ただtextFontの内容は文字列であるから、ITALICやBOLDは適用されている。ロードしたフォントが無視される、という意味。なおdraw関数を書き換えると...

function setup() {
  createCanvas(400, 400);
  loadingFont("hui", "https://inaridarkfox4231.github.io/assets/HuiFont29.ttf");
}
function draw(){
  background(255);
  textFont("hui");
  textAlign(CENTER, CENTER);
  textSize(36);

  drawingContext.letterSpacing = "-5px";
  textStyle(ITALIC);
  text("italic font",200,50);
  textStyle(NORMAL);
  text("non italic font", 200, 150);

  drawingContext.letterSpacing = "0px";
  textStyle(ITALIC);
  text("italic font",200,250);
  textStyle(NORMAL);
  text("non italic font", 200, 350);
}

function loadingFont(name, url){
  const fontFile = new FontFace(name, `url(${url})`);
  fontFile.load();
  document.fonts.add(fontFile);
}

この場合でも適用されないのはせいぜい最初の1,2フレームである。すぐに適用され、こうなる:

feugufge.png

適用されないフレームを作りたくないかどうかはスケッチの方針による。

おわりに

 loadFontで作ったフォントにtextStyle(ITALIC)が使えないのはずっと気になっていたんですが、解消できて良かったです。なおタグで導入する場合もtextStyleが使えるようです。ただjsで完結してる方が分かりやすいのでこっちを採用しました。
 ここまでお読みいただいてありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?