diff --git a/source b/source index f9b7fb2ae66..ed5adab1dd9 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 an originating canvas element
+ weak reference, width and height (dimensions in the originating canvas element's
+ output bitmap pixels), a translation matrix, and a scaling matrix. A snapshot captures
+ the border box of the element it was created from. Descendants of the element that
+ are in the top layer must not be captured, unless the canvas element is
+ also in the top layer and is higher than the descendant in the top layer stack. A
+ snapshot is immutable once created and is not affected by any later changes to the element.
The internal representation of an element image + snapshot 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.
+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 +69623,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 children are to be laid out, and false otherwise. This is
+ required for using drawElementImage().
Can be set, to change whether the children 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 the + 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:
Let snapshot be the result of get element image snapshot given + element.
If snapshot's originating canvas element
+ is not this, then throw a TypeError.
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.
If snapshot's originating canvas element
+ is not this, then throw a TypeError.
Return the result of get element transform with 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-or-OffscreenCanvasRenderingContext2D
+ context, an Element-or-ElementImage element,
+ numbers dx and dy, optional numbers dw and dh, and an
+ optional source rectangle sourceRect:
Let canvas be the canvas element to which context is
+ bound if context is a CanvasRenderingContext2D, or the associated
+ OffscreenCanvas object for context otherwise.
Let originatingCanvas be canvas if canvas is a
+ canvas element, or canvas's placeholder canvas element otherwise.
If originatingCanvas is null, then throw a TypeError.
This can happen when canvas is an OffscreenCanvas that
+ never had a placeholder canvas
+ element, or when that canvas element has already been garbage collected.
Let snapshot be the result of get element image snapshot given + element.
If snapshot's originating canvas element
+ is not originatingCanvas, then throw a TypeError.
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 throw a
+ TypeError.
Paint the area of snapshot given by sourceRect to the specified + rectangular area.
+ +The element image must be painted in its original orientation, even if dw or + dh are negative.
+ +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.
Post-multiply Tdraw with a translation transformation described by + (dx, dy).
Post-multiply Tdraw with a scale transformation described by + (dw / snapshot's width, dh / snapshot's + height).
Return the result of get element transform with snapshot and + Tdraw.
To check same-origin canvas nesting 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 return true.
Only same-origin nesting is considered because cross-origin nested
+ canvas elements will not be drawn at all by drawElementImage().
Set current to current's node navigable's container.
Return false.
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.
Let canvas be element's parent in the flat + tree.
If canvas is null or is not a canvas element, then throw an
+ "InvalidStateError" DOMException.
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 element image snapshot snapshot and a + transformation matrix Tdraw:
+ +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 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(in oklab, ${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 object. The image in the OffscreenCanvas object is
replaced with a new blank image.
matrix = offscreenCanvas.getElementTransform(elementImage, drawTransform)Returns a transform that can be applied to the 'transform' property on the + original element to align its location for hit testing with its drawn location, assuming that it + was drawn with drawTransform.
+Return image.
The getElementTransform(elementImage,
+ drawTransform) method, when invoked, must run these steps:
Let originatingCanvas be this's placeholder canvas element.
If originatingCanvas is null, then throw a TypeError.
This can happen when this OffscreenCanvas never had a placeholder canvas element, or when
+ that canvas element has already been garbage collected.
Let snapshot be the result of get element image snapshot given + elementImage.
If snapshot's originating canvas element
+ is not originatingCanvas, then throw a TypeError.
Return the result of get element transform with snapshot and + drawTransform.
The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the @@ -76231,6 +76701,7 @@ interface OffscreenCanvasRenderingContext2D { OffscreenCanvasRenderingContext2D includes CanvasRect; OffscreenCanvasRenderingContext2D includes CanvasDrawPath; OffscreenCanvasRenderingContext2D includes CanvasText; +OffscreenCanvasRenderingContext2D includes CanvasDrawElementImage; OffscreenCanvasRenderingContext2D includes CanvasDrawImage; OffscreenCanvasRenderingContext2D includes CanvasImageData; OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles; @@ -76323,6 +76794,138 @@ interface OffscreenCanvasRenderingContext2D { +
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 this's 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;
+ [SameObject] readonly attribute FrozenArray<Element> removedElements;
+};
+
+dictionary CanvasPaintEventInit : EventInit {
+ sequence<Element> changedElements = [];
+};
+
+ event.changedElementsReturns a frozen array of the elements that have changed.
+event.removedElementsReturns a frozen array of the elements that have been removed.
+The changedElements and removedElements attributes must return
+ the values they were initialized to.
The drawElementImage() method and any
+ other methods that draw element image
+ snapshots, as well as the paint event, do not reveal
+ any security- or privacy-sensitive information that isn't otherwise observable to author code.
+ This is achieved through the use of read-back-allowed
+ rendering when creating the element image
+ snapshots.
canvas elementsSecurityError" DOMException rather than leak
cross-origin data.
+ The element image snapshots used by drawElementImage() are created using read-back-allowed
+ rendering, so that security- or privacy-sensitive information, such as cross-origin data, is
+ not exposed.
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.
If check same-origin canvas nesting given canvas returns true, + 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 contentBox's width in CSS pixels and + scaleY be canvas's output bitmap'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.
Let removedElements be an empty list.
For each child element element of canvas within the flat + tree, in tree order:
+ +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.
If snapshots[element] exists + and its width is + width, height is + height, translation matrix + matches translationMatrix, and scaling matrix matches + scalingMatrix, 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 snapshot be a new element image snapshot with originating canvas
+ element set to a weak reference to canvas, 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 using read-back-allowed
+ rendering.
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 in the flat tree is canvas, + then continue.
Remove element from + snapshots.
Append element to + removedElements.
Set fireEvent to true.
If fireEvent is true, then append + (canvas, changedElements, removedElements) to + paintEvents.
For each (canvas, changedElements, removedElements) 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 and the removedElements attribute initialized to
+ the result of creating a frozen array given removedElements.
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 +124759,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 +148794,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 +148868,7 @@ legend[align=right i] {
@@ -149991,7 +150798,6 @@ if (s = prompt('What is your name?')) {
-
@namespace "http://www.w3.org/1999/xhtml";
+canvas[layoutsubtree] > * { isolation: isolate !important; contain: paint !important; }
iframe { border: 2px inset; }
video { object-fit: contain; }Obsolete features
Obsolete but conforming features
@@ -154566,6 +155372,11 @@ interface External {
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 +157647,9 @@ INSERT INTERFACES HERE