90 lines
2.3 KiB
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>
|