Automatic update from web-platform-tests [IntersectionObserver] Fix occlusion detection with 3D transform For regular (i.e. event-targeting) hit testing, z-axis ordering is based on the z-axis position of the center of a PaintLayer. That's not good enough for occlusion testing. With this CL, when a hit test for occlusion encounters a 3d transform, it computes the z-axis position of the four corners of the PaintLayer, and if any of them are above any point in the occlusion target (i.e. the HitTestRequest::stop_node_) then the PaintLayer is considered occluding. This is not 100% accurate, but it will never result in a false positive (i.e., reporting the target as unoccluded when it actually is), which is a hard requirement of IntersectionObserver. The corner-checking code makes a simplifying assumption that the stop_node_ has no 3D projection, which is enforced by a call to LayoutObject::HasDistortingVisualEffects from IntersectionObserver. Bug: 479203484 Change-Id: Ida70f919efc73149d32112900b019987f27a5a7e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7835432 Reviewed-by: Philip Rogers <pdr@chromium.org> Commit-Queue: Stefan Zager <szager@chromium.org> Cr-Commit-Position: refs/heads/main@{#1629048} -- wpt-commits: 082be2f96b0c78e2784300a801fd88ff5b0f9425 wpt-pr: 59807
62 lines
1.5 KiB
HTML
62 lines
1.5 KiB
HTML
<!DOCTYPE html>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<style>
|
|
body {
|
|
transform-style: preserve-3d;
|
|
}
|
|
div {
|
|
position: absolute;
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
#target1, #target2 {
|
|
background: green;
|
|
}
|
|
#target2 {
|
|
left: 150px;
|
|
}
|
|
#occluder {
|
|
background: red;
|
|
transform: translateZ(-10px) rotateY(30deg);
|
|
transform-origin: center;
|
|
}
|
|
#behind {
|
|
left: 150px;
|
|
background: red;
|
|
transform: translateZ(-10px) rotateY(10deg);
|
|
transform-origin: center;
|
|
}
|
|
</style>
|
|
|
|
<div id=occluder></div>
|
|
<div id=target1></div>
|
|
|
|
<div id=behind></div>
|
|
<div id=target2></div>
|
|
|
|
<script>
|
|
promise_test(() => {
|
|
return Promise.all([
|
|
new Promise((resolve, reject) => {
|
|
const target = document.getElementById("target1");
|
|
new IntersectionObserver(entries => {
|
|
// part of #occluder is visible above #target1
|
|
assert_false(entries[0].isVisible);
|
|
resolve();
|
|
}, {trackVisibility:true, delay:100}).observe(target);
|
|
}),
|
|
new Promise((resolve, reject) => {
|
|
const target = document.getElementById("target2");
|
|
new IntersectionObserver(entries => {
|
|
// #behind is entirely behind #target2
|
|
assert_true(entries[0].isVisible);
|
|
resolve();
|
|
}, {trackVisibility:true, delay:100}).observe(target);
|
|
})
|
|
]);
|
|
}, "Intersection observer V2 test with occlusion by an element with a 3D transform.");
|
|
</script>
|