|
7 | 7 | import Graph from "/src/components/views/Graph.svelte"; |
8 | 8 | import RulerInput from "/src/components/widgets/inputs/RulerInput.svelte"; |
9 | 9 | import ScrollbarInput from "/src/components/widgets/inputs/ScrollbarInput.svelte"; |
| 10 | + import TextLabel from "/src/components/widgets/labels/TextLabel.svelte"; |
10 | 11 | import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte"; |
11 | 12 | import type { AppWindowStore } from "/src/stores/app-window"; |
12 | 13 | import type { DocumentStore } from "/src/stores/document"; |
|
16 | 17 | import { pasteFile } from "/src/utility-functions/files"; |
17 | 18 | import { textInputCleanup } from "/src/utility-functions/keyboard-entry"; |
18 | 19 | import { rasterizeSVGCanvas } from "/src/utility-functions/rasterization"; |
19 | | - import { setupViewportResizeObserver } from "/src/utility-functions/viewports"; |
| 20 | + import { setupViewportResizeObserver, hasFirstArtworkBeenReceived, markFirstArtworkReceived } from "/src/utility-functions/viewports"; |
20 | 21 | import type { EditorWrapper, MenuDirection, MouseCursorIcon, SRGBA8 } from "/wrapper/pkg/graphite_wasm_wrapper"; |
21 | 22 |
|
22 | 23 | let rulerHorizontal: RulerInput | undefined; |
|
53 | 54 | // Rendered SVG viewport data |
54 | 55 | let artworkSvg = ""; |
55 | 56 |
|
| 57 | + // Web-only "Initializing Renderer…" overlay shown until the first Vello-rendered artwork arrives |
| 58 | + const isWeb = import.meta.env.MODE !== "native"; |
| 59 | + let firstArtworkReceived = hasFirstArtworkBeenReceived(); |
| 60 | +
|
56 | 61 | // Rasterized SVG viewport data, or none if it's not up-to-date |
57 | 62 | let rasterizedCanvas: HTMLCanvasElement | undefined = undefined; |
58 | 63 | let rasterizedContext: CanvasRenderingContext2D | undefined = undefined; |
|
470 | 475 | subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => { |
471 | 476 | await tick(); |
472 | 477 |
|
| 478 | + if (!firstArtworkReceived) { |
| 479 | + firstArtworkReceived = true; |
| 480 | + markFirstArtworkReceived(); |
| 481 | + } |
| 482 | +
|
473 | 483 | updateDocumentArtwork(data.svg); |
474 | 484 | }); |
475 | 485 | subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => { |
|
708 | 718 | > |
709 | 719 | </canvas> |
710 | 720 | {/if} |
| 721 | + {#if isWeb} |
| 722 | + <TextLabel class="shader-compiling-overlay" italic={true} classes={{ show: !firstArtworkReceived }}>Initializing Renderer…</TextLabel> |
| 723 | + {/if} |
711 | 724 | </div> |
712 | 725 |
|
713 | 726 | <div class="graph-view" class:open={$document.graphViewOverlayOpen} style:--fade-artwork={`${$document.fadeArtwork}%`} data-graph> |
|
944 | 957 | unicode-bidi: plaintext; |
945 | 958 | } |
946 | 959 |
|
| 960 | + .shader-compiling-overlay { |
| 961 | + position: absolute; |
| 962 | + inset: 0; |
| 963 | + display: flex; |
| 964 | + align-items: center; |
| 965 | + justify-content: center; |
| 966 | + pointer-events: none; |
| 967 | + opacity: 0; |
| 968 | + transition: opacity 0.5s ease; |
| 969 | +
|
| 970 | + &.show { |
| 971 | + opacity: 1; |
| 972 | + animation: shader-compiling-overlay-fade-in 0.5s ease 0.5s both; |
| 973 | + } |
| 974 | +
|
| 975 | + @keyframes shader-compiling-overlay-fade-in { |
| 976 | + from { |
| 977 | + opacity: 0; |
| 978 | + } |
| 979 | + to { |
| 980 | + opacity: 1; |
| 981 | + } |
| 982 | + } |
| 983 | + } |
| 984 | +
|
947 | 985 | .text-input div { |
948 | 986 | cursor: text; |
949 | 987 | background: none; |
|
0 commit comments