dylanebert
commited on
Commit
·
0a9d77b
1
Parent(s):
3f9905a
ux improvements
Browse files- viewer/src/lib/data/scenes.json +2 -2
- viewer/src/routes/+page.svelte +7 -0
- viewer/src/routes/models/[slug]/+page.server.ts +0 -2
- viewer/src/routes/models/[slug]/+page.svelte +31 -17
- viewer/src/routes/viewer/[slug]/+page.server.ts +6 -2
- viewer/src/routes/viewer/[slug]/+page.svelte +19 -0
- viewer/static/global.css +15 -2
viewer/src/lib/data/scenes.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
"slug": "boombox",
|
| 4 |
-
"model": "
|
| 5 |
"title": "BoomBox",
|
| 6 |
"url": "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoomBox/glTF-Binary/BoomBox.glb"
|
| 7 |
},
|
|
@@ -13,7 +13,7 @@
|
|
| 13 |
},
|
| 14 |
{
|
| 15 |
"slug": "toycar",
|
| 16 |
-
"model": "
|
| 17 |
"title": "Toy Car",
|
| 18 |
"url": "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/ToyCar/glTF-Binary/ToyCar.glb"
|
| 19 |
}
|
|
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
"slug": "boombox",
|
| 4 |
+
"model": "",
|
| 5 |
"title": "BoomBox",
|
| 6 |
"url": "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoomBox/glTF-Binary/BoomBox.glb"
|
| 7 |
},
|
|
|
|
| 13 |
},
|
| 14 |
{
|
| 15 |
"slug": "toycar",
|
| 16 |
+
"model": "",
|
| 17 |
"title": "Toy Car",
|
| 18 |
"url": "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/ToyCar/glTF-Binary/ToyCar.glb"
|
| 19 |
}
|
viewer/src/routes/+page.svelte
CHANGED
|
@@ -2,8 +2,15 @@
|
|
| 2 |
import { activeTab } from "./store.js";
|
| 3 |
import ModelsView from "./components/ModelsView.svelte";
|
| 4 |
import ScenesView from "./components/ScenesView.svelte";
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
</script>
|
| 6 |
|
|
|
|
|
|
|
|
|
|
| 7 |
<div class="container">
|
| 8 |
<div class="tabs">
|
| 9 |
<button on:click={() => activeTab.set("Models")} class={$activeTab === "Models" ? "active" : ""}>Models</button>
|
|
|
|
| 2 |
import { activeTab } from "./store.js";
|
| 3 |
import ModelsView from "./components/ModelsView.svelte";
|
| 4 |
import ScenesView from "./components/ScenesView.svelte";
|
| 5 |
+
|
| 6 |
+
function goHome() {
|
| 7 |
+
window.location.href = "/";
|
| 8 |
+
}
|
| 9 |
</script>
|
| 10 |
|
| 11 |
+
<div class="banner">
|
| 12 |
+
<h1 on:pointerdown={goHome}>IGF</h1>
|
| 13 |
+
</div>
|
| 14 |
<div class="container">
|
| 15 |
<div class="tabs">
|
| 16 |
<button on:click={() => activeTab.set("Models")} class={$activeTab === "Models" ? "active" : ""}>Models</button>
|
viewer/src/routes/models/[slug]/+page.server.ts
CHANGED
|
@@ -8,8 +8,6 @@ export async function load({ params }) {
|
|
| 8 |
const model = models.find((model: any) => model.slug === params.slug);
|
| 9 |
const modelScenes = scenes.filter((scene: any) => scene.model === params.slug);
|
| 10 |
|
| 11 |
-
if (!modelScenes.length) throw error(404);
|
| 12 |
-
|
| 13 |
return {
|
| 14 |
model: model,
|
| 15 |
scenes: modelScenes
|
|
|
|
| 8 |
const model = models.find((model: any) => model.slug === params.slug);
|
| 9 |
const modelScenes = scenes.filter((scene: any) => scene.model === params.slug);
|
| 10 |
|
|
|
|
|
|
|
| 11 |
return {
|
| 12 |
model: model,
|
| 13 |
scenes: modelScenes
|
viewer/src/routes/models/[slug]/+page.svelte
CHANGED
|
@@ -19,14 +19,16 @@
|
|
| 19 |
image.src = placeholderImage;
|
| 20 |
}
|
| 21 |
|
| 22 |
-
function
|
| 23 |
-
window.
|
| 24 |
}
|
| 25 |
</script>
|
| 26 |
|
|
|
|
|
|
|
|
|
|
| 27 |
<div class="container">
|
| 28 |
<div class="header">{data.model.title}</div>
|
| 29 |
-
<div class="exit-button" on:pointerdown={exit}>x</div>
|
| 30 |
<div class="model-container">
|
| 31 |
<div class="model-info">
|
| 32 |
<p class="model-header">Info</p>
|
|
@@ -52,25 +54,30 @@
|
|
| 52 |
</table>
|
| 53 |
</div>
|
| 54 |
<div class="grid-container">
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
<
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
</div>
|
| 69 |
</div>
|
| 70 |
</div>
|
| 71 |
|
| 72 |
<style>
|
| 73 |
-
|
| 74 |
.model-header {
|
| 75 |
padding: 10px;
|
| 76 |
font-size: 16px;
|
|
@@ -164,4 +171,11 @@
|
|
| 164 |
width: calc(25% - 10px);
|
| 165 |
}
|
| 166 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
</style>
|
|
|
|
| 19 |
image.src = placeholderImage;
|
| 20 |
}
|
| 21 |
|
| 22 |
+
function goHome() {
|
| 23 |
+
window.location.href = "/";
|
| 24 |
}
|
| 25 |
</script>
|
| 26 |
|
| 27 |
+
<div class="banner">
|
| 28 |
+
<h1 on:pointerdown={goHome}>IGF</h1>
|
| 29 |
+
</div>
|
| 30 |
<div class="container">
|
| 31 |
<div class="header">{data.model.title}</div>
|
|
|
|
| 32 |
<div class="model-container">
|
| 33 |
<div class="model-info">
|
| 34 |
<p class="model-header">Info</p>
|
|
|
|
| 54 |
</table>
|
| 55 |
</div>
|
| 56 |
<div class="grid-container">
|
| 57 |
+
{#if data.scenes.length > 0}
|
| 58 |
+
<div class="grid">
|
| 59 |
+
{#each data.scenes as scene}
|
| 60 |
+
<a href={`/viewer/${scene.slug}`} class="grid-item">
|
| 61 |
+
<img
|
| 62 |
+
src={`/thumbnails/${scene.slug}.png`}
|
| 63 |
+
alt={scene.title}
|
| 64 |
+
class="thumbnail"
|
| 65 |
+
on:error={(event) => handleImageError(event)}
|
| 66 |
+
/>
|
| 67 |
+
<div class="title">{scene.title}</div>
|
| 68 |
+
</a>
|
| 69 |
+
{/each}
|
| 70 |
+
</div>
|
| 71 |
+
{:else}
|
| 72 |
+
<div class="grid">
|
| 73 |
+
<div class="warning">No scenes found</div>
|
| 74 |
+
</div>
|
| 75 |
+
{/if}
|
| 76 |
</div>
|
| 77 |
</div>
|
| 78 |
</div>
|
| 79 |
|
| 80 |
<style>
|
|
|
|
| 81 |
.model-header {
|
| 82 |
padding: 10px;
|
| 83 |
font-size: 16px;
|
|
|
|
| 171 |
width: calc(25% - 10px);
|
| 172 |
}
|
| 173 |
}
|
| 174 |
+
|
| 175 |
+
.warning {
|
| 176 |
+
width: 100%;
|
| 177 |
+
margin-top: 20px;
|
| 178 |
+
text-align: center;
|
| 179 |
+
color: #aaa;
|
| 180 |
+
}
|
| 181 |
</style>
|
viewer/src/routes/viewer/[slug]/+page.server.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
| 1 |
import { error } from "@sveltejs/kit";
|
| 2 |
-
import { getScenes } from "$lib/dataLoader";
|
| 3 |
|
| 4 |
export async function load({ params }) {
|
|
|
|
| 5 |
const scenes = await getScenes();
|
|
|
|
| 6 |
const scene = scenes.find((scene: any) => scene.slug === params.slug);
|
|
|
|
| 7 |
|
| 8 |
if (!scene) throw error(404);
|
| 9 |
|
| 10 |
return {
|
| 11 |
-
scene
|
|
|
|
| 12 |
};
|
| 13 |
}
|
|
|
|
| 1 |
import { error } from "@sveltejs/kit";
|
| 2 |
+
import { getModels, getScenes } from "$lib/dataLoader";
|
| 3 |
|
| 4 |
export async function load({ params }) {
|
| 5 |
+
const models = await getModels();
|
| 6 |
const scenes = await getScenes();
|
| 7 |
+
|
| 8 |
const scene = scenes.find((scene: any) => scene.slug === params.slug);
|
| 9 |
+
const model = models.find((model: any) => model.slug === scene!.model);
|
| 10 |
|
| 11 |
if (!scene) throw error(404);
|
| 12 |
|
| 13 |
return {
|
| 14 |
+
scene: scene,
|
| 15 |
+
model: model
|
| 16 |
};
|
| 17 |
}
|
viewer/src/routes/viewer/[slug]/+page.svelte
CHANGED
|
@@ -6,8 +6,12 @@
|
|
| 6 |
export let data: {
|
| 7 |
scene: {
|
| 8 |
title: string;
|
|
|
|
| 9 |
url: string;
|
| 10 |
};
|
|
|
|
|
|
|
|
|
|
| 11 |
};
|
| 12 |
|
| 13 |
let overlay: HTMLDivElement | null = null;
|
|
@@ -197,6 +201,16 @@
|
|
| 197 |
<div class="section">
|
| 198 |
<div class="title">{data.scene.title}</div>
|
| 199 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
<div class="section">
|
| 201 |
<div class="section-title">Stats</div>
|
| 202 |
<div class="info-panel">
|
|
@@ -336,6 +350,11 @@
|
|
| 336 |
padding: 4px;
|
| 337 |
}
|
| 338 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
.info-panel {
|
| 340 |
padding: 10px 10px 0px 10px;
|
| 341 |
color: #ddd;
|
|
|
|
| 6 |
export let data: {
|
| 7 |
scene: {
|
| 8 |
title: string;
|
| 9 |
+
model: string;
|
| 10 |
url: string;
|
| 11 |
};
|
| 12 |
+
model: {
|
| 13 |
+
title: string;
|
| 14 |
+
};
|
| 15 |
};
|
| 16 |
|
| 17 |
let overlay: HTMLDivElement | null = null;
|
|
|
|
| 201 |
<div class="section">
|
| 202 |
<div class="title">{data.scene.title}</div>
|
| 203 |
</div>
|
| 204 |
+
<div class="section">
|
| 205 |
+
<div class="section-title">Model</div>
|
| 206 |
+
<div class="info-panel">
|
| 207 |
+
{#if data.scene.model}
|
| 208 |
+
<a href={`/models/${data.scene.model}`} class="section-label">{data.model.title}</a>
|
| 209 |
+
{:else}
|
| 210 |
+
<div class="section-label">None</div>
|
| 211 |
+
{/if}
|
| 212 |
+
</div>
|
| 213 |
+
</div>
|
| 214 |
<div class="section">
|
| 215 |
<div class="section-title">Stats</div>
|
| 216 |
<div class="info-panel">
|
|
|
|
| 350 |
padding: 4px;
|
| 351 |
}
|
| 352 |
|
| 353 |
+
.section-label {
|
| 354 |
+
font-size: 14px;
|
| 355 |
+
color: #ddd;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
.info-panel {
|
| 359 |
padding: 10px 10px 0px 10px;
|
| 360 |
color: #ddd;
|
viewer/static/global.css
CHANGED
|
@@ -5,9 +5,22 @@ body {
|
|
| 5 |
color: white;
|
| 6 |
}
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
.container {
|
| 9 |
-
padding
|
| 10 |
-
padding-right: 15px;
|
| 11 |
margin-left: auto;
|
| 12 |
margin-right: auto;
|
| 13 |
max-height: 100vh;
|
|
|
|
| 5 |
color: white;
|
| 6 |
}
|
| 7 |
|
| 8 |
+
.banner {
|
| 9 |
+
width: 100%;
|
| 10 |
+
padding: 0 20px;
|
| 11 |
+
margin: 0;
|
| 12 |
+
border-bottom: 1px solid #333;
|
| 13 |
+
box-sizing: border-box;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.banner h1 {
|
| 17 |
+
padding: 0;
|
| 18 |
+
margin: 20px 0;
|
| 19 |
+
cursor: pointer;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
.container {
|
| 23 |
+
padding: 10px 15px 10px 15px;
|
|
|
|
| 24 |
margin-left: auto;
|
| 25 |
margin-right: auto;
|
| 26 |
max-height: 100vh;
|