mns
/
urna
forked from mns/mini-skamja
4
0
Fork 0
urna/components/model/scene.vue

90 lines
2.3 KiB
Vue

<script setup lang="ts">
import { Vector3 } from 'three'
const types = {
bench: defineAsyncComponent(() => import('./bench.vue')),
table: defineAsyncComponent(() => import('./bench-table.vue'))
}
const props = defineProps({
type: {
type: String as PropType<keyof typeof types>,
default: 'bench',
required: true
}
})
const camera = ref()
const controls = ref()
const controlsState = reactive({
minDistance: 2,
maxDistance: 20,
enablePan: false
// enableZoom: false,
// maxPolarAngle: Math.PI / 2 - 0.2
})
const toggleModal = () => {}
const changeDistance = (v = 1) => {
if (camera.value && controls.value) {
const distance = camera.value.position.distanceTo(new Vector3(0, 0, 0))
const r = distance + v
camera.value.position.normalize().multiplyScalar(r)
}
}
</script>
<template>
<div>
<div class="relative h-[600px] max-h-screen">
<ClientOnly fallback-tag="div">
<template #fallback>
<div class="fallback">Загрузка 3D модели</div>
</template>
<TresCanvas height="600" clear-color="#e2e8f0">
<TresPerspectiveCamera
:position="new Vector3(-7, 2, 4)"
ref="camera"
/>
<OrbitControls v-bind="controlsState" ref="controls" make-default />
<ModelEnv />
<Suspense>
<component :is="types[props.type]" />
</Suspense>
</TresCanvas>
<div class="canvas-icons">
<a
href="#"
@click.prevent="changeDistance(-0.5)"
:class="[
{
disabled: camera
? camera.position.distanceTo(new Vector3(0, 0, 0)) <= controlsState.minDistance
: null
}
]"
>
<Icon name="mdi:plus-circle-outline" />
</a>
<a
href="#"
@click.prevent="changeDistance(0.5)"
:class="[
{
disabled: camera
? camera.position.distanceTo(new Vector3(0, 0, 0)) >= controlsState.maxDistance
: null
}
]"
>
<Icon name="mdi:minus-circle-outline" />
</a>
</div>
</ClientOnly>
</div>
<button @click.prevent="toggleModal">Рассчитать</button>
</div>
</template>