Skip to content

Commit

Permalink
Revert "[css-view-transitions-2] First pass at layered capture (#11045)…
Browse files Browse the repository at this point in the history
…" (#11228)

This reverts commit 02eb632.
  • Loading branch information
noamr authored Nov 18, 2024
1 parent e59fec8 commit a15fbbc
Showing 1 changed file with 10 additions and 186 deletions.
196 changes: 10 additions & 186 deletions css-view-transitions-2/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ spec:css-view-transitions-1;
text: snapshot containing block; type: dfn;
text: old transform; for: captured element; type: dfn;
text: new element; for: captured element; type: dfn;
text: old width; for: captured element; type: dfn;
text: old height; for: captured element; type: dfn;
text: updateCallbackDone; type: property; for: ViewTransition;
text: phase; type: dfn; for: ViewTransition;
text: call the update callback; type: dfn;
Expand All @@ -48,8 +46,6 @@ spec:css-view-transitions-1;
text: group styles rule; type: dfn;
text: update pseudo-element styles rule; type: dfn;
text: document-scoped view transition name; type: dfn;
text: capture rendering characteristics; type: dfn;
text: capturing the image; type: dfn;
spec:dom; type:dfn; text:document
spec:css22; type:dfn; text:element
spec:selectors-4; type:dfn;
Expand All @@ -67,23 +63,7 @@ spec:geometry-1
text:multiply; type:dfn;
text:matrix; type:dfn;
spec:infra; type:dfn; text:list
spec:css-borders-4;
type: property; text:border-color;
type: property; text:border-radius;
type: property; text:box-shadow;
type: property; text:border-top;
type: property; text:border-right;
type: property; text:border-bottom;
type: property; text:border-left;
type: property; text:border-left-width;
type: property; text:border-top-width;
spec:css-sizing-3;
type: value; text:box-sizing;
type: value; text:border-box;
type: value; text:content-box;
spec:css-box-4;
type: dfn; text:padding box; for: /;
type: dfn; text:content box; for: /;
spec:css-borders-4; type: property; text:border-radius;
</pre>

<style>
Expand Down Expand Up @@ -905,48 +885,6 @@ and by applying ''view-transition-group'' to the internal element referencing th
The [=used value=] for 'view-transition-group' resolves to a 'view-transition-name' in its ancestor chain, or to ''view-transition-name/none''. When generating the [=named view transition pseudo-element=], the ''::view-transition-group()'' with that name
would be the parent of the ''::view-transition-group()'' generated for this element's 'view-transition-name'.

# Layered capture # {#layered-capture}

## Overview ## {#layered-capture-overview}

*This section is non-normative.*

In [[css-view-transitions-1]], the old and new states are captured as snapshots, and the initial and final geometry are captured,
creating a crossfade animation by default. This is a simple model and mostly creates the desired outcome.

However, crossfading two flattened snapshots is not always the most expressive animation. CSS allows animating borders, gradient backgrounds, 'filter', 'box-shadow' etc.
which can feel more expressive and natural than crossfade depending on the desired UX.

In addition, when using <a href="#nested-view-transitions">nested view transitions</a>, some of the animations could look "wrong" when the CSS properties are flattened to a snapshot.
This includes tree effects, such as 'opacity', 'mask', 'clip-path' and 'filter', and also clipping using 'overflow'. These effects are designed to apply to the whole tree of elements, not just to one element and its content.

With layered capture, all the CSS properties that affect the entire tree, as well as box decorations, are captured as style and animate as part of the group.

Issue: should this behavior be an opt-in/opt-out with a CSS property? See <a href="https://github.com/w3c/csswg-drafts/issues/11078">issue 11078</a>.


## Table of captured CSS properties {#layered-captured-css-properties}

The following list of <dfn>layered capture properties</dfn> defines the CSS properties that participate in layered capture.
When the old or new state of the element are captured, these properties are captured as style, and the user agent must render the snapshot
with disregard to that property:

- 'background'
- 'border-left'
- 'border-top'
- 'border-bottom'
- 'border-right'
- 'border-radius'
- 'border-image'
- 'box-shadow'
- 'box-sizing'
- 'clip-path'
- 'filter'
- 'mask'
- 'opacity'
- 'outline'
- 'padding'

# Algorithms # {#algorithms}

## Data structures ## {#cross-doc-data-structures}
Expand Down Expand Up @@ -1001,32 +939,15 @@ It has the following [=struct/items=]:

### Captured elements extension ### {#capture-classes-data-structure}
The [=captured element=] struct should contain these fields, in addition to the existing ones:
<dl dfn-for="captured element">
: <dfn>class list</dfn>
<dl>
: <dfn for="captured element">class list</dfn>
:: a [=/list=] of strings, initially empty.

: <dfn>containing group name</dfn>
: <dfn for="captured element">containing group name</dfn>
:: Null or a string, initially null.

: <dfn>old layered-capture style</dfn>
:: A string.

: <dfn>transform from snapshot containing block</dfn>
:: A [=matrix=], initially the [=identity transform function=].

: <dfn>old box properties
: <dfn>new box properties
:: A [=layered box properties=] or null, initially null.
</dl>
The <dfn>layered box properties</dfn> is a struct, containing the following fields:
<dl dfn-for="layered box properties">
: <dfn>box sizing</dfn>
:: ''box-sizing/border-box'' or ''box-sizing/content-box''.

: <dfn>content box</dfn>
: <dfn>padding box</dfn>
:: A rectangle, in CSS pixel units, relative to the border box.
: <dfn for="captured element">transform from snapshot containing block</dfn>
:: A [=matrix=], initially the identity matrix.
</dl>

## Resolving the ''@view-transition'' rule ## {#vt-rule-algo}
Expand Down Expand Up @@ -1318,122 +1239,25 @@ When [[css-view-transitions-1#setup-transition-pseudo-elements-algorithm|setting

1. Append |group| to |parentGroup|.

1. When setting the animation keyframes given |transform|, [=adjust the nested group transform=] to |transform|, given |groupContainerElement|'s [=old transform=], |groupContainerElement|'s [=captured element/old width=], |groupContainerElement|'s [=old height=], and |groupContainerElement|'s [=old box properties=].
1. When setting the animation keyframes given |transform|, [=multiply=] |transform| by the inverse matrix of |groupContainerElement|'s [=old transform=].

Note: It is TBD how this is resolved when the old and new groups mismatch. See <a href="https://github.com/w3c/csswg-drafts/issues/10631">Issue 10631</a>.
</div>

### Adjust the group's 'transform' to be relative to its containing ''::view-transition-group()'' ### {#vt-group-transform-adjust}
<div algorithm="additional pseudo-element style update steps (group)">
When [[css-view-transitions-1#style-transition-pseudo-elements-algorithm|updating the style of the transition pseudo-element]], perform the following steps before setting the [=captured element/group styles rule=], given a [=captured element=] |capturedElement|, a |transform|, and a {{ViewTransition}} |transition|:
When [[css-view-transitions-1#style-transition-pseudo-elements-algorithm|updating the style of the transition pseudo-element]], perform the following steps before setting the [=captured element/group styles rule=], given a [=captured element=] |capturedElement|, given a |transform| and a {{ViewTransition}} |transition|:

1. Set |capturedElement|'s [=transform from snapshot containing block=] to |transform|.

1. If |capturedElement|'s [=containing group name=] is not null, then:

1. Let |groupContainerElement| be |transition|'s [=ViewTransition/named elements=][|capturedElement|'s [=containing group name=].

1. Let |containerRect| be [=snapshot containing block=] if |capturedElement| is the [=document element=],
otherwise, |capturedElement|'s [=border box=].

1. [=Adjust the nested group transform=] to |transform|, given |groupContainerElement|'s [=transform from snapshot containing block=], |containerRect|'s width, |containerRect|'s height, and |groupContainerElement|'s [=new box properties=].</div>

## Capturing layered CSS properties ## {#layered-capture-algorithms}

### Compute the layered-capture style ### {#layered-capture-compute-style}
1. Let |groupContainerElement| be |transition|'s [=ViewTransition/named elements=][|capturedElement|'s [=containing group name=]].

<div algorithm="compute layered capture style">
To compute the <dfn>layered capture style</dfn> of an {{Element}} |element|:

1. Let |propertiesToCapture| be a new [=/list=] corresponding to the [=layered capture properties=],
1. Issue: Specify the behavior of 'overflow' and containment. See <a href="https://github.com/w3c/csswg-drafts/issues/11079">issue 11079</a>.
1. Let |styles| be a « ».
1. For each |property| in |propertiesToCapture|, [=list/append=] the [=string/concatenate|concatentation=] of « |property|, `":"`, |element|'s [=computed value=] of |property|, `";"` » to |styles|.
1. Return the [=string/concatenate|concatentation=] of |styles|.
</div>

<div algorithm="compute layered capture geometry">
To compute the <dfn>layered capture geometry</dfn> of an {{Element}} |element|, return a new [=layered box properties=],
whose [=layered box properties/box sizing=] is |element|'s [=computed value|computed=] 'box-sizing',
[=layered box properties/padding box=] is |element|'s [=/padding box=],
and whose [=layered box properties/content box=] is |element|'s [=/content box=].
1. [=Multiply=] |transform| by the inverse matrix of |groupContainerElement|'s [=transform from snapshot containing block=].
</div>

To compute the <dfn>default group size</dfn> given |element|
return |element|'s [=/content box=]'s size if |element|'s [=computed value|computed=] 'box-sizing' is ''box-sizing/content-box'', otherwise |element|'s [=/border box=]'s size.

### Capture the old layered properties ### {#capture-new-layered-props-algorithm}
<div algorithm="additional old capture steps (layered)">
When [[css-view-transitions-1#capture-new-state-algorithm|capturing the old state for an element]], perform the following steps given a [=captured element=] |capturedElement| and an [=element=] |element|:

1. Set |capturedElement|'s [=old layered-capture style=] to |element|'s [=layered capture style=].
1. Set |capturedElement|'s [=old box properties=] to |element|'s [=layered capture geometry=].
1. Set |capturedElement|'s ([=old width=], [=old height=] to |element|'s [=default group size=].
</div>

### Adjustment to image capture size ### {#capture-image-size-algorithm}
<div algorithm="adjust image capture size (layered)">
When [=capturing the image=], the [=natural dimensions=] of the image will be based on the element's [=/content box=]'s size rather than on the [=border box=].
</div>

### Render the snapshot with layered capture ### {#layered-capture-rendering}

When capturing an element into a snapshot, only the [=element contents=] are painted, without the element's effects and box decorations.
Specifically, the element's 'background', 'border', 'border-image', 'box-shadow', and 'outline' are not painted, and its 'border-radius', 'clip-path', 'filter', 'mask', and 'opacity' are not applied.

### Adjust the nested group transform ### {#vt-adjust-nested-group-transform}
To <dfn>adjust the nested group transform</dfn> given a [=matrix=] |transform|, a [=matrix=] |parentTransform|, |borderBoxWidth|, |borderBoxHeight|, and a [=layered box properties=] |boxProperties|, perform the following steps:
1. [=Multiply=] |transform| with the inverse matrix of |parentTransform|.
1. Let (left, top) be the border edge based on |boxProperties|'s [=layered box properties/padding box=] inside (|borderBoxWidth|, |borderBoxHeight|).
1. Translate |transform| by (-left, -top).

Note: These operations ensure that the default position of this nested group would be equivalent to the original element's position, given that by default a nested ':view-transition-group' would be positioned relative to the parent's [=padding edge=].

### Apply the old layered-capture properties to ''::view-transition-group()'' keyframes ### {#vt-layered-capture-apply-keyframes}
<div algorithm="additional pseudo-element setup steps (layered capture keyframes)">
When [[css-view-transitions-1#setup-transition-pseudo-elements-algorithm|setting up the transition pseudo-element]] for a [=captured element=] |capturedElement|, given a |transitionName|:
1. Let |keyframesName| be the [=string/concatenate|concatentation=] of « `-ua-view-transition-group-anim-`, |transitionName| »
1. Append |capturedElement|'s [=old layered-capture style=] to the constructed rule for |keyframesName|.
</div>

### Apply the new layered-capture properties to ''::view-transition-group()'' ### {#vt-layered-capture-apply-new-state}
<div algorithm="additional pseudo-element style update steps (layered capture new state)">
When [[css-view-transitions-1#style-transition-pseudo-elements-algorithm|updating the style of the transition pseudo-element]], perform the following steps before setting the [=captured element/group styles rule=], given a |transitionName|, a |capturedElement|, |width|, |height|, and an {{Element}} |element|:

Note: this might change and |width|, |height|.

1. Let |style| be |element|'s [=layered capture style=].
1. Set |capturedElement|'s [=new box properties=] to |element|'s [=layered capture properties=].
1. Set (|width|, |height|) to the |element|'s [=default group size=].
1. Append the [=string/concatenate|concatentation=] of « `"::view-transition-group("`, |transitionName|, `") {"`, |style| , `"}"` » to the constructed user-agent stylesheet.
1. Let (|oldContentWidth|, |oldContentHeight|) be (|capturedElement|'s [=captured element/old width=], |capturedElement|'s [=captured element/old height=]) if |capturedElement|'s [=old box properties=] is null, otherwise |capturedElement|'s [=old box properties=]'s [=layered box properties/content box=]'s size.
1. Let (|newContentWidth|, |newContentHeight|) be (|width|, |height|) if [=new box properties=] is null, otherwise |capturedElement|'s [=new box properties=]'s [=layered box properties/content box=]'s size.
1. Append the next string (with replaced variables) to the user agent stylesheet:

<pre highlight="css">
@keyframes -ua-view-transition-content-geometry-<var>transitionName</var> {
from {
width: <var>oldContentWidth</var>;
height: <var>oldContentHeight</var>;
}
}

:root::view-transition-image-pair(<var>transitionName</var>) {
position: relative;
inset: unset;
width: <var>newContentWidth</var>;
height: <var>newContentHeight</var>;
animation-name: -ua-view-transition-<var>transitionName</var>;
animation-direction: inherit;
animation-timing-function: inherit;
animation-iteration-count: inherit;
animation-duration: inherit;
}
</pre>

Note: the ':view-transition-image-pair' pseudo-element is using ''position/relative'' positioning so that the group's 'padding' will take effect.

</div>

<h2 id="priv" class="no-num">Privacy Considerations</h2>

Expand Down

0 comments on commit a15fbbc

Please sign in to comment.