mns-mini-zabor/components/expDiagram.vue

101 lines
3.7 KiB
Vue

<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'
import { Vector3 } from 'three';
const camera = ref()
const controls = ref()
const controlsState = reactive({
minDistance: 2,
maxDistance: 10,
enablePan: false,
// enableZoom: false,
maxPolarAngle: (Math.PI / 2) - 0.2,
})
const explosion_state = use_explosion_state()
const toggleExpState = () => {
explosion_state.value = !explosion_state.value
}
const back_light = ref()
const key_light = ref()
const secondary_light = ref()
const loadAll = async () => {
const { scene: back } = await useGLTF('/models_light/back_exp.glb')
const { scene: key } = await useGLTF('/models_light/key_exp.glb')
const { scene: secondary } = await useGLTF('/models_light/secondary_exp.glb')
const k = 0.001
back_light.value = back.children[0]
back_light.value.intensity = back_light.value.intensity * k
back_light.value.shadow.bias = -0.01
key_light.value = key.children[0]
key_light.value.intensity = key_light.value.intensity * k
key_light.value.shadow.bias = -0.01
key_light.value.cast_shadow = true
secondary_light.value = secondary.children[0]
secondary_light.value.intensity = secondary_light.value.intensity * k
secondary_light.value.shadow.bias = -0.01
}
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)
}
}
onMounted(() => {
loadAll()
})
</script>
<template>
<div class="h-96 relative">
<ClientOnly fallback-tag="div">
<template #fallback>
<div class="fallback">
Загрузка 3D модели
</div>
</template>
<TresCanvas height="600">
<TresPerspectiveCamera :position="[-7, 2, 4]" ref="camera" />
<OrbitControls v-bind="controlsState" ref="controls" make-default />
<Suspense>
<ModelDiagram />
</Suspense>
<TresPointLight v-bind="back_light" v-if="back_light"
:position="[back_light.position.x, back_light.position.y, back_light.position.z]" />
<TresPointLight v-bind="key_light" v-if="key_light"
:position="[key_light.position.x, key_light.position.y, key_light.position.z]" />
<TresPointLight v-bind="secondary_light" v-if="secondary_light"
:position="[secondary_light.position.x, secondary_light.position.y, secondary_light.position.z]" />
<!-- <TresAmbientLight :intensity="2" /> -->
</TresCanvas>
</ClientOnly>
<div class="canvas-icons">
<a href="#" @click.prevent="toggleExpState">
<Icon name="mdi:arrow-collapse-horizontal" v-if="explosion_state" />
<Icon name="mdi:arrow-expand-horizontal" v-else />
</a>
<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>
</div>
</template>
<style scoped>
.container {
height: 600px;
display: block;
}
</style>