Skip to content

Commit 89ecbcc

Browse files
committed
Remove last_svg_canvas and do this logic in the frontend
1 parent 190ae98 commit 89ecbcc

File tree

3 files changed

+8
-20
lines changed

3 files changed

+8
-20
lines changed

editor/src/messages/portfolio/portfolio_message_handler.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,10 +1088,6 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
10881088
// Set the new active document ID
10891089
self.active_document_id = Some(document_id);
10901090

1091-
// Clear the cached canvas frame so the frontend gets a fresh SVG with the canvas placeholder,
1092-
// since the previous document's DOM element was destroyed when the document view changed.
1093-
self.executor.clear_canvas_cache();
1094-
10951091
responses.add(MenuBarMessage::SendLayout);
10961092
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
10971093
responses.add(FrontendMessage::UpdateActiveDocument { document_id });

editor/src/node_graph_executor.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use graph_craft::document::value::{RenderOutput, TaggedValue};
55
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput};
66
use graph_craft::proto::GraphErrors;
77
use graph_craft::wasm_application_io::EditorPreferences;
8-
use graphene_std::application_io::{NodeGraphUpdateMessage, RenderConfig};
9-
use graphene_std::application_io::{SurfaceFrame, TimingInformation};
8+
use graphene_std::application_io::{NodeGraphUpdateMessage, RenderConfig, TimingInformation};
109
use graphene_std::raster::{CPU, Raster};
1110
use graphene_std::renderer::{RenderMetadata, format_transform_matrix};
1211
use graphene_std::text::FontCache;
@@ -56,7 +55,6 @@ pub struct NodeGraphExecutor {
5655
futures: VecDeque<(u64, ExecutionContext)>,
5756
node_graph_hash: u64,
5857
previous_node_to_inspect: Option<NodeId>,
59-
last_svg_canvas: Option<SurfaceFrame>,
6058
}
6159

6260
#[derive(Debug, Clone)]
@@ -79,7 +77,6 @@ impl NodeGraphExecutor {
7977
node_graph_hash: 0,
8078
current_execution_id: 0,
8179
previous_node_to_inspect: None,
82-
last_svg_canvas: None,
8380
};
8481
(node_runtime, node_executor)
8582
}
@@ -94,10 +91,6 @@ impl NodeGraphExecutor {
9491
execution_id
9592
}
9693

97-
pub fn clear_canvas_cache(&mut self) {
98-
self.last_svg_canvas = None;
99-
}
100-
10194
pub fn update_font_cache(&self, font_cache: FontCache) {
10295
self.runtime_io.send(GraphRuntimeRequest::FontCacheUpdate(font_cache)).expect("Failed to send font cache update");
10396
}
@@ -388,19 +381,14 @@ impl NodeGraphExecutor {
388381
// Send to frontend
389382
responses.add(FrontendMessage::UpdateImageData { image_data });
390383
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
391-
self.last_svg_canvas = None;
392384
}
393-
RenderOutputType::CanvasFrame(frame) => 'block: {
394-
if self.last_svg_canvas == Some(frame) {
395-
break 'block;
396-
}
385+
RenderOutputType::CanvasFrame(frame) => {
397386
let matrix = format_transform_matrix(frame.transform);
398387
let transform = if matrix.is_empty() { String::new() } else { format!(" transform=\"{matrix}\"") };
399388
let svg = format!(
400389
r#"<svg><foreignObject width="{}" height="{}"{transform}><div data-canvas-placeholder="{}" data-is-viewport="true"></div></foreignObject></svg>"#,
401390
frame.resolution.x, frame.resolution.y, frame.surface_id.0,
402391
);
403-
self.last_svg_canvas = Some(frame);
404392
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
405393
}
406394
RenderOutputType::Texture { .. } => {}

frontend/src/components/panels/Document.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,13 @@
198198
const logicalWidth = parseFloat(foreignObject.getAttribute("width") || "0");
199199
const logicalHeight = parseFloat(foreignObject.getAttribute("height") || "0");
200200
201-
// Clone canvas for repeated instances (layers that appear multiple times)
202-
// Viewport canvas is marked with data-is-viewport and should never be cloned
201+
// Viewport canvas is marked with data-is-viewport and should never be cloned.
202+
// If it's already mounted in the viewport, skip the DOM replacement since it's already showing the rendered content.
203+
// We check `canvas.isConnected` to ensure it's in the live DOM, not a detached tree from a destroyed component.
203204
const isViewport = placeholder.hasAttribute("data-is-viewport");
205+
if (isViewport && canvas.isConnected && canvas.parentElement?.closest("[data-viewport]")) return;
206+
207+
// Clone canvas for repeated instances (layers that appear multiple times)
204208
if (!isViewport && canvas.parentElement) {
205209
const newCanvas = window.document.createElement("canvas");
206210
const context = newCanvas.getContext("2d");

0 commit comments

Comments
 (0)