mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 01:36:12 +02:00
🐛 Fix new render masks
This commit is contained in:
parent
91fbe8f8ef
commit
1f44d53f6b
4 changed files with 109 additions and 13 deletions
|
@ -108,6 +108,11 @@ export function useShape(id) {
|
|||
Module._use_shape(...buffer);
|
||||
}
|
||||
|
||||
export function set_parent(id) {
|
||||
const buffer = getU32(id);
|
||||
Module._set_parent(...buffer);
|
||||
}
|
||||
|
||||
export function setupInteraction(canvas) {
|
||||
canvas.addEventListener("wheel", (e) => {
|
||||
e.preventDefault();
|
||||
|
|
86
frontend/resources/wasm-playground/masks.html
Normal file
86
frontend/resources/wasm-playground/masks.html
Normal file
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>WASM + WebGL2 Canvas</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
background: #111;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
<script type="module">
|
||||
import initWasmModule from '/js/render_wasm.js';
|
||||
import {
|
||||
init, addShapeSolidFill, assignCanvas, hexToU32ARGB, getRandomInt, getRandomColor,
|
||||
getRandomFloat, useShape, setShapeChildren, setupInteraction, set_parent
|
||||
} from './js/lib.js';
|
||||
|
||||
const canvas = document.getElementById("canvas");
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
const shapes = 10;
|
||||
|
||||
initWasmModule().then(Module => {
|
||||
init(Module);
|
||||
assignCanvas(canvas);
|
||||
Module._set_canvas_background(hexToU32ARGB("#FABADA", 1));
|
||||
Module._set_view(1, 0, 0);
|
||||
Module._init_shapes_pool(shapes + 1);
|
||||
setupInteraction(canvas);
|
||||
|
||||
useShape("00000000-0000-0000-0000-000000000000");
|
||||
const group_id = "cbf2e110-ef85-8081-8006-2d4d7cb97d4a";
|
||||
setShapeChildren([group_id, "cbf2e110-ef85-8081-8006-2d4d7cb97d4d"]);
|
||||
|
||||
useShape("cbf2e110-ef85-8081-8006-2d4d7cb97d4d");
|
||||
set_parent("00000000-0000-0000-0000-000000000000");
|
||||
Module._set_shape_type(3);
|
||||
Module._set_shape_selrect(100, 100, 200, 200);
|
||||
addShapeSolidFill(hexToU32ARGB("#aabbcc", 1));
|
||||
|
||||
const group_children = [];
|
||||
|
||||
let uuid = "a822d9e3-16c5-802c-8006-2d6d04f9c3e5";
|
||||
group_children.push(uuid);
|
||||
useShape(uuid);
|
||||
set_parent(group_id);
|
||||
Module._set_shape_type(3);
|
||||
Module._set_shape_selrect(319, 144, 544, 332);
|
||||
addShapeSolidFill(hexToU32ARGB("#0c44ea", 1));
|
||||
|
||||
|
||||
uuid = "a822d9e3-16c5-802c-8006-2d6d06e88e19";
|
||||
group_children.push(uuid);
|
||||
useShape(uuid);
|
||||
set_parent(group_id);
|
||||
Module._set_shape_type(6);
|
||||
Module._set_shape_selrect(98, 214, 426, 475);
|
||||
addShapeSolidFill(hexToU32ARGB("#B1B2B5", 1));
|
||||
|
||||
useShape(group_id);
|
||||
set_parent("00000000-0000-0000-0000-000000000000");
|
||||
Module._set_shape_type(1);
|
||||
Module._set_shape_selrect(319, 144, 544, 332);
|
||||
Module._set_shape_masked_group(true);
|
||||
setShapeChildren(group_children);
|
||||
|
||||
Module._render(Date.now());
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,7 @@
|
|||
use skia_safe::{self as skia, image, Matrix, RRect, Rect};
|
||||
|
||||
use crate::uuid::Uuid;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use crate::performance;
|
||||
use crate::view::Viewbox;
|
||||
|
@ -90,7 +90,7 @@ pub(crate) struct RenderState {
|
|||
// Indicates whether the rendering process has pending frames.
|
||||
pub render_in_progress: bool,
|
||||
// Stack of nodes pending to be rendered.
|
||||
pub pending_nodes: VecDeque<NodeRenderState>,
|
||||
pub pending_nodes: Vec<NodeRenderState>,
|
||||
pub current_tile: Option<tiles::Tile>,
|
||||
pub sampling_options: skia::SamplingOptions,
|
||||
pub render_area: Rect,
|
||||
|
@ -146,7 +146,7 @@ impl RenderState {
|
|||
background_color: skia::Color::TRANSPARENT,
|
||||
render_request_id: None,
|
||||
render_in_progress: false,
|
||||
pending_nodes: VecDeque::new(),
|
||||
pending_nodes: vec![],
|
||||
current_tile: None,
|
||||
sampling_options,
|
||||
render_area: Rect::new_empty(),
|
||||
|
@ -552,7 +552,7 @@ impl RenderState {
|
|||
}
|
||||
performance::end_measure!("tile_cache");
|
||||
|
||||
self.pending_nodes = VecDeque::new();
|
||||
self.pending_nodes = vec![];
|
||||
// reorder by distance to the center.
|
||||
self.pending_tiles.sort_by(|a, b| b.2.cmp(&a.2));
|
||||
self.current_tile = None;
|
||||
|
@ -720,7 +720,7 @@ impl RenderState {
|
|||
performance::begin_measure!("render_shape_tree::uncached");
|
||||
let mut i = 0;
|
||||
let mut is_empty = true;
|
||||
while let Some(node_render_state) = self.pending_nodes.pop_front() {
|
||||
while let Some(node_render_state) = self.pending_nodes.pop() {
|
||||
let NodeRenderState {
|
||||
id: node_id,
|
||||
visited_children,
|
||||
|
@ -751,7 +751,7 @@ impl RenderState {
|
|||
// the blend mode 'destination-in') the content
|
||||
// of the group and the mask.
|
||||
if group.masked {
|
||||
self.pending_nodes.push_back(NodeRenderState {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: node_id,
|
||||
visited_children: true,
|
||||
clip_bounds: None,
|
||||
|
@ -759,7 +759,7 @@ impl RenderState {
|
|||
mask: false,
|
||||
});
|
||||
if let Some(&mask_id) = element.mask_id() {
|
||||
self.pending_nodes.push_back(NodeRenderState {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: mask_id,
|
||||
visited_children: false,
|
||||
clip_bounds: None,
|
||||
|
@ -801,7 +801,7 @@ impl RenderState {
|
|||
}
|
||||
|
||||
// Set the node as visited_children before processing children
|
||||
self.pending_nodes.push_back(NodeRenderState {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: node_id,
|
||||
visited_children: true,
|
||||
clip_bounds: None,
|
||||
|
@ -825,8 +825,8 @@ impl RenderState {
|
|||
});
|
||||
}
|
||||
|
||||
for child_id in children_ids.iter().rev() {
|
||||
self.pending_nodes.push_front(NodeRenderState {
|
||||
for child_id in children_ids.iter() {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: *child_id,
|
||||
visited_children: false,
|
||||
clip_bounds: children_clip_bounds,
|
||||
|
|
|
@ -635,12 +635,17 @@ impl Shape {
|
|||
IndexSet::<Uuid>::new()
|
||||
} else if let Type::Group(group) = self.shape_type {
|
||||
if group.masked {
|
||||
self.children.iter().skip(1).cloned().collect()
|
||||
self.children
|
||||
.iter()
|
||||
.rev()
|
||||
.take(self.children.len() - 1)
|
||||
.cloned()
|
||||
.collect()
|
||||
} else {
|
||||
self.children.clone().into_iter().collect()
|
||||
self.children.clone().into_iter().rev().collect()
|
||||
}
|
||||
} else {
|
||||
self.children.clone().into_iter().collect()
|
||||
self.children.clone().into_iter().rev().collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue