Files
nuxt-portfolio/app/components/GraphNode.vue
2025-12-01 14:56:16 +01:00

61 lines
1.4 KiB
Vue

<script setup lang="ts">
import {motion, type MotionValue} from "motion-v";
const {
x,
y,
name,
img = undefined,
color = 'bg-white',
hOffset = undefined,
vOffset = undefined,
} = defineProps<{
x: MotionValue<number>,
y: MotionValue<number>,
name: string,
img?: string,
color?: string,
hOffset?: string,
vOffset?: string,
}>()
const isHoveringParent = ref(false)
const roundedDivClass = `rounded-full w-full h-full absolute ${color}`
const hOffsetValue = hOffset === undefined ? '' : hOffset
const vOffsetValue = vOffset === undefined ? '' : vOffset
const computedClass = `w-20 h-20 absolute avatar ${hOffsetValue} ${vOffsetValue}`
</script>
<template>
<motion.div
ref="elementRef"
:class="computedClass"
:style="{ x, y }"
:while-hover="{ scale: 3 }"
@hover-start="event => {isHoveringParent=true}"
@hover-end="event => {isHoveringParent=false}">
<div v-if="img !== undefined" class="mask mask-squircle w-24">
<NuxtImg :src="img"/>
</div>
<div v-else :class="roundedDivClass"/>
<motion.p
v-show="isHoveringParent"
class="-top-8 absolute text-xs"
:initial="{ opacity: 0 }"
:animate="{ opacity: 1 }"
:exit="{ opacity: 0 }">
{{ name }}
</motion.p>
</motion.div>
</template>
<style scoped>
* {
overflow: visible;
}
</style>