Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CanvasRenderingContext2D - add missing properties #19859

Merged
merged 29 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
31e72bb
CanvasRenderingContext2D.letterSpacing - add doc
hamishwillee Aug 23, 2022
873b007
Add letterSpacing to canvasrenderingcontext2d
hamishwillee Aug 23, 2022
abc0104
Add cross link to wordspacing
hamishwillee Aug 23, 2022
9f41882
CanvasRenderingContext2D.wordSpacing - add doc
hamishwillee Aug 23, 2022
3baddde
CanvasRenderingContext2D.fontStretch - add doc
hamishwillee Aug 23, 2022
f01e1ca
fontStretch - minor layout update
hamishwillee Aug 23, 2022
c52b086
CanvasRenderingContext2D.fontVariantCaps - add doc
hamishwillee Aug 23, 2022
7f77636
fontVariantCaps - fix typo
hamishwillee Aug 23, 2022
02a1a7e
fontVariantCaps - typos
hamishwillee Aug 23, 2022
e0dbbf0
CanvasRenderingContext2D.textRednering - add doc
hamishwillee Aug 23, 2022
5025cf8
CanvasRenderingContext2D.fontKerning - add doc
hamishwillee Aug 23, 2022
1bfadb2
font kerning, fontstretch tidy
hamishwillee Aug 23, 2022
e4509dd
CanvasRenderingContext2D.roundedRect() - add doc
hamishwillee Aug 23, 2022
cd28549
Fix up parent doc to link to the sub docs
hamishwillee Aug 23, 2022
12fafea
CanvasRenderingContext2D.fontKerning - not experimental now
hamishwillee Aug 26, 2022
6b1cc30
Fix up new additions experimental status
hamishwillee Aug 26, 2022
37595a5
Apply suggestions from code review
hamishwillee Aug 28, 2022
ebaaa4b
Canvas - losing/regaining context
hamishwillee Aug 29, 2022
6139bf6
Update files/en-us/web/api/htmlcanvaselement/contextlost_event/index.md
hamishwillee Aug 29, 2022
0036577
Add reset()
hamishwillee Aug 29, 2022
f7a0e42
Apply suggestions from code review
hamishwillee Aug 30, 2022
909fb7a
Switch generic context events first
hamishwillee Aug 30, 2022
b702497
isContextLost() - add example
hamishwillee Aug 30, 2022
adc0928
CanvasRenderingContext2D.reset() - examples plus more words
hamishwillee Aug 30, 2022
cf97f92
contextlost/restored updates
hamishwillee Aug 30, 2022
293655d
Fix link to preventDefault()
bsmth Sep 1, 2022
9b31909
Merge branch 'main' into canvasrenderingcontext2d_updates
bsmth Sep 1, 2022
d1af047
Apply fix from reviewer feedback
bsmth Sep 1, 2022
a3ba79d
Merge branch 'main' into canvasrenderingcontext2d_updates
bsmth Sep 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: CanvasRenderingContext2D.fontKerning
slug: Web/API/CanvasRenderingContext2D/fontKerning
page-type: web-api-instance-property
tags:
- API
- Canvas
- CanvasRenderingContext2D
- Property
- Reference
browser-compat: api.CanvasRenderingContext2D.fontKerning
---
{{APIRef}}

The **`CanvasRenderingContext2D.fontKerning`** property of the [Canvas API](/en-US/docs/Web/API/Canvas_API) specifies how font kerning information is used.

Kerning adjusts how adjacent letters are spaced in a proportional font, allowing them to edge into each other's visual area if there is space available.
For example, in well-kerned fonts, the characters `AV`, `Ta` and `We` nest together and make character spacing more uniform and pleasant to read than the equivalent text without kerning.

The property corresponds to the [`font-kerning`](/en-US/docs/Web/CSS/font-kerning) CSS property.

## Value

The property can be used to get or set the value.

Allowed values are:

- `auto`
- : The browser determines whether font kerning should be used or not.
For example, some browsers will disable kerning on small fonts, since applying it could harm the readability of text.
- `normal`
- : Font kerning information stored in the font must be applied.
- `none`
- : Font kerning information stored in the font is disabled.

## Examples

In this example we display the text "AVA Ta We" using each of the supported values of the `textRendering` property.

#### HTML

