Add 3d control buttons to linear mode (#8178)

Adds control buttons to the top left of the 3d preview in linear mode.
<img width="460" alt="image"
src="https://github.com/user-attachments/assets/35a83b9c-65af-46c3-a910-be5ad30c428e"
/>


This was deprioritized because I forgot the secret to magically
unwrapping a set of refs (wrap them in another ref).

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8178-Add-3d-control-buttons-to-linear-mode-2ee6d73d3650816ab1a8e73ace1bdbc7)
by [Unito](https://www.unito.io)
This commit is contained in:
AustinMroz
2026-01-23 19:24:48 -08:00
committed by GitHub
parent 1b1356951e
commit ef2d34c560
2 changed files with 27 additions and 11 deletions

View File

@@ -630,6 +630,10 @@ export const useLoad3dViewer = (node?: LGraphNode) => {
handleBackgroundImageUpdate,
handleModelDrop,
handleSeek,
cleanup
cleanup,
hasSkeleton: false,
intensity: lightIntensity,
showSkeleton: false
}
}

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { useTemplateRef, watch } from 'vue'
import { ref, useTemplateRef, watch } from 'vue'
import Load3DControls from '@/components/load3d/Load3DControls.vue'
import AnimationControls from '@/components/load3d/controls/AnimationControls.vue'
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
@@ -10,12 +11,12 @@ const { modelUrl } = defineProps<{
const containerRef = useTemplateRef('containerRef')
const viewer = useLoad3dViewer()
const viewer = ref(useLoad3dViewer())
watch([containerRef, () => modelUrl], async () => {
if (!containerRef.value || !modelUrl) return
await viewer.initializeStandaloneViewer(containerRef.value, modelUrl)
await viewer.value.initializeStandaloneViewer(containerRef.value, modelUrl)
})
//TODO: refactor to add control buttons
@@ -29,14 +30,25 @@ watch([containerRef, () => modelUrl], async () => {
@resize="viewer.handleResize"
>
<div class="pointer-events-none absolute top-0 left-0 size-full">
<Load3DControls
v-model:scene-config="viewer"
v-model:model-config="viewer"
v-model:camera-config="viewer"
v-model:light-config="viewer"
:is-splat-model="viewer.isSplatModel"
:is-ply-model="viewer.isPlyModel"
:has-skeleton="viewer.hasSkeleton"
@update-background-image="viewer.handleBackgroundImageUpdate"
@export-model="viewer.exportModel"
/>
<AnimationControls
v-if="viewer.animations.value && viewer.animations.value.length > 0"
v-model:animations="viewer.animations.value"
v-model:playing="viewer.playing.value"
v-model:selected-speed="viewer.selectedSpeed.value"
v-model:selected-animation="viewer.selectedAnimation.value"
v-model:animation-progress="viewer.animationProgress.value"
v-model:animation-duration="viewer.animationDuration.value"
v-if="viewer.animations && viewer.animations.length > 0"
v-model:animations="viewer.animations"
v-model:playing="viewer.playing"
v-model:selected-speed="viewer.selectedSpeed"
v-model:selected-animation="viewer.selectedAnimation"
v-model:animation-progress="viewer.animationProgress"
v-model:animation-duration="viewer.animationDuration"
@seek="viewer.handleSeek"
/>
</div>