CanvasRenderingContext2D: lang 属性

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

实验性: 这是一项实验性技术
在生产中使用此技术之前,请仔细检查浏览器兼容性表格

Canvas 2D API 的 CanvasRenderingContext2D.lang 属性用于获取或设置 Canvas 绘图上下文的语言。

lang 属性可以接受以下字符串值之一:

  • 表示 Canvas 上下文语言的 BCP 47 语言标签
  • 字符串 inherit,在这种情况下,语言将从原始 <canvas> 元素的 lang 属性或最近一个具有显式设置的 lang 的祖先元素继承。
  • 一个空字符串 (""),可以设置为指定 Canvas 上下文没有语言。

默认值为 inherit

描述

有时,你需要为 Canvas 渲染上下文设置一种语言,以便它知道如何渲染依赖于语言的功能:例如,某些字体在不同语言中会以不同的方式渲染某些字符。屏幕上的 Canvas 上下文 (CanvasRenderingContext2D) 始终与特定的 <canvas> 元素相关联,因此无论何时使用它渲染内容,它都可以从 <canvas> 元素的 lang 属性值派生出语言。

然而,屏幕外的 Canvas 上下文 (OffscreenCanvasRenderingContext2D) 在与其关联的 <canvas> 元素之前渲染其内容,因此它无法从 <canvas> 元素的 lang 属性派生出渲染语言。lang 属性解决了这个问题,允许你直接在 Canvas 渲染上下文上设置语言,无论你使用的是屏幕内还是屏幕外 Canvas。

inherit

当使用 inherit 值时,Canvas 上下文的语言将从最近的可用 HTML 源的 lang 属性继承。

  • 对于屏幕内上下文,或者从屏幕内上下文传输而来的屏幕外上下文,这将是原始的 <canvas> 元素,前提是它具有有效的 lang 属性设置。
  • 如果与 <canvas> 元素关联的 lang 属性不可用,这可能是屏幕内或屏幕外上下文的情况,那么它将是最近一个具有显式 lang 设置的祖先元素,这通常是文档根元素。

由于技术限制,inherit 值对于屏幕内和屏幕外 Canvas 的行为不同。

  • 对于屏幕内 Canvas,当关联的 CanvasRenderingContext2D 对象首次创建时,lang 值会被继承;随后,如果 lang 属性值被更新,继承的 lang 值将动态改变。
  • 对于屏幕外 Canvas,当关联的 OffscreenCanvasRenderingContext2D 对象首次创建时,lang 值会被继承,然后在此 OffscreenCanvas 的生命周期内固定。如果 lang 属性值被更新,它不会改变。因此,屏幕外 Canvas 的语言只能通过显式设置 lang 值来更改。

示例

基本用法

js
const canvasElem = document.querySelector("canvas");
const ctx = canvasElem.getContext("2d");

// Get context language; returns "inherit" by default
console.log(ctx.lang);

// Set context language
ctx.lang = "en";
// Logs "en"
console.log(ctx.lang);

演示 Canvas 上下文本地化支持

在这个示例中,我们使用一种具有语言相关连字(ligatures)的特定字体,将一个文本字符串渲染到 2D Canvas 上下文中。我们允许调整 Canvas 上下文的语言,以便你可以看到渲染效果的差异。

HTML

HTML 包括一个 <select> 元素,允许你选择语言 — en (英语) 或 tr (土耳其语),以及一个 <canvas> 元素用于渲染。

html
<p>
  <label for="lang">Choose language:</label>
  <select id="lang" name="lang">
    <option>en</option>
    <option>tr</option>
  </select>
</p>
<canvas></canvas>

JavaScript

在 JavaScript 中,我们首先获取对 <canvas> 元素、其 CanvasRenderingContext2D 以及 <select> 元素的引用,然后使用 CSS Font Loading API 加载依赖于语言的字体。字体加载完成后,我们运行一个 init() 函数。该函数定义了另一个函数 — drawText(),它使用加载的字体将一些文本绘制到 Canvas 上下文中,向 <select> 元素添加一个 change 事件监听器,然后调用 drawText(),以便在页面首次加载时立即将文本绘制到 Canvas 上。

