fix: 调整动画效果

master
xjs 2026-06-08 13:49:06 +08:00
parent 955c92cff3
commit 7ca0098a1b
2 changed files with 37 additions and 21 deletions

View File

@ -12,26 +12,20 @@
</span>
<Teleport to="body">
<Transition
enter-active-class="transition-all duration-150 ease-out"
leave-active-class="transition-all duration-150 ease-in"
enter-from-class="opacity-0 translate-y-[0.25rem]"
leave-to-class="opacity-0 translate-y-[0.25rem]"
<div
v-if="visible"
ref="tipRef"
class="fixed z-[9999] max-w-[min(38rem,calc(100vw-2rem))] px-[1.5rem] py-[1rem] text-[#D9F7FF] text-[2rem] leading-[1.25] break-all pointer-events-none border border-[rgba(132,232,255,0.55)] rounded-[0.75rem] bg-[linear-gradient(180deg,rgba(10,58,132,0.96)_0%,rgba(7,35,98,0.98)_100%)] shadow-[0_0_1.5rem_rgba(68,193,239,0.28),inset_0_0_1rem_rgba(68,193,239,0.14)] transition-opacity duration-150 ease-out"
:class="positioned ? 'opacity-100' : 'opacity-0'"
:style="tipStyle"
role="tooltip"
>
<div
v-if="visible"
ref="tipRef"
class="fixed z-[9999] max-w-[min(38rem,calc(100vw-2rem))] px-[1.5rem] py-[1rem] text-[#D9F7FF] text-[2rem] leading-[1.25] break-all pointer-events-none border border-[rgba(132,232,255,0.55)] rounded-[0.75rem] bg-[linear-gradient(180deg,rgba(10,58,132,0.96)_0%,rgba(7,35,98,0.98)_100%)] shadow-[0_0_1.5rem_rgba(68,193,239,0.28),inset_0_0_1rem_rgba(68,193,239,0.14)]"
:style="tipStyle"
role="tooltip"
>
<span class="block">{{ text }}</span>
<span
class="absolute h-[0.85rem] w-[0.85rem] rotate-45 border-[rgba(132,232,255,0.55)] border-solid bg-[rgba(7,35,98,0.98)]"
:class="arrowPlacementClass"
></span>
</div>
</Transition>
<span class="block">{{ text }}</span>
<span
class="absolute h-[0.85rem] w-[0.85rem] rotate-45 border-[rgba(132,232,255,0.55)] border-solid bg-[rgba(7,35,98,0.98)]"
:class="arrowPlacementClass"
></span>
</div>
</Teleport>
</template>
@ -55,8 +49,10 @@
const triggerRef = ref<HTMLElement | null>(null);
const tipRef = ref<HTMLElement | null>(null);
const visible = ref(false);
const positioned = ref(false);
const isListening = ref(false);
const timer = ref<number | null>(null);
const revealFrame = ref<number | null>(null);
const gap = 10;
const viewportPadding = 8;
@ -83,6 +79,13 @@
}
};
const clearRevealFrame = () => {
if (revealFrame.value) {
window.cancelAnimationFrame(revealFrame.value);
revealFrame.value = null;
}
};
const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);
const addPositionListeners = () => {
@ -104,21 +107,29 @@
if (visible.value) {
calculatePosition();
positioned.value = true;
return;
}
clearTimer();
timer.value = window.setTimeout(async () => {
timer.value = null;
positioned.value = false;
visible.value = true;
await nextTick();
calculatePosition();
revealFrame.value = window.requestAnimationFrame(() => {
positioned.value = true;
revealFrame.value = null;
});
addPositionListeners();
}, props.delay);
};
const hideTip = () => {
clearTimer();
clearRevealFrame();
positioned.value = false;
visible.value = false;
removePositionListeners();
};

View File

@ -19,7 +19,9 @@
<span class="text-[2.75rem] font-600" v-if="index > 2">{{ index + 1 }}</span>
</template>
<template #name="{ data }">
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.name }}</span>
<Tooltip :text="data.name" position="bottom">
<span class="block max-w-[9rem] overflow-hidden text-ellipsis whitespace-nowrap text-[#C0EEFF] text-[2.75rem]">{{ data.name }}</span>
</Tooltip>
</template>
<template #total="{ data }">
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.total }}</span>
@ -47,7 +49,9 @@
<span class="text-[2.75rem] font-600" v-if="index > 2">{{ index + 1 }}</span>
</template>
<template #name="{ data }">
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.name }}</span>
<Tooltip :text="data.name" position="bottom">
<span class="block max-w-full overflow-hidden text-ellipsis whitespace-nowrap text-[#C0EEFF] text-[2.75rem]">{{ data.name }}</span>
</Tooltip>
</template>
<template #total="{ data }">
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.total }}</span>
@ -60,6 +64,7 @@
import SvgComponent from "@/components/SvgComponent.vue";
import RankingTable from "@/components/table/RankingTable.vue";
import MobileDrawer from "./MobileDrawer.vue";
import Tooltip from "./Tooltip.vue";
const columns = [
{ field: "rank", header: "名次", align: "justify-center", width: "6rem" },