```html
<canvas id="canvas" width="700" height="140"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '30px serif';

// Default (auto)
ctx.fillText(`AVA Ta We (default: ${ctx.fontKerning})`, 5, 30);

// Font kerning: normal
ctx.fontKerning = 'normal';
ctx.fillText(`AVA Ta We (${ctx.fontKerning})`, 5, 70);

// Font kerning: none
ctx.fontKerning = 'none';
ctx.fillText(`AVA Ta We (${ctx.fontKerning})`, 5, 110);
```

#### Result

Note that the the last string has font kerning disabled, so adjacent characters are evenly spread.

{{ EmbedLiveSample('Examples', 700, 150) }}

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
title: CanvasRenderingContext2D.fontStretch
slug: Web/API/CanvasRenderingContext2D/fontStretch
page-type: web-api-instance-property
tags:
- API
- Canvas
- CanvasRenderingContext2D
- Property
- Reference
- Experimental
browser-compat: api.CanvasRenderingContext2D.fontStretch
---
{{APIRef}}{{SeeCompatTable}}

The **`CanvasRenderingContext2D.fontStretch`** property of the [Canvas API](/en-US/docs/Web/API/Canvas_API) specifies how the font may be expanded or condensed when drawing text.

The property corresponds to the [`font-stretch`](/en-US/docs/Web/CSS/font-stretch) CSS property when used with keywords (percentage values are not supported).

## Value

The font stretch value as a string.
This is one of: `ultra-condensed`, `extra-condensed`, `condensed`, `semi-condensed`, `normal` (default), `semi-expanded`, `expanded`, `extra-expanded`, `ultra-expanded`.

The property can be used to get or set the font stretch value.

## Examples

In this example we display the text "Hello World" using each of the supported values of the `fontStretch` property.
Copy link
Member

@Elchi3 Elchi3 Aug 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example doesn't show different text renderings to me (in Chrome).

Like in CSS, should a new FontFace be added to the document first?

let ff = new FontFace('myfont', url);
ff.stretch = "condensed";
document.fonts.add(ff);

