Files
onboard/resources/js/Components/Tour/TourOverlay.vue

127 lines
2.5 KiB
Vue

<script setup>
import { computed } from "vue"
const props = defineProps({
rect: {
type: Object,
required: true
},
allowInteraction: {
type: Boolean,
default: true
}
})
const overlayStyle = computed(() => {
if (!props.rect) return null;
const { top, left, width, height } = props.rect
return {
top: {
top: 0,
left: 0,
width: '100vw',
height: `${top}px`
},
left: {
top: `${top}px`,
left: 0,
width: `${left}px`,
height: `${height}px`
},
right: {
top: `${top}px`,
left: `${left+width}px`,
width: `calc(100vw - ${left+width}px)`,
height: `${height}px`
},
bottom: {
top: `${top+height}px`,
left: 0,
width: "100vw",
height: `calc(100vh - ${top+height}px)`
},
highlight: {
top: `${top}px`,
left: `${left}px`,
width: `${width}px`,
height: `${height}px`
},
}
})
</script>
<template>
<Teleport to="body">
<Transition name="tour-fade">
<div v-if="rect && overlayStyle">
<div
class="tour-mask"
:style="overlayStyle.top"
/>
<div
class="tour-mask"
:style="overlayStyle.left"
/>
<div
class="tour-mask"
:style="overlayStyle.right"
/>
<div
class="tour-mask"
:style="overlayStyle.bottom"
/>
<div
class="tour-highlight"
:style="overlayStyle.highlight"
/>
<div
v-if="!allowInteraction"
class="tour-blocker"
/>
</div>
</Transition>
</Teleport>
</template>
<style scoped>
.tour-mask {
position: fixed;
z-index: 9998;
background: rgba(0,0,0,.55);
pointer-events: auto;
}
.tour-blocker {
position: fixed;
inset: 0;
z-index: 9998;
background: transparent;
pointer-events: auto;
}
.tour-highlight {
position: fixed;
z-index: 9998;
border: 2px solid white;
border-radius: 8px;
pointer-events: none;
}
.tour-fade-enter-active,
.tour-fade-leave-active {
transition: opacity .2s;
}
.tour-fade-enter-from,
.tour-fade-leave-to {
opacity: 0;
}
</style>