本文へスキップ

図形とテキスト ​

spryte はスプライトに加えて、塗りつぶした矩形、円、線、そして CSS フォントやビットマップフォントのテキストを描きます。どれもほかの描画と一緒に、呼び出し順でバッチ処理されます。

ts
draw.rect(10, 10, 100, 8, "#333");                // HP バーの背景
draw.rect(10, 10, 100 * hp, 8, "#cffb2d");        // HP バーの中身
draw.circle(160, 90, 24, "#ff5c8a");              // 塗りつぶし、アンチエイリアスあり
draw.line(0, 0, 320, 180, 2, "#ffffff80");        // 幅2単位、半透明
draw.text("score 120", 8, 24, { color: "#fbbf24" });

図形 ​

メソッド
rect(x, y, w, h, color)左上を起点とした塗りつぶしの矩形。
circle(x, y, r, color)中心を指定した、アンチエイリアスありの塗りつぶしの円。
line(x1, y1, x2, y2, width, color)回転した矩形として描く線。長さ0の線は何も描きません。

3つとも現在のトランスフォームとグローバルな draw.alpha に従います(トランスフォームを参照)。図形は塗りつぶしのみです。輪郭線が欲しいときは、細い矩形か線を4本描いてください。

色 ​

spryte が色を受け取る場所(rect、circle、line、text の color、スプライトの tint、begin() のクリア色)では、次のどれでも渡せます。

  • CSS の16進文字列:"#rgb"、"#rgba"、"#rrggbb"、"#rrggbbaa"。
  • 数値 0xRRGGBBAA。たとえば 0xcffb2dff。
  • そのほかの CSS カラー。たとえば "rebeccapurple" や "rgb(255 0 0 / 50%)"。これらは一度 canvas を通して解決され、キャッシュされます。

16進文字列と数値が最も軽量です。spryte は、パックされた 0xRRGGBBAA の数値を返す toRGBA(color) と、その逆の rgbaToCss(rgba) もエクスポートしています。

CSS フォントのテキスト ​

ts
draw.text("Game over", 160, 90, {
  font: "bold 24px system-ui",
  color: "#ffffff",
  align: "center",
  baseline: "middle",
});
オプションデフォルト
fontdraw.fontCSS のフォント文字列、または BitmapFont。
color"#ffffff"テキストの色。
align"left"x に対して "left"、"center"、"right"。
baseline"top"y に対して "top"、"middle"、"bottom"。
alpha1不透明度。draw.alpha と掛け合わされます。

CSS のテキストは、begin() に渡した scale で一度だけラスタライズされ、テクスチャとしてキャッシュされます(256エントリの LRU キャッシュ)。そのため高 DPI 画面でもくっきり表示されます。ミリ秒付きのタイマーのように毎フレーム変わるテキストはキャッシュを新しいエントリで埋めますが、古いものは自動で追い出されます。

Web フォントは、描く前に読み込みを済ませておいてください。たとえば await document.fonts.load("24px Pixelify") を使います。そうしないと、最初のラスタライズが代替フォントで行われ、そのままキャッシュされてしまいます。

デフォルトのフォント ​

text() や measure() にフォントが渡されなかったときは draw.font が使われます。デフォルトは "16px sans-serif" で、CSS 文字列、BitmapFont、またはそれらを返す関数を指定できます。関数は最初に使われたときに呼ばれるので、canvas から作るフォントは、テキストを描くまでコストがかかりません。

ts
draw.font = "14px monospace";
draw.text("hp 3", 4, 4); // 14px monospace を使う

ビットマップフォント ​

BitmapFont は、グリフを並べたスプライトシートからテキストを描きます。グリフは整数ピクセル上に置かれるので、どの整数倍率でもくっきりしたままです。ドット絵にはこちらが適しています。

ts
import { BitmapFont, type Frame } from "spryte";

const sheet = await load("/font.png"); // 6×9 グリッドのグリフ、1行に16個
const frames: Frame[] = [];
for (let i = 0; i < 95; i++) frames.push({ image: sheet, x: (i % 16) * 6, y: Math.floor(i / 16) * 9, w: 6, h: 9 });

const font = new BitmapFont({ frames, chars: BitmapFont.ASCII });
draw.text("coins 3", 4, 4, { font, color: "#fbbf24" });

BitmapFont.ASCII は、スペースから ~ までの表示可能な ASCII 文字で、多くのフォントシートと同じ並びです。コンストラクタは次のオプションを受け取ります。

オプションデフォルト
frames必須グリフごとに1フレーム。chars の順に並べます。
chars必須フレームに含まれる文字。
widths計測グリフごとの送り幅(ピクセル)。デフォルトでは各グリフの最も右の不透明な列から計測するので、グリッドがプロポーショナルフォントになります。数値を渡すと等幅フォントになります。
spacing1グリフ間のピクセル数。
spaceWidthセルの高さの3分の1(四捨五入)スペース、および計測結果が空になったグリフの送り幅。
lineHeightセルの高さ + 1ある行の上端から次の行の上端までのピクセル数。
fallbackあれば "?"フォントにない文字の代わりに描かれます。

ビットマップテキストは "\n" による複数行に対応し、同じ color、align、baseline、alpha オプションが使えます。

計測 ​

draw.measure(text, font?) は、text() が描く範囲を論理単位の { w, h } で返します。当て推量なしでレイアウトや中央揃えができます。

ts
const label = "Start";
const { w, h } = draw.measure(label, "20px system-ui");
draw.rect(160 - w / 2 - 6, 120 - 4, w + 12, h + 8, "#222");
draw.text(label, 160, 120, { font: "20px system-ui", align: "center" });

計測は text() と同じキャッシュを使うので、計測してから描いてもラスタライズは1回です。

次へ:トランスフォームとクリッピング