js
const canvasElem = document.querySelector("canvas");
const ctx = canvasElem.getContext("2d");

const selectElem = document.querySelector("select");

const latoMediumFontFace = new FontFace(
  // Lato-Medium is a font with language specific ligatures
  "Lato-Medium",
  'url("https://mdn.github.io/shared-assets/fonts/Lato-Medium.ttf")',
);

latoMediumFontFace.load().then((font) => {
  document.fonts.add(font);
  init();
});

function init() {
  function drawText() {
    ctx.clearRect(0, 0, canvasElem.width, canvasElem.height);
    ctx.font = "30px Lato-Medium";
    ctx.color = "black";
    ctx.fillText("finish crafting", 50, 100);
  }

  selectElem.addEventListener("change", () => {
    document.documentElement.lang = selectElem.value;
    drawText();
  });

  drawText();
}

<select> 的值发生变化时,会触发 change 事件处理函数,该函数:

  • <html> 元素的 lang 属性值设置为 <select> 元素的值,从而有效地更改文档的语言。
  • 运行 drawText() 函数。CanvasRenderingContext2D.lang 属性默认设置为 inherit,因此 Canvas 上下文会继承文档的语言。

结果

该示例的渲染效果如下:

尝试使用 <select> 元素更改文档语言。当语言设置为英语时,字体将以 "fi" 连字渲染。然而,当设置为土耳其语时,字体将不带 "fi" 连字渲染,因为该区域设置不包含它。

屏幕外 Canvas 的语言支持

此示例与前一个示例类似,不同之处在于字体渲染到 OffscreenCanvasRenderingContext2D,然后将生成的位图传输到屏幕上的 <canvas> 进行显示。

此外,由于屏幕外 Canvas 的继承语言只设置一次,并且在继承的 lang 属性值更改时不会动态更新,因此我们而是直接在 OffscreenCanvasRenderingContext2D 上设置 lang 属性。

HTML

html
<p>
  <label for="lang">Choose language:</label>
  <select id="lang" name="lang">
    <option>en</option>
    <option>tr</option>
  </select>
</p>
<canvas></canvas>

JavaScript

JavaScript 的工作方式与前一个示例相同,只是:

  • 屏幕内 Canvas 上下文被定义为 ImageBitmapRenderingContext
  • 我们定义了一个新的 OffscreenCanvasRenderingContext2D 来绘制文本,使用 transferToImageBitmap() 将结果传输到位图,然后使用 transferFromImageBitmap()<canvas> 上进行渲染。
  • <select> 的值发生变化时,我们直接在 OffscreenCanvasRenderingContext2D 上更新 lang 属性,而不是更改 <html>lang 属性值。
js
const canvasElem = document.querySelector("canvas");
const ctx = canvasElem.getContext("bitmaprenderer");

const offscreen = new OffscreenCanvas(canvasElem.width, canvasElem.height);
const offscreen_ctx = offscreen.getContext("2d");

const selectElem = document.querySelector("select");

const latoMediumFontFace = new FontFace(
  // Lato-Medium is a font with language specific ligatures.
  "Lato-Medium",
  'url("https://mdn.github.io/shared-assets/fonts/Lato-Medium.ttf")',
);

latoMediumFontFace.load().then((font) => {
  document.fonts.add(font);
  init();
});

function init() {
  function drawText() {
    offscreen_ctx.clearRect(0, 0, canvasElem.width, canvasElem.height);
    offscreen_ctx.lang = selectElem.value;
    offscreen_ctx.font = "30px Lato-Medium";
    offscreen_ctx.color = "black";
    offscreen_ctx.fillText("finish crafting", 50, 100);

    const bitmap = offscreen.transferToImageBitmap();
    ctx.transferFromImageBitmap(bitmap);
  }

  selectElem.addEventListener("change", () => {
    drawText();
  });

  drawText();
}

结果

该示例的渲染效果如下:

规范

规范
HTML
# dom-context-2d-lang

浏览器兼容性

另见