bx-865-apps #1
|
@ -29,5 +29,6 @@ declare module 'vue' {
|
||||||
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
Sidebar: typeof import('./src/components/Promo/sidebar.vue')['default']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,12 +93,17 @@ const clickEvent = (event: MouseEvent) => {
|
||||||
const intersects = raycaster.value.intersectObjects(clickable_objects.value);
|
const intersects = raycaster.value.intersectObjects(clickable_objects.value);
|
||||||
const names = intersects.map(el => el.object.name ?? false).filter(Boolean)
|
const names = intersects.map(el => el.object.name ?? false).filter(Boolean)
|
||||||
if (names.length) {
|
if (names.length) {
|
||||||
const clicks = clickable.value.filter(el=>names.includes(el.object_name))
|
const clicks = clickable.value.find(el => names.includes(el.object_name))
|
||||||
|
if (!clicks) return
|
||||||
|
const sidebar_data = {
|
||||||
|
title: clicks.name,
|
||||||
|
description: clicks.description
|
||||||
|
} as PromoSidebarData
|
||||||
|
if (clicks?.target) {
|
||||||
|
sidebar_data.target = clicks.target.toString()
|
||||||
|
}
|
||||||
sidebar.open()
|
sidebar.open()
|
||||||
sidebar.setData({
|
sidebar.setData(sidebar_data)
|
||||||
title: clicks[0].name,
|
|
||||||
description: clicks[0].description
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
console.timeEnd('raycaster')
|
console.timeEnd('raycaster')
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,9 @@ 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'
|
||||||
|
|
||||||
|
|
||||||
import Env from './env.vue'
|
import Env from './env.vue'
|
||||||
import LoadModels from './load_models.vue'
|
import LoadModels from './load_models.vue'
|
||||||
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
import Sidebar from './sidebar.vue'
|
||||||
|
|
||||||
const sidebar = usePromoSidebar()
|
|
||||||
|
|
||||||
const _v = new Vector3();
|
const _v = new Vector3();
|
||||||
const onChange = (e: any) => {
|
const onChange = (e: any) => {
|
||||||
|
@ -67,17 +64,7 @@ const point_light = reactive({
|
||||||
<TresPointLight v-bind="point_light" cast-shadow />
|
<TresPointLight v-bind="point_light" cast-shadow />
|
||||||
</TresCanvas>
|
</TresCanvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar" :class="[{ 'open': sidebar.is_open }]">
|
<Sidebar/>
|
||||||
<a href="#" @click.prevent="sidebar.close" class="sidebar-close">
|
|
||||||
<i-mdi-close />
|
|
||||||
</a>
|
|
||||||
<template v-if="sidebar.is_open">
|
|
||||||
<h2>{{ sidebar.title }}</h2>
|
|
||||||
<template v-for="p in sidebar.description.split('\n')">
|
|
||||||
<p>{{ p }}</p>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -93,38 +80,4 @@ const point_light = reactive({
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
width: 23vw;
|
|
||||||
background-color: #fff;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: -27vw;
|
|
||||||
bottom: 0;
|
|
||||||
transition: all 300ms linear;
|
|
||||||
|
|
||||||
padding: 2rem;
|
|
||||||
|
|
||||||
&.open {
|
|
||||||
right: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
&-close {
|
|
||||||
position: absolute;
|
|
||||||
left: 1.5rem;
|
|
||||||
top: 0.5rem;
|
|
||||||
font-size: 2rem;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2rem;
|
|
||||||
margin: 1rem
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 1rem 0;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onClickOutside } from '@vueuse/core'
|
||||||
|
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
||||||
|
|
||||||
|
const sidebar = usePromoSidebar()
|
||||||
|
const sidebar_obj = ref()
|
||||||
|
|
||||||
|
onClickOutside(sidebar_obj, () => sidebar.close())
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="sidebar" :class="[{ 'open': sidebar.is_open }]" ref="sidebar_obj">
|
||||||
|
<a href="#" @click.prevent="sidebar.close" class="sidebar-close">
|
||||||
|
<i-mdi-close />
|
||||||
|
</a>
|
||||||
|
<template v-if="sidebar.is_open">
|
||||||
|
<h2>{{ sidebar.title }}</h2>
|
||||||
|
<template v-for="p in sidebar.description.split('\n')">
|
||||||
|
<p>{{ p }}</p>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.sidebar {
|
||||||
|
width: 23vw;
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: -27vw;
|
||||||
|
bottom: 0;
|
||||||
|
transition: all 300ms linear;
|
||||||
|
|
||||||
|
padding: 2rem;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
position: absolute;
|
||||||
|
left: 1.5rem;
|
||||||
|
top: 0.5rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 2rem;
|
||||||
|
margin: 1rem
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1rem 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -31,9 +31,14 @@ interface clickableAreaType {
|
||||||
source: number;
|
source: number;
|
||||||
target: number;
|
target: number;
|
||||||
}
|
}
|
||||||
interface PromoSidebar{
|
interface PromoSidebar {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
loading: boolean
|
loading: boolean
|
||||||
is_open: boolean
|
is_open: boolean
|
||||||
}
|
}
|
||||||
|
interface PromoSidebarData {
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
target?: string
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ export const usePromoSidebar = defineStore('promo_sidebar', {
|
||||||
this.is_open = true
|
this.is_open = true
|
||||||
this.loading = true
|
this.loading = true
|
||||||
},
|
},
|
||||||
setData(data: { title: string, description: string }) {
|
setData(data: PromoSidebarData) {
|
||||||
const { title, description } = data
|
const { title, description } = data
|
||||||
this.title = title
|
this.title = title
|
||||||
this.description = description
|
this.description = description
|
||||||
|
|
Loading…
Reference in New Issue