LibWeb: Apply scroll offset to mask-images

This makes icon SVGs not disappear when scrolling on
https://www.fangamer.com/. Icons on this site are boxes with background
colours, with the SVG of the icon masking it with mask-image.
This commit is contained in:
Luke Wilde 2025-02-20 16:57:08 +00:00 committed by Tommy van der Vorst
commit 8f15e68618
4 changed files with 41 additions and 1 deletions

View file

@ -356,7 +356,8 @@ void StackingContext::paint(PaintContext& context) const
auto mask_display_list = DisplayList::create();
DisplayListRecorder display_list_recorder(*mask_display_list);
auto mask_painting_context = context.clone(display_list_recorder);
auto mask_rect_in_device_pixels = context.enclosing_device_rect(paintable_box().absolute_padding_box_rect());
CSSPixelPoint enclosing_scroll_offset = paintable_box().cumulative_offset_of_enclosing_scroll_frame();
auto mask_rect_in_device_pixels = context.enclosing_device_rect(paintable_box().absolute_padding_box_rect().translated(enclosing_scroll_offset));
mask_image->paint(mask_painting_context, { {}, mask_rect_in_device_pixels.size() }, CSS::ImageRendering::Auto);
context.display_list_recorder().add_mask(mask_display_list, mask_rect_in_device_pixels.to_type<int>());
}

View file

@ -0,0 +1,10 @@
<style>
* {
margin: 0;
scrollbar-width: none;
}
body {
background-color: white;
}
</style>
<img src="../images/mask-image-with-scroll-offset-ref.png">

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<head>
<link rel="match" href="../expected/mask-image-with-scroll-offset-ref.html" />
<style>
* {
scrollbar-width: none;
}
body {
height: 1000px;
}
#mask-image-box {
background-color: black;
mask-image: url("data:image/svg+xml;,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%20250%20100%22%20xmlns:bx=%22https://boxy-svg.com%22%20width=%22250px%22%20height=%22100px%22%3E%3Cdefs/%3E%3Cpath%20style=%22paint-order:%20fill;%20stroke-width:%207px;%20stroke:%20rgb(0,%200,%200);%20fill:%20none;%22%20d=%22M%2012.081%2016.735%20C%2012.452%2024.431%2012.257%2032.16%2012.257%2039.864%20C%2012.257%2045.194%2012.257%2050.524%2012.257%2055.854%20C%2012.257%2058.991%2012.163%2062.157%2012.54%2065.28%20C%2012.819%2067.597%2013.408%2069.752%2014.658%2071.713%20C%2020.129%2080.295%2019.491%2080.452%2026.539%2072.084%20C%2028.049%2070.292%2029.372%2068.575%2030.648%2066.62%20C%2031.224%2065.738%2033.945%2060.514%2035.196%2060.388%20C%2040.978%2059.801%2041.188%2077.229%2047.317%2076.494%20C%2051.976%2075.936%2057.851%2065.369%2060.07%2062.252%20C%2071.941%2045.581%2077.42%2027.247%2084.474%208.554%22/%3E%3Cpath%20style=%22stroke:%20rgb(0,%200,%200);%20stroke-width:%207px;%20fill:%20none;%22%20d=%22M%20114.39%2054.973%20C%20128.428%2054.973%20142.466%2054.973%20156.503%2054.973%22/%3E%3Cpath%20style=%22stroke:%20rgb(0,%200,%200);%20stroke-width:%207px;%20paint-order:%20fill;%20fill:%20none;%22%20d=%22M%20192.852%2086.865%20C%20192.852%2069.251%20193.133%2051.863%20191.594%2034.418%20C%20191.185%2029.777%20187.376%2017.14%20189.886%2012.418%20C%20190.342%2011.561%20198.042%2012.292%20198.919%2012.292%20C%20208.296%2012.292%20218.05%2012.743%20227.261%2012.743%22/%3E%3Cpath%20style=%22stroke:%20rgb(0,%200,%200);%20stroke-width:%207px;%20fill:%20none;%22%20d=%22M%20194.468%2052.122%20C%20202.778%2052.122%20211.087%2052.122%20219.397%2052.122%22/%3E%3Cpath%20style=%22stroke:%20rgb(0,%200,%200);%20stroke-width:%208px;%20fill:%20none;%22%20d=%22M%20112.97%2024.534%20C%20112.97%2039.5%20112.755%2054.483%20113.301%2069.43%20C%20113.497%2074.787%20112.519%2081.541%20113.904%2086.759%22/%3E%3Cpath%20style=%22stroke:%20rgb(0,%200,%200);%20stroke-width:%208px;%20fill:%20none;%22%20d=%22M%20156.251%2026.521%20C%20156.251%2035.293%20155.519%2044.382%20156.337%2053.117%20C%20156.872%2058.831%20158.395%2064.516%20158.467%2070.256%20C%20158.552%2076.979%20156.876%2083.994%20156.876%2090.342%22/%3E%3C/svg%3E");
width: 250px;
height: 100px;
position: absolute;
top: 60px;
}
</style>
</head>
<body>
<div id="mask-image-box">
</div>
<script>
setTimeout(() => {
window.scrollTo(0, 50);
}, 0);
</script>
</body>