墨水 API

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

墨水 API 允许浏览器在绘制墨迹应用功能中的笔触时,直接使用可用的操作系统级合成器,从而降低延迟并提高性能。

概念和用法

网页上的墨迹指的是涉及使用 指针事件 绘制平滑笔触的应用程序功能,例如绘图应用程序或文档签名功能。

指针事件通常先发送到浏览器进程,然后浏览器进程将这些事件转发到 JavaScript 事件循环,以执行关联的处理程序函数并在应用程序中呈现结果。此过程的开始和结束之间的时间延迟可能很显著,导致用户开始绘制(例如,使用触控笔或鼠标)和笔触显示在屏幕上之间出现延迟。

墨水 API 通过允许浏览器完全绕过 JavaScript 事件循环,显著减少了这种延迟。在可能的情况下,浏览器将直接将这些渲染指令传递给操作系统级合成器。如果底层操作系统没有专门的操作系统级合成器用于此目的,浏览器将使用其自己的优化渲染代码。这不像合成器那么强大,但仍然可以带来一些改进。

注意: 合成器是渲染机制的一部分,用于在浏览器或操作系统中将 UI 绘制到屏幕上。有关合成器在网页浏览器内部如何工作的一些有趣见解,请参阅 现代网页浏览器的内部视角(第 3 部分)

入口点是 Navigator.ink 属性,它为当前文档返回一个 Ink 对象。 Ink.requestPresenter() 方法返回一个 Promise,该方法将与一个 InkPresenter 对象实例一起完成。这指示操作系统级合成器在每次指针事件分发之间的下一个可用帧中渲染墨迹笔触。

接口

墨水

提供对应用程序用于渲染笔触的 InkPresenter 对象的访问。

InkPresenter

指示操作系统级合成器在指针事件分发之间渲染墨迹笔触。

对其他接口的扩展

为当前文档返回一个 Ink 对象。

示例

绘制墨迹轨迹

在此示例中,我们在 2D 画布上绘制一条轨迹。在代码开头附近,我们调用 Ink.requestPresenter(),将画布作为其要处理的呈现区域传递给它,并将它返回的 promise 存储在 presenter 变量中。

稍后,在 pointermove 事件监听器中,每次事件触发时,轨迹头部的新的位置都会被绘制到画布上。此外,当 presenter promise 完成时返回的 InkPresenter 对象,它的 updateInkTrailStartPoint() 方法被调用;这传递

  • 表示当前帧渲染点的最后一个可信指针事件。
  • 一个包含颜色和直径设置的 style 对象。

结果是,应用程序的代理墨迹轨迹在应用程序自己的指定样式中绘制在默认浏览器渲染之前,直到下次收到 pointermove 事件。

HTML

html
<canvas id="canvas"></canvas>
<div id="div">Delegated ink trail should match the color of this div.</div>

CSS

css
div {
  background-color: rgb(0 255 0 / 100%);
  position: fixed;
  top: 1rem;
  left: 1rem;
}

JavaScript

js
const ctx = canvas.getContext("2d");
const presenter = navigator.ink.requestPresenter({ presentationArea: canvas });
let move_cnt = 0;
let style = { color: "rgb(0 255 0 / 100%)", diameter: 10 };

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

canvas.addEventListener("pointermove", async (evt) => {
  const pointSize = 10;
  ctx.fillStyle = style.color;
  ctx.fillRect(evt.pageX, evt.pageY, pointSize, pointSize);
  if (move_cnt == 20) {
    const r = getRandomInt(0, 255);
    const g = getRandomInt(0, 255);
    const b = getRandomInt(0, 255);

    style = { color: `rgb(${r} ${g} ${b} / 100%)`, diameter: 10 };
    move_cnt = 0;
    document.getElementById("div").style.backgroundColor =
      `rgb(${r} ${g} ${b} / 60%)`;
  }
  move_cnt += 1;
  await presenter.updateInkTrailStartPoint(evt, style);
});

window.addEventListener("pointerdown", () => {
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
});

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

结果

规范

规范
墨水 API
# ink-interface

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