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

瀏覽器相容性

另見