document.fonts.ready.then(() => {
ctx.font = '25px myfont';
ctx.fontStretch = "condensed";
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Elchi3
Yes, clearly the default font is not a variable font, so this can't work. So yes we need to add a font. Unfortunately I am completely stumped as to how to do this in a live example (and I think it is worth doing in a live example).

I tried having the font in the same folder as the docs but I get 404 errors (it isn't served). I tried using links from the interactive examples, but they fail with CORS errors.

The "best" way to do this would be to use a CDN served font with appropriate allow headers. I tried this with fonts.gstatic.com but I can't find a woff file that contains variable fonts. For example, this doesn't vary:

let font_file = new FontFace('LeagueMonoVariable', 'url(https://fonts.gstatic.com/s/leaguespartan/v6/kJEqBuEW6A0lliaV_m88ja5TwvZwLZk.woff2');
font_file.load().then( () => {

  document.fonts.add(font_file);
  // font loaded successfully!
  const ctx = canvas.getContext('2d');
  ctx.font = '36px "LeagueMonoVariable"'

// Default (normal)
ctx.fillText(`Hello world (default: ${ctx.fontStretch})`, 5, 20);
...

What I'd like to do, because I think it would be generally useful, is use the google font API with the font loading API. However passing in the URLs suggested for CSS just gives you link parsing errors.

Any ideas?

PS Our CSS Font loading API docs are "very thin". Not enough examples, and some may be incorrect - for example https://developer.mozilla.org/en-US/docs/Web/API/FontFace/load looks to me to not be adding the font to the document, and I think that is a precondition.
In general it isn't clear what you need to do - I THINK you load() the font, wait for it to complete, then add it to the document and wait for it to be ready, but none of that is demonstrated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Elchi3 So I think we're good except for fontstretch, on which I am stumped for the above reasons.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsmth See these messages above^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, tracking this improvement in #20208

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: using fancy fonts in live samples, please see mdn/yari#5727.

The stretch value is also displayed for each case by reading the property.

#### HTML

```html
<canvas id="canvas" width="700" height="310"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '20px serif';

// Default (normal)
ctx.fillText(`Hello world (default: ${ctx.fontStretch})`, 5, 20);

// Font stretch: ultra-condensed
ctx.fontStretch = 'ultra-condensed';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 50);

// Font stretch: extra-condensed
ctx.fontStretch = 'extra-condensed';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 80);

// Font stretch: condensed
ctx.fontStretch = 'condensed';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 110);

// Font stretch: semi-condensed
ctx.fontStretch = 'semi-condensed';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 140);

// Font stretch: extra-condensed
ctx.fontStretch = 'extra-condensed';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 170);

// Font stretch: semi-expanded
ctx.fontStretch = 'semi-expanded';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 200);

// Font stretch: expanded
ctx.fontStretch = 'expanded';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 230);

// Font stretch: extra-expanded
ctx.fontStretch = 'extra-expanded';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 260);

// Font stretch: ultra-expanded
ctx.fontStretch = 'ultra-expanded';
ctx.fillText(`Hello world (${ctx.fontStretch})`, 5, 290);
```

#### Result

{{ EmbedLiveSample('Examples', 700, 300) }}

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: CanvasRenderingContext2D.fontVariantCaps
slug: Web/API/CanvasRenderingContext2D/fontVariantCaps
page-type: web-api-instance-property
tags:
- API
- Canvas
- CanvasRenderingContext2D
- Property
- Reference
- Experimental
browser-compat: api.CanvasRenderingContext2D.fontVariantCaps
---
{{APIRef}}{{SeeCompatTable}}

The **`CanvasRenderingContext2D.fontVariantCaps`** property of the [Canvas API](/en-US/docs/Web/API/Canvas_API) specifies an alternative capitalization of the rendered text.

This corresponds to the CSS [`font-variant-caps`](/en-US/docs/Web/CSS/font-variant-caps) property.

## Value

The font alternative capitalization value, which is one of:

- `normal` (default)
- : Deactivates of the use of alternate glyphs.
- `small-caps`
- : Enables display of small capitals (OpenType feature: `smcp`).
Small-caps glyphs typically use the form of uppercase letters but are reduced to the size of lowercase letters.
- `all-small-caps`
- : Enables display of small capitals for both upper and lowercase letters (OpenType features: `c2sc`, `smcp`).
- `petite-caps`
- : Enables display of petite capitals (OpenType feature: `pcap`).
- `all-petite-caps`
- : Enables display of petite capitals for both upper and lowercase letters (OpenType features: `c2pc`, `pcap`).
- `unicase`
- : Enables display of mixture of small capitals for uppercase letters with normal lowercase letters (OpenType feature: `unic`).
- `titling-caps`
- : Enables display of titling capitals (OpenType feature: `titl`).
Uppercase letter glyphs are often designed for use with lowercase letters.
When used in all uppercase titling sequences they can appear too strong.
Titling capitals are designed specifically for this situation.

The property can be used to get or set the font capitalization value.

Note that there are accessibility concerns with some of these, which are outlined in the corresponding [`font-variant-caps`](/en-US/docs/Web/CSS/font-variant-caps#accessibility_concerns) topic.

## Examples

In this example we display the text "Hello World" using each of the supported values of the `fontVariantCaps` property.
The value is also displayed for each case by reading the property.

#### HTML

```html
<canvas id="canvas" width="700" height="220"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '20px serif';

// Default (normal)
ctx.fillText(`Hello world (default: ${ctx.fontVariantCaps})`, 5, 20);

// Capitalization: small-caps
ctx.fontVariantCaps = 'small-caps';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 50);

// Capitalization: all-small-caps
ctx.fontVariantCaps = 'all-small-caps';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 80);

// Capitalization: petite-caps
ctx.fontVariantCaps = 'petite-caps';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 110);

// Capitalization: all-petite-caps
ctx.fontVariantCaps = 'all-petite-caps';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 140);

// Capitalization: unicase
ctx.fontVariantCaps = 'unicase';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 170);

// Capitalization: titling-caps
ctx.fontVariantCaps = 'titling-caps';
ctx.fillText(`Hello world (${ctx.fontVariantCaps})`, 5, 200);
```

#### Result

{{ EmbedLiveSample('Examples', 700, 230) }}

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}
20 changes: 19 additions & 1 deletion files/en-us/web/api/canvasrenderingcontext2d/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,25 @@ The following methods and properties control how lines are drawn.
The following properties control how text is laid out.

- {{domxref("CanvasRenderingContext2D.font")}}
- : Font setting. Default value `10px sans-serif`.
- : Font setting. Default value `"10px sans-serif"`.
- {{domxref("CanvasRenderingContext2D.textAlign")}}
- : Text alignment setting. Possible values: `start` (default), `end`, `left`, `right`, `center`.
- {{domxref("CanvasRenderingContext2D.textBaseline")}}
- : Baseline alignment setting. Possible values: `top`, `hanging`, `middle`, `alphabetic` (default), `ideographic`, `bottom`.
- {{domxref("CanvasRenderingContext2D.direction")}}
- : Directionality. Possible values: `ltr`, `rtl`, `inherit` (default).
- {{domxref("CanvasRenderingContext2D.letterSpacing")}}
- : Letter spacing. Default: `0px`.
- {{domxref("CanvasRenderingContext2D.fontKerning")}}
- : Font kerning. Possible values: `auto` (default), `normal`, `none`.
- {{domxref("CanvasRenderingContext2D.fontStretch")}} {{experimental_inline}}
- : Font stretch. Possible values: `ultra-condensed`, `extra-condensed`, `condensed`, `semi-condensed`, `normal` (default), `semi-expanded`, `expanded`, `extra-expanded`, `ultra-expanded`.
- {{domxref("CanvasRenderingContext2D.fontVariantCaps")}} {{experimental_inline}}
- : Font variant caps. Possible values: `normal` (default), `small-caps`, `all-small-caps`, `petite-caps`, `all-petite-caps`, `unicase`, `titling-caps`.
- {{domxref("CanvasRenderingContext2D.textRendering")}} {{experimental_inline}}
- : Text rendering. Possible values: `auto` (default), `optimizeSpeed`, `optimizeLegibility`, `geometricPrecision`.
- {{domxref("CanvasRenderingContext2D.wordSpacing")}} {{experimental_inline}}
- : Word spacing. Default value: `0px`

### Fill and stroke styles

Expand Down Expand Up @@ -168,6 +180,8 @@ The following methods can be used to manipulate paths of objects.
- : Adds an elliptical arc to the current path.
- {{domxref("CanvasRenderingContext2D.rect()")}}
- : Creates a path for a rectangle at position (x, y) with a size that is determined by _width_ and _height_.
- {{domxref("CanvasRenderingContext2D.roundRect()")}} {{experimental_inline}}
- : Creates a path for a rounded rectangle with a specified position, width, height, and corner radii.

### Drawing paths

Expand Down Expand Up @@ -247,6 +261,10 @@ The `CanvasRenderingContext2D` rendering context contains a variety of drawing s
- : A read-only back-reference to the {{domxref("HTMLCanvasElement")}}. Might be [`null`](/en-US/docs/Web/JavaScript/Reference/Operators/null) if it is not associated with a {{HTMLElement("canvas")}} element.
- {{domxref("CanvasRenderingContext2D.getContextAttributes()")}}
- : Returns an object containing the actual context attributes. Context attributes can be requested with {{domxref("HTMLCanvasElement.getContext()")}}.
- {{domxref("CanvasRenderingContext2D.reset()")}}
- : Resets the rendering context, including the backing buffer, the drawing state stack, path, and styles.
- {{domxref("CanvasRenderingContext2D.isContextLost()")}}
- : Returns `true` if the rendering context was lost.

### Filters

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: CanvasRenderingContext2D.isContextLost()
slug: Web/API/CanvasRenderingContext2D/isContextLost
page-type: web-api-instance-method
tags:
- API
- Canvas
- CanvasRenderingContext2D
- Method
- Reference
browser-compat: api.CanvasRenderingContext2D.isContextLost
---
{{APIRef}}

The **`CanvasRenderingContext2D.isContextLost()`** method of the Canvas 2D API returns `true` if the rendering context is lost (and has not yet been reset).
This might occur due to driver crashes, running out of memory, and so on.

If the user agent detects that the canvas backing storage is lost it will fire the [`contextlost` event](/en-US/docs/Web/API/HTMLCanvasElement/contextlost_event) at the associated [`HTMLCanvasElement`](/en-US/docs/Web/API/HTMLCanvasElement).
If this event is not cancelled it will attempt to reset the backing storage to the default state (this is equivalent to calling {{domxref("CanvasRenderingContext2D.reset()")}}).
On success it will fire the [`contextrestored` event](/en-US/docs/Web/API/HTMLCanvasElement/contextrestored_event), indicating that the context is ready to reinitialize and redraw.

## Syntax

```js
isContextLost()
```

### Parameters

None.

hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
### Return value

`true` if the rendering context was lost; `false` otherwise.

### Examples

```js
const ctx = canvas.getContext('2d');

if (ctx.isContextLost()) {
console.log("Context is lost")
}
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The interface defining this method: {{domxref("CanvasRenderingContext2D")}}
- [`HTMLCanvasElement: contextlost` event](/en-US/docs/Web/API/HTMLCanvasElement/contextlost_event)
- [`HTMLCanvasElement: contextrestored` event](/en-US/docs/Web/API/HTMLCanvasElement/contextrestored_event)
Loading