text customization
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {motion, frame} from "motion-v";
|
||||
|
||||
const {
|
||||
name,
|
||||
img = undefined,
|
||||
@@ -9,6 +10,8 @@ const {
|
||||
scaleFactor = 2,
|
||||
initialWidth = undefined,
|
||||
initialHeight = undefined,
|
||||
topTextOffset = undefined,
|
||||
bottomTextOffset = undefined,
|
||||
} = defineProps<{
|
||||
name: string,
|
||||
img?: string,
|
||||
@@ -18,12 +21,18 @@ const {
|
||||
scaleFactor?: number,
|
||||
initialWidth?: string,
|
||||
initialHeight?: string,
|
||||
topTextOffset?: string,
|
||||
bottomTextOffset?: string,
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['positionChanged'])
|
||||
|
||||
const isHoveringParent = ref(false)
|
||||
const roundedDivClass = `rounded-full w-full h-full absolute ${color}`
|
||||
|
||||
const imageMaskClass = `avatar mask mask-squircle ${initialWidth ? initialWidth : 'w-30'} ${initialHeight ? initialHeight : 'h-30'}`
|
||||
const roundedDivClass = `rounded-full absolute ${color} ${initialWidth ? initialWidth : 'w-30'} ${initialHeight ? initialHeight : 'h-30'}`
|
||||
const topTextClass = `absolute w-full text-center ${topTextOffset ? topTextOffset : '-top-30'}`
|
||||
const bottomTextClass = `absolute w-full text-center ${bottomTextOffset ? bottomTextOffset : '-bottom-30'}`
|
||||
|
||||
function getRandomArbitrary(min: number, max: number): number {
|
||||
return Math.random() * (max - min) + min;
|
||||
@@ -42,8 +51,8 @@ const handlePointerMove = ({clientX, clientY}: { clientX: number; clientY: numbe
|
||||
const element = elementRef.value?.$el
|
||||
if (!element) return
|
||||
frame.read(() => {
|
||||
xPoint.set((clientX - element.offsetLeft - element.offsetWidth / 2)/moveFactorValue)
|
||||
yPoint.set((clientY - element.offsetTop - element.offsetHeight / 2)/moveFactorValue)
|
||||
xPoint.set((clientX - element.offsetLeft - element.offsetWidth / 2) / moveFactorValue)
|
||||
yPoint.set((clientY - element.offsetTop - element.offsetHeight / 2) / moveFactorValue)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,8 +62,8 @@ useRafFn(() => {
|
||||
return
|
||||
emit(
|
||||
'positionChanged',
|
||||
x.get() + element.offsetLeft + element.offsetWidth/2,
|
||||
y.get() + element.offsetTop + element.offsetHeight/2,)
|
||||
x.get() + element.offsetLeft + element.offsetWidth / 2,
|
||||
y.get() + element.offsetTop + element.offsetHeight / 2,)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@@ -65,43 +74,50 @@ onUnmounted(() => {
|
||||
window.removeEventListener("pointermove", handlePointerMove)
|
||||
})
|
||||
|
||||
const baseElementClass = ref(`${initialWidth ? initialWidth : 'w-30'} ${initialHeight ? initialHeight : 'h-30'} avatar absolute`)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<motion.div
|
||||
ref="elementRef"
|
||||
:class="baseElementClass"
|
||||
:style="{ x, y }"
|
||||
:while-hover="{ scale: scaleFactor }"
|
||||
@hover-start="event => {isHoveringParent=true}"
|
||||
@hover-end="event => {isHoveringParent=false}">
|
||||
class="w-60 h-24 absolute flex items-center justify-center"
|
||||
:style="{ x, y }">
|
||||
|
||||
<div v-if="img !== undefined" class="mask mask-squircle w-full">
|
||||
<motion.div
|
||||
v-if="img !== undefined"
|
||||
:class="imageMaskClass"
|
||||
:while-hover="{ scale: scaleFactor }"
|
||||
@hover-start="event => {isHoveringParent=true}"
|
||||
@hover-end="event => {isHoveringParent=false}">
|
||||
<NuxtImg :src="img"/>
|
||||
</div>
|
||||
<div v-else :class="roundedDivClass"/>
|
||||
|
||||
<motion.p
|
||||
v-if="textTop"
|
||||
v-show="isHoveringParent"
|
||||
class="-top-8 absolute text-xs"
|
||||
:initial="{ opacity: 0 }"
|
||||
:animate="{ opacity: 1 }"
|
||||
:exit="{ opacity: 0 }">
|
||||
{{ name }}
|
||||
</motion.p>
|
||||
|
||||
<motion.p
|
||||
</motion.div>
|
||||
<motion.div
|
||||
v-else
|
||||
v-show="isHoveringParent"
|
||||
class="-bottom-8 absolute text-xs"
|
||||
:initial="{ opacity: 0 }"
|
||||
:animate="{ opacity: 1 }"
|
||||
:exit="{ opacity: 0 }">
|
||||
{{ name }}
|
||||
</motion.p>
|
||||
:class="roundedDivClass"
|
||||
:while-hover="{ scale: scaleFactor }"
|
||||
@hover-start="event => {isHoveringParent=true}"
|
||||
@hover-end="event => {isHoveringParent=false}"/>
|
||||
|
||||
<AnimatePresence>
|
||||
<motion.p
|
||||
v-if="textTop"
|
||||
v-show="isHoveringParent"
|
||||
:class="topTextClass"
|
||||
:initial="{ opacity: 0, scale: 0 }"
|
||||
:animate="{ opacity: 1, scale: 1 }"
|
||||
:exit="{ opacity: 0, scale: 0 }">
|
||||
{{ name }}
|
||||
</motion.p>
|
||||
|
||||
<motion.p
|
||||
v-else
|
||||
v-show="isHoveringParent"
|
||||
:class="bottomTextClass"
|
||||
:initial="{ opacity: 0, scale: 0 }"
|
||||
:animate="{ opacity: 1, scale: 1 }"
|
||||
:exit="{ opacity: 0, scale: 0 }">
|
||||
{{ name }}
|
||||
</motion.p>
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user