bx-1379-redesign #15
|
@ -55,9 +55,6 @@ $boxShadow: 0px 0px 8px rgba(0, 0, 0, .25);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
max-height: 50vh;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
background-color: $bg;
|
background-color: $bg;
|
||||||
border-top-left-radius: 0.5rem;
|
border-top-left-radius: 0.5rem;
|
||||||
border-bottom-left-radius: 0.5rem;
|
border-bottom-left-radius: 0.5rem;
|
||||||
|
@ -70,6 +67,7 @@ $boxShadow: 0px 0px 8px rgba(0, 0, 0, .25);
|
||||||
padding: 1.125rem 1rem;
|
padding: 1.125rem 1rem;
|
||||||
border-bottom: 2px solid var(--primary-color);
|
border-bottom: 2px solid var(--primary-color);
|
||||||
max-height: 4rem;
|
max-height: 4rem;
|
||||||
|
overflow: hidden;
|
||||||
transition: max-height 300ms linear;
|
transition: max-height 300ms linear;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
|
|
@ -93,9 +93,12 @@ const loadModels = async () => {
|
||||||
(controls.value as any)._needsUpdate = true;
|
(controls.value as any)._needsUpdate = true;
|
||||||
(controls.value as any).update()
|
(controls.value as any).update()
|
||||||
|
|
||||||
const sidebar_items = [] as PromoScene[]
|
const sidebar_clickable = [] as PromoScene[]
|
||||||
|
const sidebar_visible = [] as PromoScene[]
|
||||||
clickable_items.value = []
|
clickable_items.value = []
|
||||||
|
|
||||||
|
sidebar_scene.setName({ name: raw_data.name, description: raw_data.name })
|
||||||
|
|
||||||
loading_store.status = 'model'
|
loading_store.status = 'model'
|
||||||
for (let index = 0; index < data.length; index++) {
|
for (let index = 0; index < data.length; index++) {
|
||||||
loading_store.count = index
|
loading_store.count = index
|
||||||
|
@ -105,6 +108,7 @@ const loadModels = async () => {
|
||||||
item.modelUrl = `${IMAGE_URL}/${element.model_file}`
|
item.modelUrl = `${IMAGE_URL}/${element.model_file}`
|
||||||
let { scene: loaded_scene } = await useGLTF(item.modelUrl)
|
let { scene: loaded_scene } = await useGLTF(item.modelUrl)
|
||||||
item.modelFile = loaded_scene
|
item.modelFile = loaded_scene
|
||||||
|
item.id = element.id
|
||||||
item.name = element.name
|
item.name = element.name
|
||||||
|
|
||||||
if (!element.is_enabled) {
|
if (!element.is_enabled) {
|
||||||
|
@ -126,7 +130,12 @@ const loadModels = async () => {
|
||||||
const res = await fetch(`${SERVER_URL}/api/obj/clickable/?source=${element.id}`)
|
const res = await fetch(`${SERVER_URL}/api/obj/clickable/?source=${element.id}`)
|
||||||
const clickable_areas = await res.json()
|
const clickable_areas = await res.json()
|
||||||
clickable.list.push(...clickable_areas)
|
clickable.list.push(...clickable_areas)
|
||||||
|
|
||||||
|
if (!element.can_not_disable) {
|
||||||
|
sidebar_visible.push(element)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
sidebar_scene.setVisible(sidebar_visible)
|
||||||
|
|
||||||
let c = new Color()
|
let c = new Color()
|
||||||
if (envVars.clear_color) {
|
if (envVars.clear_color) {
|
||||||
|
@ -195,15 +204,15 @@ const loadModels = async () => {
|
||||||
clickable_items.value.push(point)
|
clickable_items.value.push(point)
|
||||||
clickable_refs.value.push(ref(`${element.id}_clickable`))
|
clickable_refs.value.push(ref(`${element.id}_clickable`))
|
||||||
|
|
||||||
sidebar_items.push({
|
sidebar_clickable.push({
|
||||||
|
is_enabled: true,
|
||||||
id: element.id,
|
id: element.id,
|
||||||
name: element.name
|
name: element.name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebar_scene.name = raw_data.name;
|
sidebar_scene.setClickable(sidebar_clickable)
|
||||||
sidebar_scene.setData(sidebar_items)
|
|
||||||
|
|
||||||
loading_store.status = 'boxes'
|
loading_store.status = 'boxes'
|
||||||
const box = new Box3();
|
const box = new Box3();
|
||||||
|
@ -385,7 +394,8 @@ onUnmounted(() => {
|
||||||
<Env v-bind="envVars" />
|
<Env v-bind="envVars" />
|
||||||
<!-- <PostProcessing /> -->
|
<!-- <PostProcessing /> -->
|
||||||
<template v-for="item in models">
|
<template v-for="item in models">
|
||||||
<TresGroup :name="item.name">
|
<TresGroup :name="item.name"
|
||||||
|
:visible="sidebar_scene.visible.find(el => el.id == item.id) ? sidebar_scene.visible.find(el => el.id == item.id).is_enabled : true">
|
||||||
<TresObject3D v-bind="item.modelFile.clone()" />
|
<TresObject3D v-bind="item.modelFile.clone()" />
|
||||||
</TresGroup>
|
</TresGroup>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,8 +8,6 @@ const sidebar = usePromoSidebar()
|
||||||
const sidebar_scene = usePromoScene()
|
const sidebar_scene = usePromoScene()
|
||||||
const sidebar_obj = ref()
|
const sidebar_obj = ref()
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const opened_desc = ref()
|
const opened_desc = ref()
|
||||||
|
|
||||||
const openedChange = () => {
|
const openedChange = () => {
|
||||||
|
@ -46,16 +44,23 @@ const toggleAccordion = (name: string) => {
|
||||||
<i-mdi-plus-circle v-else />
|
<i-mdi-plus-circle v-else />
|
||||||
<h3>Объекты</h3>
|
<h3>Объекты</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-accordion-content" v-if="open_accordions.includes('obj')">
|
||||||
|
<div class="sidebar-list-item" v-for="item in sidebar_scene.visible">
|
||||||
|
<input type="checkbox" v-model=item.is_enabled :value="item.id" :id="item.id.toString()" />
|
||||||
|
<label :for="item.id.toString()">{{ item.name }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-accordion" :class="[{ 'open': open_accordions.includes('desc') }]">
|
</div>
|
||||||
<div class="sidebar-accordion-title" @click="toggleAccordion('desc')">
|
</div>
|
||||||
<i-mdi-minus-circle v-if="open_accordions.includes('desc')" />
|
<div class="sidebar-accordion" :class="[{ 'open': open_accordions.includes('clickable') }]">
|
||||||
|
<div class="sidebar-accordion-title" @click="toggleAccordion('clickable')">
|
||||||
|
<i-mdi-minus-circle v-if="open_accordions.includes('clickable')" />
|
||||||
<i-mdi-plus-circle v-else />
|
<i-mdi-plus-circle v-else />
|
||||||
<h3>Описание</h3>
|
<h3>Кликабельные области</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="sidebar-list" v-if="false">
|
<div class="sidebar-accordion-content" v-if="open_accordions.includes('clickable')">
|
||||||
<div class="sidebar-list-item" v-for="item in sidebar_scene.list">
|
<div class="sidebar-list-item" v-for="item in sidebar_scene.clickable">
|
||||||
<input type="radio" v-model=opened_desc :value="item.id" :id="item.id.toString()"
|
<input type="radio" v-model=opened_desc :value="item.id" :id="item.id.toString()"
|
||||||
:checked="opened_desc == item.id" @change="openedChange"
|
:checked="opened_desc == item.id" @change="openedChange"
|
||||||
:class="[{ checked: opened_desc == item.id }]" />
|
:class="[{ checked: opened_desc == item.id }]" />
|
||||||
|
@ -63,16 +68,20 @@ const toggleAccordion = (name: string) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content" v-if="false">
|
<div class="sidebar-accordion" :class="[{ 'open': open_accordions.includes('desc') }]">
|
||||||
<h2>{{ sidebar.title }}</h2>
|
<div class="sidebar-accordion-title" @click="toggleAccordion('desc')">
|
||||||
<div class="sidebar-inner" v-if="sidebar.description">
|
<i-mdi-minus-circle v-if="open_accordions.includes('desc')" />
|
||||||
<template v-for="p in sidebar.description.replace(/(\n|\r)+/g, '\n').split('\n')">
|
<i-mdi-plus-circle v-else />
|
||||||
|
<h3>Описание</h3>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-accordion-content" v-if="open_accordions.includes('desc')">
|
||||||
|
<template
|
||||||
|
v-for="p in (sidebar.description || sidebar_scene.description || '').replace(/(\n|\r)+/g, '\n').split('\n')">
|
||||||
<p>{{ p }}</p>
|
<p>{{ p }}</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<RouterLink class="btn" :to="`/${route.params.item}/${sidebar.target}`" v-if="sidebar.target">
|
|
||||||
<i-mdi-arrow-right />
|
|
||||||
</RouterLink>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
type state = {
|
type state = {
|
||||||
name: string,
|
name?: string,
|
||||||
list: PromoScene[]
|
description?: string,
|
||||||
|
clickable: PromoScene[],
|
||||||
|
visible: PromoScene[],
|
||||||
}
|
}
|
||||||
export const usePromoScene = defineStore('promo_scene', {
|
export const usePromoScene = defineStore('promo_scene', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
name: '',
|
clickable: [],
|
||||||
list: []
|
visible: [],
|
||||||
} as state
|
} as state
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setData(data: PromoScene[]) {
|
setName(data: any) {
|
||||||
this.list = data
|
this.name = data.name
|
||||||
|
this.description = data.description
|
||||||
|
},
|
||||||
|
setClickable(data: PromoScene[]) {
|
||||||
|
this.clickable = data
|
||||||
|
},
|
||||||
|
setVisible(data: PromoScene[]) {
|
||||||
|
this.visible = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue