mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 00:38:12 +08:00
Add an "Initializing Renderer…" overlay when Vello shader compilation is slow on web
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
import Graph from "/src/components/views/Graph.svelte";
|
import Graph from "/src/components/views/Graph.svelte";
|
||||||
import RulerInput from "/src/components/widgets/inputs/RulerInput.svelte";
|
import RulerInput from "/src/components/widgets/inputs/RulerInput.svelte";
|
||||||
import ScrollbarInput from "/src/components/widgets/inputs/ScrollbarInput.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 WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
|
||||||
import type { AppWindowStore } from "/src/stores/app-window";
|
import type { AppWindowStore } from "/src/stores/app-window";
|
||||||
import type { DocumentStore } from "/src/stores/document";
|
import type { DocumentStore } from "/src/stores/document";
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
import { pasteFile } from "/src/utility-functions/files";
|
import { pasteFile } from "/src/utility-functions/files";
|
||||||
import { textInputCleanup } from "/src/utility-functions/keyboard-entry";
|
import { textInputCleanup } from "/src/utility-functions/keyboard-entry";
|
||||||
import { rasterizeSVGCanvas } from "/src/utility-functions/rasterization";
|
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";
|
import type { EditorWrapper, MenuDirection, MouseCursorIcon, SRGBA8 } from "/wrapper/pkg/graphite_wasm_wrapper";
|
||||||
|
|
||||||
let rulerHorizontal: RulerInput | undefined;
|
let rulerHorizontal: RulerInput | undefined;
|
||||||
@@ -53,6 +54,10 @@
|
|||||||
// Rendered SVG viewport data
|
// Rendered SVG viewport data
|
||||||
let artworkSvg = "";
|
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
|
// Rasterized SVG viewport data, or none if it's not up-to-date
|
||||||
let rasterizedCanvas: HTMLCanvasElement | undefined = undefined;
|
let rasterizedCanvas: HTMLCanvasElement | undefined = undefined;
|
||||||
let rasterizedContext: CanvasRenderingContext2D | undefined = undefined;
|
let rasterizedContext: CanvasRenderingContext2D | undefined = undefined;
|
||||||
@@ -470,6 +475,11 @@
|
|||||||
subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
|
subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
|
||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
|
if (!firstArtworkReceived) {
|
||||||
|
firstArtworkReceived = true;
|
||||||
|
markFirstArtworkReceived();
|
||||||
|
}
|
||||||
|
|
||||||
updateDocumentArtwork(data.svg);
|
updateDocumentArtwork(data.svg);
|
||||||
});
|
});
|
||||||
subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
|
subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
|
||||||
@@ -708,6 +718,9 @@
|
|||||||
>
|
>
|
||||||
</canvas>
|
</canvas>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if isWeb}
|
||||||
|
<TextLabel class="shader-compiling-overlay" italic={true} classes={{ show: !firstArtworkReceived }}>Initializing Renderer…</TextLabel>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-view" class:open={$document.graphViewOverlayOpen} style:--fade-artwork={`${$document.fadeArtwork}%`} data-graph>
|
<div class="graph-view" class:open={$document.graphViewOverlayOpen} style:--fade-artwork={`${$document.fadeArtwork}%`} data-graph>
|
||||||
@@ -944,6 +957,31 @@
|
|||||||
unicode-bidi: plaintext;
|
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 {
|
.text-input div {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
background: none;
|
background: none;
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
import type { EditorWrapper } from "/wrapper/pkg/graphite_wasm_wrapper";
|
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 {
|
export function setupViewportResizeObserver(editor: EditorWrapper): () => void {
|
||||||
const viewports = Array.from(window.document.querySelectorAll("[data-viewport-container]"));
|
const viewports = Array.from(window.document.querySelectorAll("[data-viewport-container]"));
|
||||||
if (viewports.length <= 0) return () => {};
|
if (viewports.length <= 0) return () => {};
|
||||||
|
|||||||
Reference in New Issue
Block a user