1. 소개
낮은 지연 시간을 달성하는 것은 웹에서 훌륭한 잉킹 경험을 제공하는 데 매우 중요합니다. 일반적으로 웹에서의 잉킹은 PointerEvent
이벤트를 소비하고 스트로크를 canvas,
WebGL 또는 SVG에 렌더링하는 일을 포함합니다.
현재 getPredictedEvents()
및 비동기화된 canvas와 같은 점진적 향상이 제공되고 있지만, 이들 중 어느 것도 더 나은 지연 시간을 달성하기 위해 운영
체제가 제공하는 시스템 컴포지터를 활용하지 않습니다. 운영 체제 컴포지터는 일반적으로 모든 창을 함께 합성하기 위해 한 프레임의
지연 시간을 도입합니다. 이 지연 시간 프레임 동안 입력이 애플리케이션에 전달될 수 있지만 애플리케이션은 다음 프레임까지 이
새 입력으로 렌더링된 프레임을 업데이트할 수 없습니다. 시스템 컴포지터는 애플리케이션을 대신하여 이 입력을 처리하고 현재
프레임을 그에 따라 업데이트할 수 있는 능력을 가질 수 있습니다. Ink API의 목적은 시스템 컴포지터의 이러한 기능을 웹
애플리케이션에 점진적 향상 옵션으로 노출하여, 지원되는 시스템에서 네이티브 애플리케이션과 지연 시간 동등성을 달성할 수
있게 하는 것입니다. 이는 이미 존재하는 기존의 점진적 잉크 향상을 대체하는 것이 아니라 또 다른 옵션을 제공합니다.
2. 범위
3. Ink API
3.1. 소개
시스템 컴포지터가 후속 입력 지점을 충분한 충실도로 그릴 수 있으려면, 애플리케이션은 마지막으로 렌더링된 지점을 컴포지터에 설명해야 합니다. 시스템이 마지막으로 렌더링된 지점을 알면, 웹 애플리케이션에 전달되었지만 아직 렌더링되지 않은 펜 입력 이벤트에 대해 잉크 궤적의 세그먼트를 생성할 수 있습니다.예를 들어, 현재 입력 프레임까지 모든 잉크 스트로크를 렌더링한 애플리케이션을 생각해 보십시오.

여기서 펜은 디지타이저 위에서 계속 이동했지만, 애플리케이션은 렌더링을 위해 이 입력을 처리할 기회를 아직 갖지 못했습니다. "superwet" 잉킹 경험을 달성하려면, 시스템 컴포지터가 이러한 입력에 대한 잉크 세그먼트를 오버레이해야 합니다.

PointerEvent가
웹 애플리케이션에 전달되면, 애플리케이션은 시스템 컴포지터 잉크를 애플리케이션이 렌더링한 스트로크로 매끄럽게 대체하고
자신이 렌더링한 마지막 이벤트 지점으로 컴포지터를 업데이트할 수 있습니다.

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 요소에 대한 참조입니다. 이 영역은 항상 해당 요소의 border box에 대한 클라이언트 좌표이므로, 요소를 이동하거나 요소를 스크롤해도 작성자가 다시 계산할 필요가 없습니다. 이것이 제공되지 않으면 기본값은 포함하는 viewport를 사용하는 것입니다. 이 요소는
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보다 커야 하며, 그렇지 않으면 오류를 발생시키고 중단합니다.
3.6.
Ink Navigator 인터페이스
확장
이 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 }); }); }