Ink API

コミュニティグループ報告書ドラフト,

このバージョン:
https://wicg.github.io/ink-enhancement
最新公開バージョン:
https://www.w3.org/TR/2021/ink-api
フィードバック:
GitHub
編集者:
Ben Mathwig (Microsoft Corporation)

概要

Webインキング遅延の漸進的な改善のためのWeb APIを提供する。

この文書のステータス

この仕様は、Web Platform Incubator Community Groupによって公開されました。 これはW3C標準ではなく、W3C標準化過程上にもありません。 W3C Community Contributor License Agreement(CLA)の下では、限定的なオプトアウトおよびその他の条件が適用されることに注意してください。 W3C Community and Business Groupsについてさらに詳しく学ぶ。

1. はじめに

低レイテンシを達成することは、Web上で優れたインキング体験を実現するために重要である。一般に、Web上でのインキングは、PointerEvent イベントを消費し、ストロークをcanvas、 WebGL、またはSVGにレンダリングすることを含む。

現在、getPredictedEvents() やDesyncronized canvasなど、漸進的な改善は利用可能であるが、これらはいずれも、よりよいレイテンシを達成するためにオペレーティング システムによって提供されるシステムコンポジターを活用していない。オペレーティングシステムのコンポジターは通常、すべてのウィンドウを合成するために 1フレーム分のレイテンシを導入する。このレイテンシのフレーム中、入力がアプリケーションへ届けられることはあるが、 アプリケーションは次のフレームまで、この新しい入力でレンダリング済みフレームを更新できない。システムコンポジターは、 アプリケーションに代わってこの入力を処理し、それに応じて現在のフレームを更新する能力を持つ場合がある。Ink APIの目的は、 システムコンポジターのこの機能を、対応するシステム上でネイティブアプリケーションと同等のレイテンシを達成できる 漸進的な改善オプションとしてWebアプリケーションに公開することである。これは、すでに存在する既存の漸進的インク 改善を置き換えるものではなく、別の選択肢を提供するものである。

2. スコープ

3. Ink API

3.1. はじめに

システムコンポジターが後続の入力点を十分な忠実度で描画できるようにするには、 アプリケーションが最後にレンダリングした点をコンポジターに記述する必要がある。システムが最後にレンダリングされた 点を知っていれば、Webアプリケーションに届けられたがまだレンダリングされていないペン入力イベントに対して、 インクトレイルのセグメントを生成できる。

たとえば、入力の現在のフレームまでのすべてのインクストロークをレンダリングしたアプリケーションを考える:

部分的なインクトレイルが、入力の現在のフレームまでアプリケーションによってレンダリングされる。ペンはさらに先にある。

ここで、ペンはデジタイザー上で動き続けているが、アプリケーションはこの入力をレンダリングのために処理する機会を まだ得ていない。「superwet」なインキング体験を達成するには、システムコンポジターはこれらの入力に対して インクセグメントを重ね合わせる必要がある:

アプリケーションによってレンダリングされた同じ部分的なインクトレイルが、'superwet'なインキング体験を達成するために、ペンの位置までシステムコンポジターによって重ね合わされたインクセグメントで補完される

PointerEvent がWebアプリケーションに届けられると、アプリケーションはシステムコンポジターのインクを、アプリケーションがレンダリングしたストロークで シームレスに置き換え、最後にレンダリングしたイベント点についてコンポジターを更新できる:

すべてのユーザー入力イベントを処理した後、アプリケーションによってレンダリングされた完全なインクトレイル。

Ink APIは、これを達成するために基盤となるオペレーティングシステムAPIを公開するDelegatedInkTrailPresenter インターフェイスを提供し、将来の追加プレゼンターをサポートするために拡張性を開いたままにする。

3.2. Ink インターフェイス

[Exposed=Window]
interface Ink {
    Promise<DelegatedInkTrailPresenter> requestPresenter(
        optional InkPresenterParam param = {});
};
requestPresenter(param)

このメソッドは、DelegatedInkTrailPresenter オブジェクトのインスタンスをPromise内で返す。これはPointerEvent のディスパッチの合間にインクストロークをレンダリングするために使用できる。このメソッドが呼び出されるたびに、新しいDelegatedInkTrailPresenter インスタンスを作成しなければならない。

3.3. InkPresenterParam 辞書

dictionary InkPresenterParam {
    Element? presentationArea = null;
};
presentationArea, 型はElement、nullable、既定値はnull

インクトレイルのレンダリングを、その要素によって境界づけられた領域に制限する任意のElement。 presentationAreaはnullであるか、Inkインターフェイスと同じ文書内になければならない。そうでない場合はエラーを投げて中止する。

3.4. DelegatedInkTrailPresenter インターフェイス

