on click outside

This commit is contained in:
Kseninia Mikhaylova 2024-06-27 11:16:37 +03:00
parent 116baf4f6c
commit 800e7f390c
6 changed files with 80 additions and 57 deletions

View File

@ -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']
}
}

View File

@ -89,16 +89,21 @@ const clickEvent = (event: MouseEvent) => {
pointer.x = x
pointer.y = y
raycaster.value.setFromCamera(new Vector2(pointer.x, pointer.y), camera.value);
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')
}

View File

@ -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>

View File

@ -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>

View File

@ -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
}

View File

@ -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