on click outside
This commit is contained in:
parent
116baf4f6c
commit
800e7f390c
|
@ -29,5 +29,6 @@ declare module 'vue' {
|
|||
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
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 names = intersects.map(el => el.object.name ?? false).filter(Boolean)
|
||||
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.setData({
|
||||
title: clicks[0].name,
|
||||
description: clicks[0].description
|
||||
})
|
||||
sidebar.setData(sidebar_data)
|
||||
}
|
||||
console.timeEnd('raycaster')
|
||||
}
|
||||
|
|
|
@ -6,12 +6,9 @@ import { Vector3 } from 'three';
|
|||
import { TresCanvas } from '@tresjs/core';
|
||||
import { CameraControls, useProgress, StatsGl } from '@tresjs/cientos'
|
||||
|
||||
|
||||
import Env from './env.vue'
|
||||
import LoadModels from './load_models.vue'
|
||||
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
||||
|
||||
const sidebar = usePromoSidebar()
|
||||
import Sidebar from './sidebar.vue'
|
||||
|
||||
const _v = new Vector3();
|
||||
const onChange = (e: any) => {
|
||||
|
@ -67,17 +64,7 @@ const point_light = reactive({
|
|||
<TresPointLight v-bind="point_light" cast-shadow />
|
||||
</TresCanvas>
|
||||
</div>
|
||||
<div class="sidebar" :class="[{ 'open': sidebar.is_open }]">
|
||||
<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>
|
||||
<Sidebar/>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
|
@ -93,38 +80,4 @@ const point_light = reactive({
|
|||
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>
|
|
@ -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;
|
||||
target: number;
|
||||
}
|
||||
interface PromoSidebar{
|
||||
interface PromoSidebar {
|
||||
title: string
|
||||
description: string
|
||||
loading: 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.loading = true
|
||||
},
|
||||
setData(data: { title: string, description: string }) {
|
||||
setData(data: PromoSidebarData) {
|
||||
const { title, description } = data
|
||||
this.title = title
|
||||
this.description = description
|
||||
|
|
Loading…
Reference in New Issue