🐛 Fix children blur rendering

This commit is contained in:
Elena Torro
2025-11-04 12:20:47 +01:00
parent 69bbdad570
commit 564ad8adba
5 changed files with 242 additions and 6 deletions

File diff suppressed because one or more lines are too long

View File

@@ -228,3 +228,19 @@ test("Renders a file with paths and svg attrs", async ({
await expect(workspace.canvas).toHaveScreenshot(); await expect(workspace.canvas).toHaveScreenshot();
}); });
test("Renders a file with nested frames with inherited blur", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockGetFile("render-wasm/get-file-frame-with-nested-blur.json");
await workspace.goToWorkspace({
id: "58c5cc60-d124-81bd-8007-0ee4e5030609",
pageId: "58c5cc60-d124-81bd-8007-0ee4e503060a",
});
await workspace.waitForFirstRender();
await expect(workspace.canvas).toHaveScreenshot();
});

View File

@@ -1182,10 +1182,11 @@ impl RenderState {
if !node_render_state.is_root() { if !node_render_state.is_root() {
let transformed_element: Cow<Shape> = Cow::Borrowed(element); let transformed_element: Cow<Shape> = Cow::Borrowed(element);
let extrect = element.extrect(tree);
// FIXME: we need to find a way to update the extrect properly instead
let bounds = transformed_element.apply_children_blur(extrect, tree);
let is_visible = transformed_element let is_visible = bounds.intersects(self.render_area)
.extrect(tree)
.intersects(self.render_area)
&& !transformed_element.hidden && !transformed_element.hidden
&& !transformed_element.visually_insignificant(self.get_scale(), tree); && !transformed_element.visually_insignificant(self.get_scale(), tree);
@@ -1346,9 +1347,7 @@ impl RenderState {
match element.shape_type { match element.shape_type {
Type::Frame(_) | Type::Group(_) => { Type::Frame(_) | Type::Group(_) => {
if let Some(blur) = element.blur { self.nested_blurs.push(element.blur);
self.nested_blurs.push(Some(blur));
}
} }
_ => {} _ => {}
} }

View File

@@ -861,6 +861,45 @@ impl Shape {
rect rect
} }
pub fn apply_children_blur(&self, mut rect: math::Rect, tree: ShapesPoolRef) -> math::Rect {
let mut children_blur = 0.0;
let mut current_parent_id = self.parent_id;
while let Some(parent_id) = current_parent_id {
if parent_id.is_nil() {
break;
}
if let Some(parent) = tree.get(&parent_id) {
match parent.shape_type {
Type::Frame(_) | Type::Group(_) => {
if let Some(blur) = parent.blur {
if !blur.hidden && blur.blur_type == BlurType::LayerBlur {
children_blur += blur.value;
}
}
}
_ => {}
}
current_parent_id = parent.parent_id;
} else {
break;
}
}
let blur = children_blur;
if blur > 0.0 {
rect.left -= blur;
rect.top -= blur;
rect.right += blur;
rect.bottom += blur;
}
rect
}
pub fn calculate_extrect(&self, shapes_pool: ShapesPoolRef) -> math::Rect { pub fn calculate_extrect(&self, shapes_pool: ShapesPoolRef) -> math::Rect {
let shape = self; let shape = self;
let max_stroke = Stroke::max_bounds_width(shape.strokes.iter(), shape.is_open()); let max_stroke = Stroke::max_bounds_width(shape.strokes.iter(), shape.is_open());
@@ -886,6 +925,7 @@ impl Shape {
rect = self.apply_shadow_bounds(rect); rect = self.apply_shadow_bounds(rect);
rect = self.apply_blur_bounds(rect); rect = self.apply_blur_bounds(rect);
rect = self.apply_children_bounds(rect, shapes_pool); rect = self.apply_children_bounds(rect, shapes_pool);
rect = self.apply_children_blur(rect, shapes_pool);
rect rect
} }