File size: 3,500 Bytes
31a2d08
 
 
 
62c50cd
31a2d08
 
 
 
 
 
 
 
 
 
 
 
 
c99cc8d
 
31a2d08
 
 
 
c99cc8d
 
 
 
31a2d08
 
 
c99cc8d
31a2d08
 
 
 
c99cc8d
62c50cd
 
c99cc8d
31a2d08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c99cc8d
 
 
 
31a2d08
 
 
 
 
 
 
5743069
31a2d08
 
 
 
 
5743069
31a2d08
 
c99cc8d
 
 
 
 
62c50cd
e7b5357
 
 
 
 
62c50cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31a2d08
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<script lang="ts">
    import { onMount, onDestroy } from "svelte";
    import type { IViewer } from "./viewers/IViewer";
    import { createViewer } from "./viewers/ViewerFactory";
    import { ArrowLeft, Cube, WatsonHealth3DPrintMesh } from "carbon-icons-svelte";

    interface Scene {
        name: string;
        url: string;
        thumbnail: string;
    }

    export let modelName: string;
    export let scene: Scene;
    export let onBack: () => void;

    let container: HTMLDivElement;
    let canvas: HTMLCanvasElement;
    let overlay: HTMLDivElement;
    let loadingBarFill: HTMLDivElement;

    let viewer: IViewer;

    async function loadScene() {
        overlay.style.display = "flex";
        viewer = await createViewer(scene.url, canvas, (progress) => {
            loadingBarFill.style.width = `${progress * 100}%`;
        });
        window.addEventListener("resize", handleResize);
        window.addEventListener("keydown", handleKeyDown);
        handleResize();
        overlay.style.display = "none";
    }

    function handleResize() {
        if (!canvas || !container) return;
        requestAnimationFrame(() => {
            canvas.width = container.clientWidth;
            canvas.height = container.clientHeight;
        });
    }

    function handleKeyDown(e: KeyboardEvent) {
        if (e.code === "KeyP") {
            capture();
        }
    }

    async function capture() {
        const data = await viewer.capture();
        if (!data) {
            console.error("Failed to capture screenshot");
            return;
        }
        const a = document.createElement("a");
        a.href = data;
        a.download = "screenshot.png";
        a.click();
    }

    onMount(loadScene);

    onDestroy(() => {
        viewer?.dispose();
        if (typeof window !== "undefined") {
            window.removeEventListener("resize", handleResize);
            window.removeEventListener("keydown", handleKeyDown);
        }
    });
</script>

<div class="header">
    <div class="back" aria-label="Back" aria-hidden="true" on:click={onBack}>
        <ArrowLeft size={24} />
    </div>
    <div class="spacer" />
    <button class="title-button" on:click={loadScene}>
        <!-- svelte-ignore a11y-click-events-have-key-events -->
        <!-- svelte-ignore a11y-no-static-element-interactions -->
        <h2><span class="muted" on:click={onBack}>{modelName}/</span>{scene.name}</h2>
    </button>
    <div class="desktop-spacer" />
</div>
<div class="canvas-container" bind:this={container}>
    <div bind:this={overlay} class="loading-overlay">
        <div class="loading-bar">
            <div bind:this={loadingBarFill} class="loading-bar-fill" />
        </div>
    </div>
    <canvas class="viewer-canvas" bind:this={canvas} width={800} height={600}> </canvas>
    <div class="stats">
        {#if viewer}
            <p>vertex count: {viewer.vertexCount}</p>
        {/if}
    </div>
    <div class="mode-toggle">
        <label>
            <input
                type="radio"
                name="modeB"
                value="default"
                checked
                on:change={() => viewer.setRenderMode("default")}
            />
            <Cube class="mode-toggle-icon" />
        </label>
        <label>
            <input type="radio" name="modeB" value="wireframe" on:change={() => viewer.setRenderMode("wireframe")} />
            <WatsonHealth3DPrintMesh class="mode-toggle-icon" />
        </label>
    </div>
</div>