bx-865-apps #1
|
@ -1,12 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { IMAGE_URL, SERVER_URL, } from '../../constants'
|
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
|
||||||
import { Box3, Vector2, Vector3 } from 'three';
|
import { Box3, Vector2, Vector3 } from 'three';
|
||||||
|
|
||||||
import { useTresContext, useSeek } from '@tresjs/core';
|
import { useTresContext, useSeek } from '@tresjs/core';
|
||||||
import { useGLTF } from '@tresjs/cientos'
|
import { useGLTF } from '@tresjs/cientos'
|
||||||
|
|
||||||
|
import { IMAGE_URL, SERVER_URL, } from '../../constants'
|
||||||
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
||||||
|
|
||||||
|
const props = defineProps(['source'])
|
||||||
|
|
||||||
const max_size = reactive({
|
const max_size = reactive({
|
||||||
x: 0, y: 0, z: 0
|
x: 0, y: 0, z: 0
|
||||||
})
|
})
|
||||||
|
@ -22,13 +24,17 @@ function shadows_and_pos(scene: any) {
|
||||||
const models = ref<model3DType[]>([])
|
const models = ref<model3DType[]>([])
|
||||||
const clickable = ref<clickableAreaType[]>([])
|
const clickable = ref<clickableAreaType[]>([])
|
||||||
const clickable_objects = ref<any[]>([])
|
const clickable_objects = ref<any[]>([])
|
||||||
const { controls, raycaster, camera, scene } = useTresContext()
|
const { controls, raycaster, camera, scene, renderer } = useTresContext()
|
||||||
const { seekByName } = useSeek()
|
const { seekByName } = useSeek()
|
||||||
const sidebar = usePromoSidebar()
|
const sidebar = usePromoSidebar()
|
||||||
|
|
||||||
const loadModels = async () => {
|
const loadModels = async () => {
|
||||||
const res = await fetch(`${SERVER_URL}/api/obj/element/?parent__isnull=True`)
|
const res = await fetch(`${SERVER_URL}/api/obj/element/${props.source}`)
|
||||||
const data = await res.json() as element3DType[]
|
const raw_data = await res.json() as element3DType[] | element3DType
|
||||||
|
let data = raw_data as element3DType[]
|
||||||
|
if (props.source.endsWith('/')) {
|
||||||
|
data = [raw_data] as element3DType[]
|
||||||
|
}
|
||||||
if (!controls.value) return
|
if (!controls.value) return
|
||||||
const c = (controls.value as any)
|
const c = (controls.value as any)
|
||||||
const distance = {
|
const distance = {
|
||||||
|
@ -107,9 +113,16 @@ const clickEvent = (event: MouseEvent) => {
|
||||||
}
|
}
|
||||||
console.timeEnd('raycaster')
|
console.timeEnd('raycaster')
|
||||||
}
|
}
|
||||||
|
watch(() => props.source, () => {
|
||||||
|
const loaded = seekByName(scene.value, 'loaded')
|
||||||
|
if (loaded) {
|
||||||
|
scene.value.remove(loaded)
|
||||||
|
}
|
||||||
|
loadModels()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<TresGroup v-for="item in models">
|
<TresGroup v-for="item in models" name="loaded">
|
||||||
<TresObject3D v-bind="item.modelFile.clone()" />
|
<TresObject3D v-bind="item.modelFile.clone()" />
|
||||||
</TresGroup>
|
</TresGroup>
|
||||||
</template>
|
</template>
|
|
@ -1,8 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref, watch } from 'vue';
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { Vector3 } from 'three';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import { Vector3 } from 'three';
|
||||||
import { TresCanvas } from '@tresjs/core';
|
import { TresCanvas } from '@tresjs/core';
|
||||||
import { CameraControls, useProgress, StatsGl } from '@tresjs/cientos'
|
import { CameraControls, useProgress, StatsGl } from '@tresjs/cientos'
|
||||||
|
|
||||||
|
@ -34,6 +35,15 @@ const point_light = reactive({
|
||||||
position: new Vector3(-100, 50, 5),
|
position: new Vector3(-100, 50, 5),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const source = ref(route.params.target ? (route.params.target.toString() + '/') : '?parent__isnull=True')
|
||||||
|
watch(() => route.params.target, () => {
|
||||||
|
let t = '?parent__isnull=True'
|
||||||
|
if (route.params.target) t = route.params.target.toString() + '/'
|
||||||
|
if (source.value !== t) {
|
||||||
|
source.value = t
|
||||||
|
}
|
||||||
|
}, { deep: true })
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
@ -51,7 +61,7 @@ const point_light = reactive({
|
||||||
<Env />
|
<Env />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<LoadModels />
|
<LoadModels :source="source" />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<TresMesh cast-shadow>
|
<TresMesh cast-shadow>
|
||||||
<TresBoxGeometry :args="[1, 1, 1]" />
|
<TresBoxGeometry :args="[1, 1, 1]" />
|
||||||
|
@ -64,7 +74,7 @@ const point_light = reactive({
|
||||||
<TresPointLight v-bind="point_light" cast-shadow />
|
<TresPointLight v-bind="point_light" cast-shadow />
|
||||||
</TresCanvas>
|
</TresCanvas>
|
||||||
</div>
|
</div>
|
||||||
<Sidebar/>
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -79,5 +89,4 @@ const point_light = reactive({
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { RouterLink } from 'vue-router';
|
||||||
import { onClickOutside } from '@vueuse/core'
|
import { onClickOutside } from '@vueuse/core'
|
||||||
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
||||||
|
|
||||||
|
@ -18,6 +19,9 @@ onClickOutside(sidebar_obj, () => sidebar.close())
|
||||||
<template v-for="p in sidebar.description.split('\n')">
|
<template v-for="p in sidebar.description.split('\n')">
|
||||||
<p>{{ p }}</p>
|
<p>{{ p }}</p>
|
||||||
</template>
|
</template>
|
||||||
|
<RouterLink :to="`/promo/main/${sidebar.target}`" v-if="sidebar.target">
|
||||||
|
Перейти на темную сторону
|
||||||
|
</RouterLink>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -31,14 +31,12 @@ interface clickableAreaType {
|
||||||
source: number;
|
source: number;
|
||||||
target: number;
|
target: number;
|
||||||
}
|
}
|
||||||
interface PromoSidebar {
|
|
||||||
title: string
|
|
||||||
description: string
|
|
||||||
loading: boolean
|
|
||||||
is_open: boolean
|
|
||||||
}
|
|
||||||
interface PromoSidebarData {
|
interface PromoSidebarData {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
target?: string
|
target?: string
|
||||||
}
|
}
|
||||||
|
interface PromoSidebar extends PromoSidebarData {
|
||||||
|
loading: boolean
|
||||||
|
is_open: boolean
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ const routes = [
|
||||||
{ path: '/floorplan/:id', component: FloorplanItem },
|
{ path: '/floorplan/:id', component: FloorplanItem },
|
||||||
{ path: '/promo', component: Promo },
|
{ path: '/promo', component: Promo },
|
||||||
{ path: '/promo/:page', component: PromoMain },
|
{ path: '/promo/:page', component: PromoMain },
|
||||||
|
{ path: '/promo/:page/:target', component: PromoMain },
|
||||||
{ path: '/promo/:page/item/:name', component: PromoItem },
|
{ path: '/promo/:page/item/:name', component: PromoItem },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ export const usePromoSidebar = defineStore('promo_sidebar', {
|
||||||
return {
|
return {
|
||||||
title: 'Сайдбар',
|
title: 'Сайдбар',
|
||||||
description: 'Описание',
|
description: 'Описание',
|
||||||
|
target: undefined,
|
||||||
loading: true,
|
loading: true,
|
||||||
is_open: false
|
is_open: false
|
||||||
} as PromoSidebar
|
} as PromoSidebar
|
||||||
|
@ -15,9 +16,7 @@ export const usePromoSidebar = defineStore('promo_sidebar', {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
},
|
},
|
||||||
setData(data: PromoSidebarData) {
|
setData(data: PromoSidebarData) {
|
||||||
const { title, description } = data
|
this.$state = Object.assign(this.$state, data)
|
||||||
this.title = title
|
|
||||||
this.description = description
|
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$reset()
|
this.$reset()
|
||||||
|
|
Loading…
Reference in New Issue