add STL viewer via three.js, change output format to es
parent
4831d6b027
commit
5ff91af98e
6
Makefile
6
Makefile
|
@ -1,6 +1,6 @@
|
|||
all: package
|
||||
|
||||
package: target/release/upend ui/public/build/bundle.js
|
||||
package: target/release/upend ui/public/build/main.js
|
||||
rm -fr dist
|
||||
linuxdeploy-x86_64.AppImage --appdir dist
|
||||
cp target/release/upend dist/usr/bin/upend
|
||||
|
@ -17,9 +17,9 @@ target/release/upend:
|
|||
tools/upend_js/index.js:
|
||||
cd tools/upend_js && yarn install && yarn build
|
||||
|
||||
frontend: ui/public/build/bundle.js
|
||||
frontend: ui/public/build/main.js
|
||||
|
||||
ui/public/build/bundle.js: tools/upend_js/index.js
|
||||
ui/public/build/main.js: tools/upend_js/index.js
|
||||
cd ui && yarn add ../tools/upend_js && yarn install && yarn build
|
||||
|
||||
lint: backend_lint frontend_lint
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"@types/history": "^4.7.9",
|
||||
"@types/lodash": "^4.14.178",
|
||||
"@types/lru-cache": "^5.1.1",
|
||||
"@types/three": "^0.135.0",
|
||||
"@yarnpkg/fslib": "^2.6.0",
|
||||
"@yarnpkg/libzip": "^2.2.2",
|
||||
"postcss": "^8.3.11",
|
||||
|
@ -47,6 +48,7 @@
|
|||
"sirv-cli": "^1.0.0",
|
||||
"sswr": "^1.3.1",
|
||||
"svelte-navigator": "^3.1.5",
|
||||
"three": "^0.136.0",
|
||||
"upend": "../tools/upend_js"
|
||||
},
|
||||
"packageManager": "yarn@3.1.0"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<link rel="icon" type="image/png" href="/assets/upend.svg" />
|
||||
<link rel="stylesheet" href="/build/bundle.css" />
|
||||
|
||||
<script defer src="/build/bundle.js"></script>
|
||||
<script type="module" src="/build/main.js"></script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
|
|
@ -17,9 +17,9 @@ export default {
|
|||
input: "src/main.ts",
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: "iife",
|
||||
format: "esm",
|
||||
name: "app",
|
||||
file: "public/build/bundle.js",
|
||||
dir: "public/build",
|
||||
},
|
||||
plugins: [
|
||||
// To fix `history`
|
||||
|
@ -62,18 +62,14 @@ export default {
|
|||
targets: [
|
||||
{
|
||||
src: path.join(
|
||||
path.dirname(
|
||||
require.resolve("boxicons/package.json")
|
||||
),
|
||||
path.dirname(require.resolve("boxicons/package.json")),
|
||||
"fonts"
|
||||
),
|
||||
dest: path.resolve(__dirname, "public/vendor/boxicons"),
|
||||
},
|
||||
{
|
||||
src: path.join(
|
||||
path.dirname(
|
||||
require.resolve("boxicons/package.json")
|
||||
),
|
||||
path.dirname(require.resolve("boxicons/package.json")),
|
||||
"css"
|
||||
),
|
||||
dest: path.resolve(__dirname, "public/vendor/boxicons"),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { useEntity } from "../../lib/entity";
|
||||
import ModelViewer from "./blobs/ModelViewer.svelte";
|
||||
export let address: string;
|
||||
|
||||
$: ({ entity } = useEntity(address));
|
||||
|
@ -13,13 +14,21 @@
|
|||
{/if}
|
||||
{#if mimeType?.startsWith("video")}
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<video controls preload="auto" src="/api/raw/{address}" poster="/api/thumb/{address}" />
|
||||
<video
|
||||
controls
|
||||
preload="auto"
|
||||
src="/api/raw/{address}"
|
||||
poster="/api/thumb/{address}"
|
||||
/>
|
||||
{/if}
|
||||
{#if mimeType?.startsWith("image")}
|
||||
<a target="_blank" href="/api/raw/{address}">
|
||||
<img src="/api/raw/{address}" alt={address} />
|
||||
</a>
|
||||
{/if}
|
||||
{#if mimeType?.startsWith("model")}
|
||||
<ModelViewer src="/api/raw/{address}" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<script lang="ts">
|
||||
export let src: string;
|
||||
|
||||
import { onMount } from "svelte";
|
||||
let root: HTMLElement;
|
||||
|
||||
onMount(async () => {
|
||||
root.style.height = `${root.clientWidth}px`;
|
||||
|
||||
const THREE = await import("three/src/Three");
|
||||
const THREE_OC = await import("three/examples/jsm/controls/OrbitControls");
|
||||
const THREE_STL = await import("three/examples/jsm/loaders/STLLoader");
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
70,
|
||||
root.clientWidth / root.clientHeight
|
||||
);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
renderer.setSize(root.clientWidth, root.clientHeight);
|
||||
root.appendChild(renderer.domElement);
|
||||
|
||||
const controls = new THREE_OC.OrbitControls(camera, renderer.domElement);
|
||||
controls.enableDamping = true;
|
||||
controls.dampingFactor = 0.1;
|
||||
controls.enableZoom = true;
|
||||
controls.autoRotate = true;
|
||||
controls.autoRotateSpeed = 3;
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.add(new THREE.HemisphereLight(0xffffff, 1.5));
|
||||
|
||||
const loader = new THREE_STL.STLLoader();
|
||||
loader.load(src, (geometry) => {
|
||||
const material = new THREE.MeshPhongMaterial({
|
||||
color: 0xdc322f,
|
||||
specular: 100,
|
||||
shininess: 70,
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
scene.add(mesh);
|
||||
|
||||
const middle = new THREE.Vector3();
|
||||
geometry.computeBoundingBox();
|
||||
geometry.boundingBox.getCenter(middle);
|
||||
mesh.geometry.applyMatrix4(
|
||||
new THREE.Matrix4().makeTranslation(-middle.x, -middle.y, -middle.z)
|
||||
);
|
||||
|
||||
const largestDimension = Math.max(
|
||||
geometry.boundingBox.max.x,
|
||||
geometry.boundingBox.max.y,
|
||||
geometry.boundingBox.max.z
|
||||
);
|
||||
camera.position.z = largestDimension * 2;
|
||||
});
|
||||
|
||||
function animate() {
|
||||
controls.update();
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
animate();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="modelviewer" bind:this={root} />
|
||||
|
||||
<style>
|
||||
.modelviewer {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
20
ui/yarn.lock
20
ui/yarn.lock
|
@ -355,6 +355,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/three@npm:^0.135.0":
|
||||
version: 0.135.0
|
||||
resolution: "@types/three@npm:0.135.0"
|
||||
checksum: 85977e55cc3d7a14be88816a50bcec4eb0f141876d3cdc6dd7870f72122605af87462d7583e950cd0ee6ab21949b8c1b8304a88174d536648deb8ef97968fa1b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@ungap/event-target@npm:^0.2.2":
|
||||
version: 0.2.3
|
||||
resolution: "@ungap/event-target@npm:0.2.3"
|
||||
|
@ -3164,6 +3171,7 @@ __metadata:
|
|||
"@types/history": ^4.7.9
|
||||
"@types/lodash": ^4.14.178
|
||||
"@types/lru-cache": ^5.1.1
|
||||
"@types/three": ^0.135.0
|
||||
"@yarnpkg/fslib": ^2.6.0
|
||||
"@yarnpkg/libzip": ^2.2.2
|
||||
boxicons: ^2.1.1
|
||||
|
@ -3189,6 +3197,7 @@ __metadata:
|
|||
svelte-check: ^2.0.0
|
||||
svelte-navigator: ^3.1.5
|
||||
svelte-preprocess: ^4.0.0
|
||||
three: ^0.136.0
|
||||
tslib: ^2.0.0
|
||||
typescript: ^4.0.0
|
||||
upend: ../tools/upend_js
|
||||
|
@ -3332,6 +3341,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"three@npm:^0.136.0":
|
||||
version: 0.136.0
|
||||
resolution: "three@npm:0.136.0"
|
||||
checksum: 9183f83a75901edb85034fe8f6d52bf6daaece554e40d42f8eef5dead13a09e5f67548ee7cccd6c34bde42a91c5e8fa2ccb4a1b80783d7986bda4ec9f58bfe7f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"time-zone@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "time-zone@npm:2.0.0"
|
||||
|
@ -3458,8 +3474,8 @@ __metadata:
|
|||
|
||||
"upend@file:../tools/upend_js::locator=svelte-app%40workspace%3A.":
|
||||
version: 0.0.1
|
||||
resolution: "upend@file:../tools/upend_js#../tools/upend_js::hash=53bc72&locator=svelte-app%40workspace%3A."
|
||||
checksum: 1f9fed7b3499fd485712648a711b2cfc2ad1a435d69dbc96ddd57ba866e2cac19524e0300a412d8356a51de5f0a9f69fed929c6c702fce0cb9708d4ad2a9623e
|
||||
resolution: "upend@file:../tools/upend_js#../tools/upend_js::hash=a954aa&locator=svelte-app%40workspace%3A."
|
||||
checksum: 1b0605428365b2a672cb119e795292102f80171f03efec8290a5811b1514107455557a21157e7376aa7dcb7285484fd1db791d6d876893ec92f1794a0f61120f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in New Issue