[Exposed=Window]
interface DelegatedInkTrailPresenter {
    readonly attribute Element? presentationArea;

    undefined updateInkTrailStartPoint(PointerEvent event, InkTrailStyle style);
};
presentationArea, 型は Element、readonly、nullable

提供された領域の外でインクが提示されることを防ぐために、プレゼンターのスコープとなるDOM要素への参照。 この領域は常に要素のボーダーボックスのクライアント座標であるため、 要素を移動したり要素をスクロールしたりしても、作者側で再計算する必要はない。 これが提供されない場合、既定では包含ビューポートを使用する。この要素は、DelegatedInkTrailPresenter が関連付けられているものと同じ文書内にあり、かつPointerEventを受け取っている同じ文書内に なければならない。そうでない場合はエラーが投げられる。presentationAreaが文書から削除された場合、次の updateInkTrailStartPointはエラーを投げて中止しなければならない。

updateInkTrailStartPoint(event, style)

このメソッドは、現在のフレームに対する最後のレンダリング点としてどのPointerEvent が使用されたかをプレゼンターに示す。これは、DelegatedInkTrailPresenter と同じ文書内にある信頼されたイベントでなければならない。 生成された委任インクトレイルは、次のアニメーションフレームの期間中レンダリングされ、その後削除されなければならない。

3.5. InkTrailStyle 辞書

dictionary InkTrailStyle {
    required DOMString color;
    required unrestricted double diameter;
};
color, 型はDOMString

これは、インクトレイルをレンダリングするときにプレゼンターが使用するCSSカラーコードを指定する。 有効なCSS色でなければならず、そうでない場合はエラーを投げて中止する。

diameter, 型はunrestricted double

これは、インクトレイルを表示するときにプレゼンターが使用する直径を指定する。0より大きく なければならず、そうでない場合はエラーを投げて中止する。

このpartialインターフェイスは、Navigatorインターフェイスへの拡張を定義する
[Exposed=Window]
partial interface Navigator {
    [SameObject] readonly attribute Ink ink;
};
ink, 型はInk、readonly

現在の文書に対するInk のインスタンス。これは、presentationArea を含む文書、および描画するためのPointerEventを 受け取る文書と同じ文書に関連付けられていなければならない。

4. 使用例

function renderInkStroke(x, y, canvas) {
    // ... インクストロークをcanvasにレンダリングする ...
}

try {
    let canvas = document.querySelector("#canvas");
    let presenter = await navigator.ink.requestPresenter({presentationArea: canvas});

    window.addEventListener('pointermove', function(event) {
        // イベントのキューから来たすべての点をレンダリングする。
        let points = event.getCoalescedEvents();

        points.forEach( p => {
            renderInkStroke(p.x, p.y, canvas);
        });

        // ディスパッチされたイベントに属するインクストロークをレンダリングする
        renderInkStroke(event.x, event.y, canvas);

        // 最後にレンダリングした点でプレゼンターを更新し、スタイルを与える
        presenter.updateInkTrailStartPoint(event, {
            color: "#7851A9",
            diameter: event.pressure * 4
        });
    });
}

適合性

文書の 表記規則

適合性要件は、記述的な主張 とRFC 2119の用語を組み合わせて表現される。 この文書の規範的部分におけるキーワード “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” は、RFC 2119で説明されているように解釈される。 ただし、読みやすさのため、 この仕様ではこれらの語はすべて大文字では現れない。

この仕様のすべてのテキストは規範的である。 ただし、非規範的であると明示的に示されたセクション、例、および注記を除く。 [RFC2119]

この仕様の例は、“for example”という語で導入される か、または規範的テキストから class="example"によって区別される。 次のように:

これは参考例の一例である。

参考注記は“Note”という語で始まり、 規範的テキストから class="note"によって区別される。 次のように:

Note、これは参考注記である。

索引

この仕様で定義される 用語

参照により定義される 用語

参照

規範的参照

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[POINTEREVENTS3]
Patrick Lauke; Robert Flack. Pointer Events. URL: https://w3c.github.io/pointerevents/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月。Best Current Practice。 URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL索引

[Exposed=Window]
interface Ink {
    Promise<DelegatedInkTrailPresenter> requestPresenter(
        optional InkPresenterParam param = {});
};

dictionary InkPresenterParam {
    Element? presentationArea = null;
};

[Exposed=Window]
interface DelegatedInkTrailPresenter {
    readonly attribute Element? presentationArea;

    undefined updateInkTrailStartPoint(PointerEvent event, InkTrailStyle style);
};

dictionary InkTrailStyle {
    required DOMString color;
    required unrestricted double diameter;
};

[Exposed=Window]
partial interface Navigator {
    [SameObject] readonly attribute Ink ink;
};