Reputation: 1842
I am new to javascript and need to condense text drawn into a canvas using java script. w3schools suggests this can be done.
JavaScript syntax: object.style.fontStretch="expanded"
I noticed in css syntax however that neither font-stretch: condensed
nor font-stretch: expanded
appear to work and a comment in the example in w3schools also states no browsers support the font-stretch property. I am also aware this property will not work on just any font.
var can = document.getElementById("textCanvas");
var ctx = can.getContext("2d");
ctx.font = "120px Arial Bold Italic";
ctx.font.fontStretch="ultra-condensed"; //condensed”; // expanded”;
ctx.fillStyle = "red";
ctx.textAlign = "center";
ctx.fillText("NAME", 100, 100);
<canvas id="textCanvas" width="200" height="200" style="border: 1px solid black"></canvas>
Using font-stretch
made no difference. I also tried font-kerning
and font-size-adjust
. How do I condense the font ?
Upvotes: 1
Views: 1436
Reputation: 137171
ctx.font
is a string. Setting fontStretch
or anything else on it won't change it.
Now, the correct syntax is the same as CSS font
property:
ctx.font = "[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-stretch-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar"`
So for setting only the font-stretch, the minimal is
ctx.font = "<font-stretch-css3> <'font-size'> <'font-family'>"
For example ctx.font = "ultra-condensed 18px LeagueMonoVariable";
would do.
However you'll face the same limitations as with CSS: browser support is limited, only a few fonts can be used, and in Chrome you need to define the font-stretch in the font-face declaration.
// This example seems to work only on Chrome, as does the MDN's example
const font = '18px "LeagueMonoVariable"';
document.fonts.load(font)
.then(() => {
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d');
['ultra-condensed', 'condensed', 'expanded', 'ultra-expanded'].forEach((stretch, i) => {
ctx.font = stretch + ' ' + font;
ctx.fillText('Hello ' + stretch + ' World', 10, i * 30 + 30);
});
});
/* borrowed from https://developer.mozilla.org/en-US/docs/Web/CSS/font-stretch */
/*
This example uses the League Mono Variable font, developed by
Tyler Finck (https://www.tylerfinck.com/) and used here under
the terms of the SIL Open Font License, Version 1.1:
http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web
*/
@font-face {
src: url('https://tylerfinck.com/leaguemonovariable/LeagueMonoVariable.ttf');
font-family: 'LeagueMonoVariable';
font-style: normal;
font-stretch: 1% 500%;
}
<canvas id="canvas" width="500"></canvas>
Chrome output for the ones using an other browser.
Also note that apparently the percentage notation (n% font-size font-family
) is not supported in Chrome from context's font
.
Given all these limitations, it might be worth considering an alternative solution, and the best alternative is probably to have the variant font as a separate font-face and use it as simply as possible.
Promise.all([
document.fonts.load("18px Roboto"),
document.fonts.load("18px 'Roboto Condensed'")
])
.then(() => {
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d');
ctx.font = "18px Roboto";
ctx.fillText('Hello World', 10, 30);
ctx.font = "18px 'Roboto Condensed'";
ctx.fillText('Hello condensed World', 10, 60);
});
<link href="https://fonts.googleapis.com/css?family=Roboto|Roboto+Condensed&display=swap" rel="stylesheet">
<canvas id="canvas" width="500"></canvas>
Upvotes: 3