From 1051e066affb285770d6c8e87d1dc600a7dd65ca Mon Sep 17 00:00:00 2001 From: Diego Marcos Segura Date: Mon, 2 Jun 2025 02:55:51 -0700 Subject: [PATCH] Simplify viewer. Move old one to editor --- examples/editor/index.html | 695 ++++++++++++++++++++++ examples/viewer/download.svg | 3 + examples/viewer/forge-logo.svg | 4 + examples/viewer/forge-viewer.svg | 17 + examples/viewer/index.html | 956 ++++++++++--------------------- examples/viewer/upload-icon.svg | 3 + index.html | 1 + 7 files changed, 1037 insertions(+), 642 deletions(-) create mode 100644 examples/editor/index.html create mode 100644 examples/viewer/download.svg create mode 100644 examples/viewer/forge-logo.svg create mode 100644 examples/viewer/forge-viewer.svg create mode 100644 examples/viewer/upload-icon.svg diff --git a/examples/editor/index.html b/examples/editor/index.html new file mode 100644 index 0000000..5473bda --- /dev/null +++ b/examples/editor/index.html @@ -0,0 +1,695 @@ + + + + + Forge • Viewer + + + + +
+
+
+ + +
+
+ + + + + diff --git a/examples/viewer/download.svg b/examples/viewer/download.svg new file mode 100644 index 0000000..476bab7 --- /dev/null +++ b/examples/viewer/download.svg @@ -0,0 +1,3 @@ + + + diff --git a/examples/viewer/forge-logo.svg b/examples/viewer/forge-logo.svg new file mode 100644 index 0000000..bf2d187 --- /dev/null +++ b/examples/viewer/forge-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/examples/viewer/forge-viewer.svg b/examples/viewer/forge-viewer.svg new file mode 100644 index 0000000..74bd015 --- /dev/null +++ b/examples/viewer/forge-viewer.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/viewer/index.html b/examples/viewer/index.html index ffc676c..6f6cf4e 100644 --- a/examples/viewer/index.html +++ b/examples/viewer/index.html @@ -1,694 +1,366 @@ - + - + + Forge • Viewer - -
-
-
- -
-
- - + // Handle drag and drop files. + const dropZoneEl = document.querySelector('.drop-zone'); + const onDragover = function (e) { + e.preventDefault(); + dropZoneEl.classList.add('dragover'); + }; + const onDragLeave = function () { + dropZoneEl.classList.remove('dragover'); + }; + const onDrop = function (e) { + e.preventDefault(); + dropZoneEl.classList.remove('dragover'); + dropZoneEl.classList.add('drop'); + + const files = e.dataTransfer.files; + if (files.length > 0) { + loadSplatFile(files[0]); + } + }; + + dropZoneEl.addEventListener('dragover', onDragover); + forgeCanvasEl.addEventListener('dragover', onDragover); + + dropZoneEl.addEventListener('dragleave', onDragLeave); + forgeCanvasEl.addEventListener('dragleave', onDragLeave); + + dropZoneEl.addEventListener('drop', onDrop); + forgeCanvasEl.addEventListener('drop', onDrop); + + const fileInput = document.querySelector('#file-input'); + fileInput.onchange = function(event) { + loadSplatFile(event.target.files[0]); + }; + + var loadedSplat; + async function loadSplatFile(splatFile) { + const reader = new FileReader(); + fileBytes = new Uint8Array(await splatFile.arrayBuffer()); + fileName = splatFile.name; + + if (loadedSplat) { scene.remove(loadedSplat); } + + loadedSplat = new SplatMesh({ fileBytes: fileBytes.slice(), fileName }); + loadedSplat.quaternion.set(1, 0, 0, 0); + scene.add(loadedSplat); + + document.querySelector('.container').classList.add('hidden'); + document.querySelector('.canvas-container').classList.remove('invisible'); + } + + let params = new URLSearchParams(document.location.search); + let splatURL = params.get("url"); + + if (splatURL) { loadSplatURL(splatURL); } + + + function loadSplatURL(splatURL) { + fileName = splatURL.split("/").pop().split("?")[0]; + document.querySelector('.container').classList.add('hidden'); + document.querySelector('.canvas-container').classList.remove('invisible'); + fetch(splatURL) + .then(res => res.blob()) + .then(blob => { + loadSplatFile(blob); + }) + .catch(err => console.error('Download failed:', err)); + } + + const urlFormEl = document.querySelector('.url-form'); + const urlInputEl = document.querySelector('.url-input'); + urlFormEl.addEventListener('submit', function handleEnterKey(event) { + event.preventDefault(); + const url = new URL(window.location); + debugger; + const splatURL = urlInputEl.value; + loadSplatURL(urlInputEl.value); + url.searchParams.set('url', splatURL); + history.pushState(null, '', url); + }); + + document.querySelector('.spz-button').addEventListener('click', async function () { + debugger; + const fileInfo = { + fileBytes: fileBytes, + pathOrUrl: fileName, + transform: { + translate: loadedSplat.position.toArray(), + quaternion: loadedSplat.quaternion.toArray(), + scale: (loadedSplat.scale.x + loadedSplat.y + loadedSplat.z) / 3 + }, + }; + + const transcodeInfo = { + inputs: [fileInfo], + maxSh: 3, + fractionalBits: 12, + opacityThreshold: 0 + }; + const transcode = await transcodeSpz(transcodeInfo); + const blob = new Blob([transcode.fileBytes], { type: "application/octet-stream" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = fileName.split(".")[0] + ".spz"; + a.click(); + URL.revokeObjectURL(url); + }); + + +
+
+ +
Drag and drop a splat file here
+ + +
+ +
+
+
+ diff --git a/examples/viewer/upload-icon.svg b/examples/viewer/upload-icon.svg new file mode 100644 index 0000000..89721e2 --- /dev/null +++ b/examples/viewer/upload-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/index.html b/index.html index bdb20e8..7fde60a 100644 --- a/index.html +++ b/index.html @@ -142,6 +142,7 @@
  • Dynamic Lighting
  • Particle Animation
  • Particle Simulation
  • +
  • Editor
  • Viewer