Web: show the SolidCraft mark being cut from a cube while loading (#1908)
Thanks @shuff57.
This commit is contained in:
1 parent
29dfa6bd32
commit
7d44359cf6
6 files changed
+121
-4
No files matched your search
@@ -103,6 +103,7 @@ Editable drawing code, native projects and shipped exports are collected under `
|
||||
| assets/platforms/windows/solidcraft.wxs | PhotoCraft / SolidCraft contributors | PhotoCraft packaging templates (https://github.com/storytold/photocraft), adapted for SolidCraft | Apache-2.0 |
|
||||
| assets/shaders/viewport.wgsl | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/styles/ui/palettes.rs | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| assets/styles/web/loading-logo.svg | SolidCraft contributors | Animation of the SolidCraft mark, built from the paths and gradients of assets/icons/app/macos/source/SolidCraft.icon/Assets/03-solid-blue-cutout.svg; original animation | MIT OR Apache-2.0 |
|
||||
| assets/styles/web/loading.css | SolidCraft contributors | Original SolidCraft resource data or drawing code, collected without redesign | MIT OR Apache-2.0 |
|
||||
| crates/io/src/native_cad/fixtures/block.FCStd | SolidCraft contributors | original 10 × 20 × 30 mm test box saved by FreeCAD 1.1.4 run as an external program (`make_block_fcstd.py` beside it); no third-party geometry | MIT OR Apache-2.0 |
|
||||
| crates/io/src/native_cad/fixtures/block.3dm | SolidCraft contributors | original 10 × 20 × 30 mm test box written with McNeel's MIT-licensed rhino3dm Python package (`make_block_3dm.py` beside it); no third-party geometry | MIT OR Apache-2.0 |
|
||||
|
||||
@@ -29,5 +29,5 @@ web-sys = { version = "0.3", features = [
|
||||
"Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement", "Location", "Navigator", "StorageManager",
|
||||
"FileSystemHandle", "FileSystemDirectoryHandle", "FileSystemFileHandle", "FileSystemGetFileOptions", "FileSystemWritableFileStream",
|
||||
"WritableStream", "File", "FileList", "Blob", "BlobPropertyBag", "Url", "HtmlAnchorElement", "HtmlInputElement", "Storage",
|
||||
"BeforeUnloadEvent", "Event", "EventTarget", "Response", "MediaQueryList", "Gamepad",
|
||||
"BeforeUnloadEvent", "Event", "EventTarget", "Response", "MediaQueryList", "Gamepad", "Performance",
|
||||
] }
|
||||
@@ -23,6 +23,7 @@
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/BIZUDPGothic-Regular.ttf" data-target-path="fonts" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/OFL.txt" data-target-path="fonts" />
|
||||
<link data-trunk rel="css" href="../../assets/styles/web/loading.css" />
|
||||
<link data-trunk rel="copy-file" href="../../assets/styles/web/loading-logo.svg" />
|
||||
<!-- Installable as an app (manifest.webmanifest); the icons are the Linux exports of the app mark. -->
|
||||
<meta name="theme-color" content="#343840">
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
@@ -35,7 +36,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="solidcraft_canvas"></canvas>
|
||||
<div id="solidcraft_loading">Loading SolidCraft…</div>
|
||||
<div id="solidcraft_loading" role="status"><img src="loading-logo.svg" alt=""><span class="sr-only">Loading SolidCraft…</span></div>
|
||||
<script>
|
||||
// Offline use and updates (sw.js; written into release builds by `cargo xtask web-offline`).
|
||||
if ("serviceWorker" in navigator) {
|
||||
|
||||
@@ -31,6 +31,31 @@ mod web {
|
||||
/// draws it with reversed depth, whose precision follows the distance from the eye (#1434).
|
||||
const DEPTH_BITS: u8 = 32;
|
||||
|
||||
/// The loading animation (assets/styles/web/loading-logo.svg) settles into the finished mark
|
||||
/// about 3.2 s after the page starts; this adds a short hold. The app doesn't land before it.
|
||||
const LOADING_MIN_MS: f64 = 3600.0;
|
||||
/// The fade from the loading screen into the app.
|
||||
const LOADING_FADE_MS: i32 = 300;
|
||||
|
||||
/// Take the loading screen away once the animation has played to the finished mark: wait out
|
||||
/// what is left of `LOADING_MIN_MS`, fade it, then remove it.
|
||||
fn dismiss_loading(el: web_sys::Element) {
|
||||
let Some(window) = web_sys::window() else {
|
||||
el.remove();
|
||||
return;
|
||||
};
|
||||
let now = window.performance().map_or(LOADING_MIN_MS, |p| p.now());
|
||||
let wait = (LOADING_MIN_MS - now).max(0.0) as i32;
|
||||
let fade = wasm_bindgen::closure::Closure::once_into_js(move || {
|
||||
let _ = el.set_attribute("class", "done");
|
||||
let gone = wasm_bindgen::closure::Closure::once_into_js(move || el.remove());
|
||||
if let Some(window) = web_sys::window() {
|
||||
let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(gone.unchecked_ref(), LOADING_FADE_MS);
|
||||
}
|
||||
});
|
||||
let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(fade.unchecked_ref(), wait);
|
||||
}
|
||||
|
||||
/// Seconds between autosaves of unsaved work.
|
||||
const AUTOSAVE_S: f64 = 30.0;
|
||||
|
||||
@@ -534,7 +559,7 @@ mod web {
|
||||
.await;
|
||||
if let Some(el) = document.get_element_by_id(LOADING_ID) {
|
||||
match result {
|
||||
Ok(()) => el.remove(),
|
||||
Ok(()) => dismiss_loading(el),
|
||||
Err(e) => {
|
||||
el.set_inner_html(&format!("<p>SolidCraft failed to start: {e:?}</p><p>A browser with WebGPU or WebGL2 is required.</p>"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="56 24 912 1060" width="456" height="530" role="img" aria-labelledby="t d">
|
||||
<title id="t">SolidCraft</title>
|
||||
<desc id="d">A plain cube drawn in thick lines is cut twice. Each cut starts as a flat footprint on a face and presses into the solid: first a corner block through the left face, then a pocket pressed down from the top. The cut exposes its shaded faces, then the lines fade and the gaps between faces appear, leaving the SolidCraft logo.</desc>
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient-1" x1="619.14" y1="179.734" x2="694.687" y2="396.761" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1d63c6"/>
|
||||
<stop offset="1" stop-color="#15499e"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-2" x1="619.14" y1="413.244" x2="790.839" y2="605.547" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#459fff"/>
|
||||
<stop offset="1" stop-color="#2379e7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-3" x1="632.876" y1="399.508" x2="783.971" y2="968.175" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1b66cf"/>
|
||||
<stop offset="1" stop-color="#124596"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-4" x1="207.063" y1="303.357" x2="426.837" y2="968.175" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#258df5"/>
|
||||
<stop offset="1" stop-color="#1461da"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-5" x1="385.63" y1="53.364" x2="522.989" y2="510.769" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#51adff"/>
|
||||
<stop offset="1" stop-color="#2b83f1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="gfade" cx="512" cy="740" r="620" gradientTransform="translate(512 740) scale(1 .5) translate(-512 -740)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".6" stop-color="#fff" stop-opacity=".35"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient>
|
||||
<mask id="gmask" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1300" height="1300"><rect x="-100" y="-100" width="1300" height="1300" fill="url(#gfade)"/></mask>
|
||||
</defs>
|
||||
<style>
|
||||
:root { --grid: #507eaa; --word: #15499e; --line: #0b2f66; --tool: #ff6a3d; }
|
||||
.grid { stroke: var(--grid); stroke-width: 3; fill: none; opacity: .32; }
|
||||
.word { font: 700 64px ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; fill: var(--word); letter-spacing: .02em; }
|
||||
/* base styles are the finished logo (gaps, no lines, cuts done), so reduced-motion shows it whole */
|
||||
.stk { fill: none; stroke: var(--line); stroke-width: 18; stroke-linejoin: round; stroke-linecap: round; opacity: 0; }
|
||||
.old, .plug, .dep { opacity: 0; }
|
||||
.tl { opacity: 0; }
|
||||
.pface { fill: var(--tool); fill-opacity: .20; stroke: var(--tool); stroke-width: 14; stroke-linejoin: round; }
|
||||
.ptop { fill: var(--tool); fill-opacity: .38; stroke: var(--tool); stroke-width: 18; stroke-linejoin: round; }
|
||||
.all { animation: all 5.4s linear infinite; }
|
||||
.gridg { animation: gridin 5.4s ease-out infinite; }
|
||||
.cube { transform-box: view-box; transform-origin: 512px 505px; animation: cube 5.4s cubic-bezier(.3,1.3,.5,1) infinite; }
|
||||
.old { animation: old 5.4s linear infinite; }
|
||||
.s0 { animation: s0 5.4s linear infinite; } .s1k { animation: s1k 5.4s linear infinite; } .s3 { animation: s3 5.4s linear infinite; }
|
||||
.plugL { animation: plugL 5.4s ease-in infinite; } .plugR { animation: plugR 5.4s ease-in infinite; } .plugN { animation: plugN 5.4s ease-in infinite; }
|
||||
.dep { animation: dep 5.4s ease-in-out infinite; }
|
||||
.tL { animation: tL 5.4s ease-in-out infinite; } .tP { animation: tP 5.4s ease-in-out infinite; }
|
||||
.fin { animation: fin 5.4s ease-in-out infinite; }
|
||||
@keyframes all { 0% { opacity: 0; } 2%, 96% { opacity: 1; } 99.5%, 100% { opacity: 0; } }
|
||||
@keyframes gridin { 0% { opacity: 0; } 7%, 100% { opacity: 1; } }
|
||||
@keyframes cube { 0%, 3% { opacity: 0; transform: scale(.82); } 12%, 100% { opacity: 1; transform: scale(1); } }
|
||||
@keyframes old { 0%, 3% { opacity: 0; } 8%, 56% { opacity: 1; } 62%, 100% { opacity: 0; } }
|
||||
/* each cut's edge set fades in before the previous one fades out, so shared lines never dim */
|
||||
@keyframes s0 { 0%, 3% { opacity: 0; } 8%, 32.5% { opacity: 1; } 34%, 100% { opacity: 0; } }
|
||||
@keyframes s1k { 0%, 31% { opacity: 0; } 32.5%, 48.5% { opacity: 1; } 50.5%, 100% { opacity: 0; } }
|
||||
@keyframes s3 { 0%, 47% { opacity: 0; } 48.5%, 54% { opacity: 1; } 60%, 100% { opacity: 0; } }
|
||||
@keyframes plugL { 0%, 3% { opacity: 0; } 8%, 31% { opacity: 1; } 34%, 100% { opacity: 0; } }
|
||||
@keyframes plugR { 0%, 3% { opacity: 0; } 8%, 47% { opacity: 1; } 51%, 100% { opacity: 0; } }
|
||||
@keyframes plugN { 0%, 3% { opacity: 0; } 8%, 47% { opacity: 1; } 51%, 100% { opacity: 0; } }
|
||||
/* the cut's shaded faces are exposed by the removal itself */
|
||||
@keyframes dep { 0%, 47% { opacity: 0; } 51%, 100% { opacity: 1; } }
|
||||
@keyframes tL { 0%, 22% { opacity: 0; } 24%, 33% { opacity: 1; } 38%, 100% { opacity: 0; } }
|
||||
@keyframes tP { 0%, 38% { opacity: 0; } 40%, 50% { opacity: 1; } 56%, 100% { opacity: 0; } }
|
||||
@keyframes fin { 0%, 52% { opacity: 0; } 59%, 100% { opacity: 1; } }
|
||||
@media (prefers-reduced-motion: reduce) { .all, .gridg, .cube, .old, .s0, .s1k, .s3, .plugL, .plugR, .plugN, .dep, .tL, .tP, .fin { animation: none; } }
|
||||
</style>
|
||||
<g class="all">
|
||||
<g mask="url(#gmask)"><path class="grid gridg" d="M-40 -1400.0L1100 -741.8M-40 -741.8L1100 -1400.0M-40 -1286.0L1100 -627.8M-40 -627.8L1100 -1286.0M-40 -1172.0L1100 -513.8M-40 -513.8L1100 -1172.0M-40 -1058.0L1100 -399.8M-40 -399.8L1100 -1058.0M-40 -944.0L1100 -285.8M-40 -285.8L1100 -944.0M-40 -830.0L1100 -171.8M-40 -171.8L1100 -830.0M-40 -716.0L1100 -57.8M-40 -57.8L1100 -716.0M-40 -602.0L1100 56.2M-40 56.2L1100 -602.0M-40 -488.0L1100 170.2M-40 170.2L1100 -488.0M-40 -374.0L1100 284.2M-40 284.2L1100 -374.0M-40 -260.0L1100 398.2M-40 398.2L1100 -260.0M-40 -146.0L1100 512.2M-40 512.2L1100 -146.0M-40 -32.0L1100 626.2M-40 626.2L1100 -32.0M-40 82.0L1100 740.2M-40 740.2L1100 82.0M-40 196.0L1100 854.2M-40 854.2L1100 196.0M-40 310.0L1100 968.2M-40 968.2L1100 310.0M-40 424.0L1100 1082.2M-40 1082.2L1100 424.0M-40 538.0L1100 1196.2M-40 1196.2L1100 538.0M-40 652.0L1100 1310.2M-40 1310.2L1100 652.0M-40 766.0L1100 1424.2M-40 1424.2L1100 766.0M-40 880.0L1100 1538.2M-40 1538.2L1100 880.0M-40 994.0L1100 1652.2M-40 1652.2L1100 994.0M-40 1108.0L1100 1766.2M-40 1766.2L1100 1108.0M-40 1222.0L1100 1880.2M-40 1880.2L1100 1222.0M-40 1336.0L1100 1994.2M-40 1994.2L1100 1336.0M-40 1450.0L1100 2108.2M-40 2108.2L1100 1450.0M-40 1564.0L1100 2222.2M-40 2222.2L1100 1564.0M-40 1678.0L1100 2336.2M-40 2336.2L1100 1678.0M-40 1792.0L1100 2450.2M-40 2450.2L1100 1792.0M-40 1906.0L1100 2564.2M-40 2564.2L1100 1906.0M-40 2020.0L1100 2678.2M-40 2678.2L1100 2020.0M-40 2134.0L1100 2792.2M-40 2792.2L1100 2134.0M-40 2248.0L1100 2906.2M-40 2906.2L1100 2248.0M-40 2362.0L1100 3020.2M-40 3020.2L1100 2362.0"/></g>
|
||||
<g class="cube">
|
||||
<!-- fills: the carved faces always, the material each cut will remove (fades at its cut), and the cut's own faces (appear with the removal) -->
|
||||
<g class="old">
|
||||
<path class="plug plugL" d="M116.41 531.55 L296.20 635.36 L296.20 843.81 L116.41 740.00 Z" fill="url(#linear-gradient-4)" stroke="url(#linear-gradient-4)" stroke-width="3"/>
|
||||
<path class="plug plugR" d="M709.80 395.96 L907.59 281.76 L907.59 510.55 L709.80 624.75 Z" fill="url(#linear-gradient-3)" stroke="url(#linear-gradient-3)" stroke-width="3"/>
|
||||
<path class="plug plugN" d="M710.80 168.14 L907.59 281.76 L709.08 396.37 L512.28 282.75 Z" fill="url(#linear-gradient-5)" stroke="url(#linear-gradient-5)" stroke-width="3"/>
|
||||
<path d="M116.41 281.76 L512.00 510.16 L512.00 968.40 L296.20 843.81 L296.20 635.36 L116.41 531.55 Z" fill="url(#linear-gradient-4)"/><path d="M512.00 510.16 L709.80 395.96 L709.80 624.75 L907.59 510.55 L907.59 740.00 L512.00 968.40 Z" fill="url(#linear-gradient-3)"/><path d="M116.41 281.76 L512.00 53.36 L710.80 168.14 L512.28 282.75 L709.08 396.37 L512.00 510.16 Z" fill="url(#linear-gradient-5)"/>
|
||||
<path class="dep" d="M512.28 282.75 L709.80 168.71 L709.80 395.96 Z" fill="url(#linear-gradient-1)"/>
|
||||
<path class="dep" d="M709.80 395.96 L907.59 510.55 L709.80 624.75 Z" fill="url(#linear-gradient-2)"/>
|
||||
</g>
|
||||
<g class="stk s0"><path d="M116.41 281.76 L512.00 510.16 L512.00 968.40 L116.41 740.00 Z"/><path d="M512.00 510.16 L907.59 281.76 L907.59 740.00 L512.00 968.40 Z"/><path d="M116.41 281.76 L512.00 53.36 L907.59 281.76 L512.00 510.16 Z"/></g>
|
||||
<g class="stk s1k"><path d="M116.41 281.76 L512.00 510.16 L512.00 968.40 L296.20 843.81 L296.20 635.36 L116.41 531.55 Z"/><path d="M512.00 510.16 L907.59 281.76 L907.59 740.00 L512.00 968.40 Z"/><path d="M116.41 281.76 L512.00 53.36 L907.59 281.76 L512.00 510.16 Z"/></g>
|
||||
<g class="stk s3"><path d="M116.41 281.76 L512.00 510.16 L512.00 968.40 L296.20 843.81 L296.20 635.36 L116.41 531.55 Z"/><path d="M512.00 510.16 L709.80 395.96 L709.80 624.75 L907.59 510.55 L907.59 740.00 L512.00 968.40 Z"/><path d="M116.41 281.76 L512.00 53.36 L710.80 168.14 L512.28 282.75 L709.08 396.37 L512.00 510.16 Z"/><path d="M709.80 168.71 L709.80 395.96 L907.59 510.55"/></g>
|
||||
</g>
|
||||
<!-- the logo itself, with its gaps and its two depth faces, which replaces the touching cube once the cuts are done -->
|
||||
<g class="fin"><path d="M116.406 510.769 L116.406 303.529 L494 521.17 L494 957.8 L314.203 854.167 L314.203 624.777 Z" fill="url(#linear-gradient-4)"/><path d="M530 521.17 L691.797 427.912 L691.797 655.928 L907.594 531.545 L907.594 740.159 L530 957.8 Z" fill="url(#linear-gradient-3)"/><path d="M134.374 272.334 L512 53.364 L691.828 157.015 L476.117 282.846 L673.752 396.761 L512 489.993 Z" fill="url(#linear-gradient-5)"/><path d="M547.883 282.66 L709.797 188.211 L709.797 375.985 Z" fill="url(#linear-gradient-1)"/><path d="M727.797 593.626 L727.797 407.136 L889.571 500.381 Z" fill="url(#linear-gradient-2)"/></g>
|
||||
<g class="tl tL"><polygon class="pface" points="116.41,531.55 296.20,635.36 296.20,635.36 116.41,531.55"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.24;0.31;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="116.41,531.55 296.20,635.36 296.20,635.36 116.41,531.55;116.41,531.55 296.20,635.36 296.20,635.36 116.41,531.55;116.41,531.55 296.20,635.36 691.80,406.96 512.00,303.15;116.41,531.55 296.20,635.36 691.80,406.96 512.00,303.15"/></polygon><polygon class="pface" points="296.20,635.36 296.20,843.81 296.20,843.81 296.20,635.36"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.24;0.31;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="296.20,635.36 296.20,843.81 296.20,843.81 296.20,635.36;296.20,635.36 296.20,843.81 296.20,843.81 296.20,635.36;296.20,635.36 296.20,843.81 691.80,615.41 691.80,406.96;296.20,635.36 296.20,843.81 691.80,615.41 691.80,406.96"/></polygon><polygon class="pface" points="116.41,531.55 296.20,635.36 296.20,843.81 116.41,740.00"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.24;0.31;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="116.41,531.55 296.20,635.36 296.20,843.81 116.41,740.00;116.41,531.55 296.20,635.36 296.20,843.81 116.41,740.00;512.00,303.15 691.80,406.96 691.80,615.41 512.00,511.60;512.00,303.15 691.80,406.96 691.80,615.41 512.00,511.60"/></polygon><path class="ptop" d="M116.41 531.55 L296.20 635.36 L296.20 843.81 L116.41 740.00 Z"/></g>
|
||||
<g class="tl tP"><polygon class="pface" points="709.08,396.37 512.28,282.75 512.28,282.75 709.08,396.37"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.4;0.47;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="709.08,396.37 512.28,282.75 512.28,282.75 709.08,396.37;709.08,396.37 512.28,282.75 512.28,282.75 709.08,396.37;709.08,396.37 512.28,282.75 512.28,511.54 709.08,625.17;709.08,396.37 512.28,282.75 512.28,511.54 709.08,625.17"/></polygon><polygon class="pface" points="907.59,281.76 709.08,396.37 709.08,396.37 907.59,281.76"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.4;0.47;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="907.59,281.76 709.08,396.37 709.08,396.37 907.59,281.76;907.59,281.76 709.08,396.37 709.08,396.37 907.59,281.76;907.59,281.76 709.08,396.37 709.08,625.17 907.59,510.55;907.59,281.76 709.08,396.37 709.08,625.17 907.59,510.55"/></polygon><polygon class="pface" points="710.80,168.14 907.59,281.76 709.08,396.37 512.28,282.75"><animate attributeName="points" dur="5.4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.4;0.47;1" keySplines="0 0 1 1;.5 0 .35 1;0 0 1 1" values="710.80,168.14 907.59,281.76 709.08,396.37 512.28,282.75;710.80,168.14 907.59,281.76 709.08,396.37 512.28,282.75;710.80,396.93 907.59,510.55 709.08,625.17 512.28,511.54;710.80,396.93 907.59,510.55 709.08,625.17 512.28,511.54"/></polygon><path class="ptop" d="M710.80 168.14 L907.59 281.76 L709.08 396.37 L512.28 282.75 Z"/></g>
|
||||
<text class="word" x="512" y="1058" text-anchor="middle">SolidCraft</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -1,4 +1,7 @@
|
||||
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #e8ebf0; }
|
||||
#solidcraft_canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
|
||||
#solidcraft_loading { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
color: #4a5060; font: 14px system-ui, sans-serif; pointer-events: none; }
|
||||
color: #4a5060; font: 14px system-ui, sans-serif; background: #e8ebf0; z-index: 10; transition: opacity 300ms ease; }
|
||||
#solidcraft_loading.done { opacity: 0; pointer-events: none; }
|
||||
#solidcraft_loading img { width: min(60vmin, 360px); height: auto; }
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
||||
Reference in new issue
Block a user