diff --git a/source b/source index f9b7fb2ae66..a693a18ee56 100644 --- a/source +++ b/source @@ -4051,6 +4051,14 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
The following features are defined in CSS Transforms: CSSTRANSFORMS
+ +The following features are defined in CSS Writing Modes: CSSWM
onmouseoutonmouseoveronmouseuponpaintonpasteonpauseonplaywidthheightlayoutsubtreeThe user agent must use a square pixel density consisting of one pixel of image data per
coordinate space unit for the bitmaps of a canvas and its rendering contexts.
The layoutsubtree attribute is a boolean
+ attribute. If present, children of the
+ canvas element are laid out, so that they can be drawn using drawElementImage().
A canvas element can be sized arbitrarily by a style sheet, its
bitmap is then subject to the 'object-fit' CSS property.
To keep track of when the paint event needs to be fired, a
+ canvas element also has a force paint
+ event boolean, which is initially false.
A canvas element also has associated element image snapshots, which is a map of elements to element image snapshots, initially empty.
An element image snapshot is a snapshot of
+ a canvas child element that can be drawn using drawElementImage(). An element image snapshot has a width and height (dimensions in output
+ bitmap pixels), a translation matrix, and a scaling matrix. A snapshot captures
+ the border box of the element it was created from. The internal representation is
+ implementation-defined, but must preserve crisp text and vector graphics drawn at any
+ size. It could for example be a list of commands needed to draw the element. A snapshot is
+ immutable once created and is not affected by any later changes to the element.
When its canvas context mode is none, a canvas element has no rendering context,
and its bitmap must be transparent black with a natural width equal
@@ -69572,6 +69616,38 @@ callback BlobCallback = undefined (Blob? blob);
data-x="concept-agent-event-loop">event loop's update the rendering
steps.
canvas.layoutSubtree [ = value ]Returns true if the element's descendants are to be laid out, and false otherwise. This is
+ required for using drawElementImage().
Can be set, to change whether the descendants are to be laid out.
+elementImage = canvas.captureElementImage(element)Returns a newly created ElementImage object that can be drawn using
+ drawElementImage() or transferred to a
+ worker.
matrix = canvas.getElementTransform(element, drawTransform)Returns a transform that can be applied to the 'transform' property on + element to align its location for hit testing with its drawn location, assuming that + it was drawn with drawTransform.
+canvas.requestPaint()Requests that the paint event is fired on the
+ canvas even if no elements need to be repainted.
The captureElementImage(element)
+ method, when invoked, must run these steps:
Ensure non-nested canvas given this.
If element's parent is not this, then throw a
+ TypeError.
Let snapshot be the result of get element image snapshot given + element.
Return a new ElementImage object with its
+ snapshot set to snapshot.
The getElementTransform(element,
+ drawTransform) method, when invoked, must run these steps:
Let snapshot be the result of get element image snapshot given + element.
Return the result of get element transform with this, + snapshot, and drawTransform.
The requestPaint() method, when invoked, must set
+ this's force paint event to
+ true.
transform = context.drawElementImage(element, dx, dy)transform = context.drawElementImage(element, dx, dy, dw, dh)transform = context.drawElementImage(element, sx, sy, sw, sh, dx, dy)transform = context.drawElementImage(element, sx, sy, sw, sh, dx, dy, dw, dh)Draws the given element onto the canvas. Throws a TypeError if the element isn't
+ a descendant of the canvas. Returns a transform that can be applied to the
+ 'transform' property on element to align its location for hit testing with its
+ drawn location.
Objects that implement the CanvasDrawElementImage interface have the drawElementImage() method to draw
+ elements.
The drawElementImage(element, dx, dy)
+ method, when invoked, must draw an element with this,
+ element, dx, dy.
The drawElementImage(element, dx, dy, dw,
+ dh) method, when invoked, must draw an element with this,
+ element, dx, dy, dw, and dh.
The drawElementImage(element, sx, sy, sw, sh,
+ dx, dy) method, when invoked, must draw an element with this,
+ element, dx, dy, and the source rectangle given
+ by sx, sy, sw, and sh.
+
The drawElementImage(element, sx, sy, sw, sh,
+ dx, dy, dw, dh) method, when invoked, must draw an element with
+ this, element, dx, dy, dw, dh,
+ and the source rectangle given by sx, sy, sw, and
+ sh.
To draw an element, with a CanvasRenderingContext2D context,
+ an Element-or-ElementImage element, numbers dx and
+ dy, optional numbers dw and dh, and an optional source rectangle
+ sourceRect:
Ensure non-nested canvas given the canvas element to which context + is bound.
If dx or dy are infinite or NaN, then return.
If dw and dh are given and either are infinite or NaN, then + return.
Let snapshot be the result of get element image snapshot given + element.
If not given, dw and dh must default to snapshot's width and height, respectively.
If not given, sourceRect must default to a source rectange at (0, 0) with + snapshot's width and height.
If either dw or dh are zero, then return.
Paint the area of snapshot given by sourceRect to the specified + rectangular area.
+ +There is no requirement to synchronously rasterize into the output + bitmap at this point. As long as the difference is not observable, snapshot + can be stored for later rasterization.
+Let Tdraw be a copy of the current transformation + matrix.
Translate Tdraw by (dx, dy).
Scale Tdraw by (dw / snapshot's width, dh / + snapshot's height).
Return the result of get element transform with context's
+ canvas element, snapshot, and Tdraw.
To ensure non-nested canvas given a canvas element
+ canvas:
Let current be canvas.
While current is not null:
+ +If current's node document's origin is same origin with
+ canvas's node document's origin and current has a
+ shadow-including ancestor
+ canvas element, then throw a "NotSupportedError"
+ DOMException.
Only same-origin nesting is disallowed. This is because cross-origin nested
+ canvas elements will not be drawn at all by drawElementImage().
Set current to current's node navigable's container.
To get element image snapshot given an
+ Element-or-ElementImage element:
If element is an ElementImage:
If element's [[Detached]] internal slot's value is true, then
+ throw an "InvalidStateError" DOMException.
Return element's snapshot.
Assert: element is an Element.
Let canvas be the canvas element to which context is
+ bound.
If element's parent is not canvas, then throw a
+ TypeError.
Let snapshots be canvas's element image snapshots.
If snapshots[element] does not
+ exist, then throw an "InvalidStateError"
+ DOMException.
Return snapshots[element].
To get element transform, with an HTMLCanvasElement canvas,
+ an element image snapshot
+ snapshot, and a transformation matrix Tdraw:
Ensure non-nested canvas given canvas.
Let Ttranslate be snapshot's translation matrix.
Let Tscale be snapshot's scaling matrix.
Return a DOMMatrix initialized to
+ Ttranslate-1⋅Tscale-1⋅Tdraw⋅Tscale⋅Ttranslate.
Objects that implement the This example draws a pie chart where the text labels are drawn using Return image. The Let snapshot be the result of get element image snapshot given
+ element. Return the result of get element transform with this's placeholder The following are the event handlers (and their corresponding CanvasDrawImage interface have the
+ drawElementImage(). The labels can be selected, copied, etc., and are exposed to
+ assistive technologies.
+ <!doctype html>
+<meta charset="utf-8" />
+<title>Pie chart</title>
+
+<style>
+ .pie {
+ width: 250px;
+ height: 250px;
+ }
+ .pie .label {
+ text-align: center;
+ max-width: 40%;
+ font-family: sans-serif;
+ }
+ .pie .label .val {
+ display: block;
+ font-size: xx-large;
+ font-weight: bold;
+ }
+</style>
+
+<canvas layoutsubtree class="pie" role="list" aria-label="Pie Chart">
+ <div class="label" role="listitem" tabindex="0" data-val="0.45" data-color="tomato">
+ <span class="val">45%</span>Apple
+ </div>
+ <div class="label" role="listitem" tabindex="0" data-val="0.35" data-color="cornflowerblue">
+ <span class="val">35%</span>Blackberry / Bramble
+ </div>
+ <div class="label" role="listitem" tabindex="0" data-val="0.20" data-color="gold">
+ <span class="val">20%</span>Durian
+ </div>
+</canvas>
+
+<script>
+ const canvas = document.querySelector('canvas');
+ const ctx = canvas.getContext('2d');
+
+ canvas.onpaint = () => {
+ ctx.reset();
+
+ // 1. Center the coordinate system.
+ const radius = Math.min(canvas.width, canvas.height) / 2;
+ ctx.translate(radius, radius);
+
+ let angle = 0;
+ for (const label of canvas.children) {
+ const slice = Number(label.dataset.val) * Math.PI * 2;
+
+ // 2. Draw the wedge.
+ const grad = ctx.createRadialGradient(0, 0, 0, 0, 0, radius);
+ grad.addColorStop(0, `color-mix(${label.dataset.color}, white 40%)`);
+ grad.addColorStop(1, label.dataset.color);
+ ctx.fillStyle = grad;
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.arc(0, 0, radius, angle, angle + slice);
+ ctx.fill();
+
+ // 3. Draw the label element, and update its transform.
+ const mid = angle + slice / 2;
+ const label_width = label.offsetWidth * devicePixelRatio;
+ const label_height = label.offsetHeight * devicePixelRatio;
+ const x = Math.cos(mid) * radius * 0.60 - label_width / 2;
+ const y = Math.sin(mid) * radius * 0.60 - label_height / 2;
+ const transform = ctx.drawElementImage(label, x, y);
+ label.style.transform = transform;
+
+ angle += slice;
+ }
+ }
+
+ // Setup a resize observer to resize the canvas in response to dpr changes.
+ new ResizeObserver(([entry]) => {
+ const box = entry.devicePixelContentBoxSize[0];
+ canvas.width = box.inlineSize;
+ canvas.height = box.blockSize;
+ }).observe(canvas, {box: ['device-pixel-content-box']});
+</script>OffscreenCanvas is an EventTarget, so both
@@ -76198,6 +76605,21 @@ interface OffscreenCanvas : EventTarget {
getElementTransform(element,
+ drawTransform) method, when invoked, must run these steps:
+
+ canvas element,
+ snapshot, and drawTransform.oncontextlost
contextlost
oncontextrestored contextrestored
+ onpaint paint
ElementImage interface[Exposed=(Window,Worker), Transferable]
+interface ElementImage {
+ readonly attribute double width;
+ readonly attribute double height;
+ undefined close();
+};
+
+ elementImage.widthReturns the width of the element image, in output bitmap pixels.
+elementImage.heightReturns the height of the element image, in output bitmap pixels.
+elementImage.close()Discards the ElementImage object's internal data, allowing the user agent to
+ release resources early.
Each ElementImage object has an associated snapshot (an element image snapshot or null).
The width
+ getter steps are:
If this's [[Detached]] internal slot's value is true, then + return 0.
Return this's snapshot's + width.
The height getter steps are:
If this's [[Detached]] internal slot's value is true, then + return 0.
Return this's snapshot's + height.
The close()
+ method steps are:
Set this's [[Detached]] internal slot value to true.
Set snapshot to null.
ElementImage objects are transferable. Their transfer steps, given value and
+ dataHolder, are:
Set dataHolder.[[Snapshot]] to value's snapshot.
Their transfer-receiving steps, given dataHolder and value, + are:
+ +Set value's snapshot to + dataHolder.[[Snapshot]].
CanvasPaintEvent interface[Exposed=Window]
+interface CanvasPaintEvent : Event {
+ constructor(DOMString type, optional CanvasPaintEventInit eventInitDict = {});
+
+ [SameObject] readonly attribute FrozenArray<Element> changedElements;
+};
+
+dictionary CanvasPaintEventInit : EventInit {
+ sequence<Element> changedElements = [];
+};
+
+ event.changedElementsReturns a frozen array of the elements that have changed, or the
+ ElementImage objects representing those elements for
+ OffscreenCanvas.
The changedElements attribute must return
+ the value it was initialized to.
The drawElementImage() method and any
+ other methods that draw element image
+ snapshots, as well as the paint event, must not reveal
+ any security- or privacy-sensitive information that isn't otherwise observable to author code.
Such sensitive information is the following:
+ +a and area elements
+ The following is explicitly not sensitive information:
+ +canvas elementsSecurityError" DOMException rather than leak
cross-origin data.
+ The drawElementImage() method will not
+ draw cross-origin data or other sensitive information.
The value of the origin-clean flag is
propagated from a source's bitmap to a new ImageBitmap object by createImageBitmap(). Conversely, a destination
time given now and doc's relevant global object as
the timestamp. INTERSECTIONOBSERVER
For each doc of docs, prepare the rendering of doc to + reflect the current state.
+ +In implementations this operation is often called painting and creates a
+ display list. Beyond this point, the rendering is fully determined except for
+ canvas elements' output bitmaps which can
+ still be updated in the following paint events. (The layout
+ of canvas elements cannot be updated.)
Let paintEvents be an empty list.
For each doc of docs, for each shadow-including
+ descendant canvas element canvas of doc, in
+ shadow-including tree order:
Let snapshots be canvas's element image snapshots.
If canvas's layoutsubtree attribute is not specified, then
+ clear snapshots and continue.
Let fireEvent be canvas's force paint event.
Set canvas's force paint + event to false.
Let contentBox be canvas's content box.
Let scaleX be canvas's output bitmap's width in + pixels divided by canvas's contentBox's width in CSS pixels and scaleY be canvas's content + box's height in pixels divided by contentBox's height in CSS pixels.
+ +Let scalingMatrix be a new scaling matrix corresponding to scaleX + and scaleY.
+ +These scale factors are used to compute the sizes of element image snapshots, and ensure that
+ an element's default size matches what it would be outside of a canvas.
Let changedElements be an empty list.
For each child element element of canvas, in tree + order:
+ +If snapshots[element] exists, + then determine, in an implementation-defined manner, if the snapshot needs to + be updated to match the current state of element. If the implementation can + guarantee that the snapshot is up-to-date, then continue.
Let width be element's border box's width in + CSS pixels multiplied by scaleX and height + be element's border box's height in CSS + pixels multiplied by scaleY.
Let translationMatrix be a new translation matrix corresponding to the + computed value of the 'transform-origin' property of + element.
Let snapshot be a new element image snapshot with width set to width, height set to height, + translation matrix + set to translationMatrix, and scaling matrix set to + scalingMatrix. The snapshot must capture element's border + box in a representation suited for drawing at the destination width and + height. The snapshot must be created without using any sensitive + information.
+ +The width, height, and other properties of snapshot are fully + determined at this point and are not affected by future changes, e.g., changes to + canvas's output bitmap's dimensions.
+Set snapshots[element] to snapshot.
Append element to + changedElements.
Set fireEvent to true.
For each element of the keys of + snapshots:
+ +If element's parent is canvas, then + continue.
Remove element from + snapshots.
Set fireEvent to true.
If fireEvent is true, then append + (canvas, changedElements) to paintEvents.
For each (canvas, changedElements) of paintEvents,
+ fire an event named paint at canvas, using CanvasPaintEvent,
+ with the changedElements attribute
+ initialized to the result of creating a frozen array given
+ changedElements.
For each doc of docs, amend the prepared rendering of doc
+ to reflect the current state of doc's shadow-including descendant
+ canvas elements' output bitmaps.
In other words, canvas draw operations during the paint events affect the rendering of the current frame, but
+ no other API calls can, including those that synchronously update layout.
For each doc of docs, record rendering time for doc given unsafeStyleAndLayoutStartTime.
onmouseout mouseout
onmouseover mouseover
onmouseup mouseup
+ onpaint paint
onpaste paste
onpause pause
onplay play
@@ -123977,6 +124702,7 @@ typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnl
attribute EventHandler onmouseout;
attribute EventHandler onmouseover;
attribute EventHandler onmouseup;
+ attribute EventHandler onpaint;
attribute EventHandler onpaste;
attribute EventHandler onpause;
attribute EventHandler onplay;
@@ -148011,8 +148737,31 @@ legend[align=right i] {
A canvas element that represents embedded content is
expected to be treated as a replaced element; the contents of such
elements are the element's bitmap, if any, or else a transparent black bitmap with
- the same natural dimensions as the element. Other canvas elements are
- expected to be treated as ordinary elements in the rendering model.
A canvas element that has a layoutsubtree attribute specified is
+ expected to follow these requirements:
Each child is laid out individually as if it were the only child. For the purposes of this
+ layout, the canvas parent is treated as having layout containment.
This overrides the general requirement that the content of replaced elements is not considered in the CSS formatting + model.
+Children are not rendered.
Children participate in hit testing.
Children are exposed to assistive technologies (ATs).
Other canvas elements are expected to be treated as ordinary elements
+ in the rendering model.
An object element that represents an image, plugin, or its
content navigable is expected to be treated as a replaced
@@ -148062,6 +148811,7 @@ legend[align=right i] {
@@ -154566,6 +155316,11 @@ interface External {
@namespace "http://www.w3.org/1999/xhtml";
+canvas[layoutsubtree] > * { isolation: isolate !important; contain: paint !important; }
iframe { border: 2px inset; }
video { object-fit: contain; }track
layoutsubtree
+ canvas
+ lang
Window when the page's session history entry
becomes the active entry
+ paint
+ CanvasPaintEvent
+ canvas elements
+ canvas element need to be repainted using drawElementImage(), or when canvas.requestPaint() is called.
+
pointercancel
PointerEvent
@@ -156828,6 +157591,9 @@ INSERT INTERFACES HERE