Skip to content

Instantly share code, notes, and snippets.

@AsPulse
Last active June 13, 2023 15:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AsPulse/839a833e5136038a58059a65313784ae to your computer and use it in GitHub Desktop.
Save AsPulse/839a833e5136038a58059a65313784ae to your computer and use it in GitHub Desktop.
canvasRenderingContext2D.fillTextで描画される文字のフォントを強制的に変更します。
const customFontFace = new FontFace(
"CUSTOM_FONT_FACE",
"url(yout url here)",
);
document.fonts.add(customFontFace);
await customFontFace.load();
function canvasFontReplace(targetFont) {
if ('canvasFontReplacerFlag' in CanvasRenderingContext2D.prototype) {
console.warn('canvas.fillTextは既に置き換えられているので、中断しました。二度以上実行していないことを確認してください。');
return;
}
const fillTextBackup = CanvasRenderingContext2D.prototype.fillText;
//fillTextの動作を上書きする (thisに影響を及ぼすためアロー関数式で代替してはいけません)
CanvasRenderingContext2D.prototype.fillText = function(...v) {
const fontPropertyBackup = this.font;
const fontData = this.font.split(' ');
//fontプロパティで、font-familyの指定が始まっている場所を探します。
//文字列指定をしていたり、コンマで複数指定しているところがスタートです。
const startFontFamily = fontData.findIndex(v => v.startsWith(`'`) || v.startsWith(`"`) || v.endsWith(','));
//見つけた部分をtargetFontで置き換えます
fontData.splice(startFontFamily, startFontFamily === -1 ? 1 : fontData.length, targetFont);
this.font = fontData.join(' ');
//fillTextを実行 this.fillText(...) とすると再帰に陥るため、バックアップしていたものをapplyします
fillTextBackup.apply(this, v);
//お行儀よく、フォントプロパティを戻します。
//もし既存のプログラムがthis.fontを取得していた場合の副作用を防ぎます。
this.font = fontPropertyBackup;
};
//この置き換えを二重で実行すると再帰に陥るため、フラグを立てます。
CanvasRenderingContext2D.prototype.canvasFontReplacerFlag = true;
}
canvasFontReplace('CUSTOM_FONT_FACE');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment