Skip to content

Commit

Permalink
view-transitions: Clip snapshots to max texture size/viewport.
Browse files Browse the repository at this point in the history
If an element's painting exceeds viewport bounds, clip it down to max
texture size or twice the viewport bounds by painting the subset which
is closest to the snapshot root.

This involves the following 2 changes:

1) A new ClipNode is introduced to paint the desired subrect when
rendering this element in paint, raster and compositing. All these
stages should render only this subset.

2) The object-view-box on the replaced element is still set to the
ink overflow rect. So at paint time, we adjust the replaced content
rect to the actual subset that will be painted based on the clipping
above.

[email protected], [email protected], [email protected]

Bug: 1409713
Change-Id: If81bc67ad6ffe49d68e4470a6717b704edafcd3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4330193
Reviewed-by: Xianzhu Wang <[email protected]>
Commit-Queue: Khushal Sagar <[email protected]>
Reviewed-by: Philip Rogers <[email protected]>
Auto-Submit: Khushal Sagar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1121126}
  • Loading branch information
khushalsagar authored and chromium-wpt-export-bot committed Mar 23, 2023
1 parent e66b3f6 commit e79a3db
Show file tree
Hide file tree
Showing 30 changed files with 2,041 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html class=reftest-wait>
<title>View transitions: massive element below and on top of viewport partially onscreen (new content)</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:[email protected]">
<link rel="match" href="massive-element-below-and-on-top-of-viewport-partially-onscreen-ref.html">
<meta name="fuzzy" content="massive-element-below-and-on-top-of-viewport-partially-onscreen-ref.html:maxDifference=0-2;totalPixels=0-330">

<script src="/common/reftest-wait.js"></script>
<style>
.target {
position: fixed;
inset-block-start: -90px;
inline-size: 100px;
block-size: 40000px;
view-transition-name: target;
}

.top {
inline-size: 100%;
block-size: 100px;
background: lightblue;
}

.middle {
inline-size: 100%;
block-size: 39800px;
background: green;
}

.bottom {
inline-size: 100%;
block-size: 100px;
background: blue;
}

.hidden {
contain: paint;
inline-size: 10px;
block-size: 10px;
background: grey;
view-transition-name: hidden;
}

html::view-transition-group(hidden) { animation-duration: 300s; }
html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; }

html::view-transition-old(*), html::view-transition-new(*) {
object-fit: none;
}

html::view-transition-old(target) { animation: unset; opacity: 0; }
html::view-transition-new(target) { animation: unset; opacity: 1; }

</style>

<div class="target">
<div class="top">This text is at the top of the box</div>
<div class="middle">This text is in the middle of the box</div>
<div id="scrollblue" class="bottom">This text is at the bottom of the box</div>
</div>
<div id=hidden class=hidden></div>

<script>
failIfNot(document.startViewTransition, "Missing document.startViewTransition");

async function runTest() {
document.startViewTransition(() => {
requestAnimationFrame(() => requestAnimationFrame(() =>
requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
));
});
}
onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html class=reftest-wait>
<title>View transitions: massive element below and on top of viewport partially onscreen (new content)</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:[email protected]">
<link rel="match" href="massive-element-below-and-on-top-of-viewport-partially-onscreen-ref.html">
<meta name="fuzzy" content="massive-element-below-and-on-top-of-viewport-partially-onscreen-ref.html:maxDifference=0-2;totalPixels=0-330">

<script src="/common/reftest-wait.js"></script>
<style>
.target {
position: fixed;
inset-block-start: -90px;
inline-size: 100px;
block-size: 40000px;
view-transition-name: target;
}

.top {
inline-size: 100%;
block-size: 100px;
background: lightblue;
}

.middle {
inline-size: 100%;
block-size: 39800px;
background: green;
}

.bottom {
inline-size: 100%;
block-size: 100px;
background: blue;
}

.hidden {
contain: paint;
inline-size: 10px;
block-size: 10px;
background: grey;
view-transition-name: hidden;
}

html::view-transition-group(hidden) { animation-duration: 300s; }
html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; }

html::view-transition-old(*), html::view-transition-new(*) {
object-fit: none;
}

html::view-transition-old(target) { animation: unset; opacity: 1; }
html::view-transition-new(target) { animation: unset; opacity: 0; }

</style>

<div class="target">
<div class="top">This text is at the top of the box</div>
<div class="middle">This text is in the middle of the box</div>
<div id="scrollblue" class="bottom">This text is at the bottom of the box</div>
</div>
<div id=hidden class=hidden></div>

<script>
failIfNot(document.startViewTransition, "Missing document.startViewTransition");

async function runTest() {
document.startViewTransition(() => {
requestAnimationFrame(() => requestAnimationFrame(() =>
requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
));
});
}
onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<title>View transitions: massive element below viewport partially onscreen (ref)</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:[email protected]">
<style>
.target {
position: fixed;
inset-block-start: -90px;
inline-size: 100px;
block-size: 40000px;
view-transition-name: target;
}

.top {
inline-size: 100%;
block-size: 100px;
background: lightblue;
}

.middle {
inline-size: 100%;
block-size: 39800px;
background: green;
}

.bottom {
inline-size: 100%;
block-size: 100px;
background: blue;
}
</style>
<body>
<div class="target">
<div class="top">This text is at the top of the box</div>
<div class="middle">This text is in the middle of the box</div>
<div id="scrollblue" class="bottom">This text is at the bottom of the box</div>
</div>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html class=reftest-wait>
<title>View transitions: massive element below viewport and completely offscreen (new content)</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:[email protected]">
<link rel="match" href="massive-element-below-viewport-offscreen-ref.html">
<meta name="fuzzy" content="massive-element-below-viewport-offscreen-ref.html:maxDifference=0-3;totalPixels=0-950">

<script src="/common/reftest-wait.js"></script>
<style>
.target_after_bottom_edge {
position: fixed;
inset-block-start: 20000px;
inset-inline-start: 0px;
}

.target {
contain: paint;
inline-size: 100px;
block-size: 40000px;
view-transition-name: target;
}

.top {
inline-size: 100%;
block-size: 100px;
background: lightblue;
}

.middle {
inline-size: 100%;
block-size: 39800px;
background: green;
}

.bottom {
inline-size: 100%;
block-size: 100px;
background: blue;
}

.hidden {
position: fixed;
inset-block-start: 10000px;
inline-size: 10px;
block-size: 10px;
background: grey;
view-transition-name: hidden;
}

html::view-transition-group(hidden) { animation-duration: 300s; }
html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; }

html::view-transition-old(*), html::view-transition-new(*) {
object-fit: none;
}

/* We should capture at least viewport height worth of content from the element's top edge */
html::view-transition-group(target) {
animation: unset;
transform: unset;

position: fixed;
inset-block-start: 0;
inset-inline-start: 0;
}
html::view-transition-old(target) { animation: unset; opacity: 0; }
html::view-transition-new(target) { animation: unset; opacity: 1; }

</style>

<div class="target target_after_bottom_edge" id="target">
<div class="top">This text is at the top of the box</div>
<div class="middle">This text is in the middle of the box</div>
<div id="scrollblue" class="bottom">This text is at the bottom of the box</div>
</div>
<div id=hidden class=hidden></div>

<script>
failIfNot(document.startViewTransition, "Missing document.startViewTransition");

async function runTest() {
document.startViewTransition(() => {
requestAnimationFrame(() => requestAnimationFrame(() =>
requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
));
});
}
onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html class=reftest-wait>
<title>View transitions: massive element below viewport and completely offscreen (old content)</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:[email protected]">
<link rel="match" href="massive-element-below-viewport-offscreen-ref.html">
<meta name="fuzzy" content="massive-element-below-viewport-offscreen-ref.html:maxDifference=0-2;totalPixels=0-445">

<script src="/common/reftest-wait.js"></script>
<style>
.target_after_bottom_edge {
position: fixed;
inset-block-start: 20000px;
inset-inline-start: 0px;
}

.target {
contain: paint;
inline-size: 100px;
block-size: 40000px;
view-transition-name: target;
}

.top {
inline-size: 100%;
block-size: 100px;
background: lightblue;
}

.middle {
inline-size: 100%;
block-size: 39800px;
background: green;
}

.bottom {
inline-size: 100%;
block-size: 100px;
background: blue;
}

.hidden {
position: fixed;
inset-block-start: 10000px;
inline-size: 10px;
block-size: 10px;
background: grey;
view-transition-name: hidden;
}

html::view-transition-group(hidden) { animation-duration: 300s; }
html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; }

html::view-transition-old(*), html::view-transition-new(*) {
object-fit: none;
}

/* We should capture at least viewport height worth of content from the element's top edge */
html::view-transition-group(target) {
animation: unset;
transform: unset;

position: fixed;
inset-block-start: 0;
inset-inline-start: 0;
}
html::view-transition-new(target) { animation: unset; opacity: 0; }
html::view-transition-old(target) { animation: unset; opacity: 1; }

</style>

<div class="target target_after_bottom_edge" id="target">
<div class="top">This text is at the top of the box</div>
<div class="middle">This text is in the middle of the box</div>
<div id="scrollblue" class="bottom">This text is at the bottom of the box</div>
</div>
<div id=hidden class=hidden></div>

<script>
failIfNot(document.startViewTransition, "Missing document.startViewTransition");

async function runTest() {
document.startViewTransition(() => {
requestAnimationFrame(() => requestAnimationFrame(() =>
requestAnimationFrame(() => requestAnimationFrame(takeScreenshot))
));
});
}
onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
</script>

Loading

0 comments on commit e79a3db

Please sign in to comment.