Add an "Initializing Renderer…" overlay when Vello shader compilation is slow on web

This commit is contained in:
Keavon Chambers
2026-05-23 01:07:26 -04:00
parent 62287d7893
commit 96be4ec351
2 changed files with 49 additions and 1 deletions

View File

@@ -7,6 +7,7 @@
import Graph from "/src/components/views/Graph.svelte";
import RulerInput from "/src/components/widgets/inputs/RulerInput.svelte";
import ScrollbarInput from "/src/components/widgets/inputs/ScrollbarInput.svelte";
import TextLabel from "/src/components/widgets/labels/TextLabel.svelte";
import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
import type { AppWindowStore } from "/src/stores/app-window";
import type { DocumentStore } from "/src/stores/document";
@@ -16,7 +17,7 @@
import { pasteFile } from "/src/utility-functions/files";
import { textInputCleanup } from "/src/utility-functions/keyboard-entry";
import { rasterizeSVGCanvas } from "/src/utility-functions/rasterization";
import { setupViewportResizeObserver } from "/src/utility-functions/viewports";
import { setupViewportResizeObserver, hasFirstArtworkBeenReceived, markFirstArtworkReceived } from "/src/utility-functions/viewports";
import type { EditorWrapper, MenuDirection, MouseCursorIcon, SRGBA8 } from "/wrapper/pkg/graphite_wasm_wrapper";
let rulerHorizontal: RulerInput | undefined;
@@ -53,6 +54,10 @@
// Rendered SVG viewport data
let artworkSvg = "";
// Web-only "Initializing Renderer…" overlay shown until the first Vello-rendered artwork arrives
const isWeb = import.meta.env.MODE !== "native";
let firstArtworkReceived = hasFirstArtworkBeenReceived();
// Rasterized SVG viewport data, or none if it's not up-to-date
let rasterizedCanvas: HTMLCanvasElement | undefined = undefined;
let rasterizedContext: CanvasRenderingContext2D | undefined = undefined;
@@ -470,6 +475,11 @@
subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
await tick();
if (!firstArtworkReceived) {
firstArtworkReceived = true;
markFirstArtworkReceived();
}
updateDocumentArtwork(data.svg);
});
subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
@@ -708,6 +718,9 @@
>
</canvas>
{/if}
{#if isWeb}
<TextLabel class="shader-compiling-overlay" italic={true} classes={{ show: !firstArtworkReceived }}>Initializing Renderer…</TextLabel>
{/if}
</div>
<div class="graph-view" class:open={$document.graphViewOverlayOpen} style:--fade-artwork={`${$document.fadeArtwork}%`} data-graph>
@@ -944,6 +957,31 @@
unicode-bidi: plaintext;
}
.shader-compiling-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
opacity: 0;
transition: opacity 0.5s ease;
&.show {
opacity: 1;
animation: shader-compiling-overlay-fade-in 0.5s ease 0.5s both;
}
@keyframes shader-compiling-overlay-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
.text-input div {
cursor: text;
background: none;

View File

@@ -1,5 +1,15 @@
import type { EditorWrapper } from "/wrapper/pkg/graphite_wasm_wrapper";
// Tracks whether any document has produced its first frame of rendered artwork yet during this app session.
// Used to show the one-time "Initializing Renderer…" overlay only on the very first document open.
let firstArtworkEverReceived = false;
export function hasFirstArtworkBeenReceived(): boolean {
return firstArtworkEverReceived;
}
export function markFirstArtworkReceived(): void {
firstArtworkEverReceived = true;
}
export function setupViewportResizeObserver(editor: EditorWrapper): () => void {
const viewports = Array.from(window.document.querySelectorAll("[data-viewport-container]"));
if (viewports.length <= 0) return () => {};