fix: 调整动画效果
parent
955c92cff3
commit
7ca0098a1b
|
|
@ -12,16 +12,11 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<Teleport to="body">
|
<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
|
<div
|
||||||
v-if="visible"
|
v-if="visible"
|
||||||
ref="tipRef"
|
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)]"
|
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"
|
:style="tipStyle"
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
>
|
>
|
||||||
|
|
@ -31,7 +26,6 @@
|
||||||
:class="arrowPlacementClass"
|
:class="arrowPlacementClass"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -55,8 +49,10 @@
|
||||||
const triggerRef = ref<HTMLElement | null>(null);
|
const triggerRef = ref<HTMLElement | null>(null);
|
||||||
const tipRef = ref<HTMLElement | null>(null);
|
const tipRef = ref<HTMLElement | null>(null);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
const positioned = ref(false);
|
||||||
const isListening = ref(false);
|
const isListening = ref(false);
|
||||||
const timer = ref<number | null>(null);
|
const timer = ref<number | null>(null);
|
||||||
|
const revealFrame = ref<number | null>(null);
|
||||||
|
|
||||||
const gap = 10;
|
const gap = 10;
|
||||||
const viewportPadding = 8;
|
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 clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);
|
||||||
|
|
||||||
const addPositionListeners = () => {
|
const addPositionListeners = () => {
|
||||||
|
|
@ -104,21 +107,29 @@
|
||||||
|
|
||||||
if (visible.value) {
|
if (visible.value) {
|
||||||
calculatePosition();
|
calculatePosition();
|
||||||
|
positioned.value = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimer();
|
clearTimer();
|
||||||
timer.value = window.setTimeout(async () => {
|
timer.value = window.setTimeout(async () => {
|
||||||
timer.value = null;
|
timer.value = null;
|
||||||
|
positioned.value = false;
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
calculatePosition();
|
calculatePosition();
|
||||||
|
revealFrame.value = window.requestAnimationFrame(() => {
|
||||||
|
positioned.value = true;
|
||||||
|
revealFrame.value = null;
|
||||||
|
});
|
||||||
addPositionListeners();
|
addPositionListeners();
|
||||||
}, props.delay);
|
}, props.delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideTip = () => {
|
const hideTip = () => {
|
||||||
clearTimer();
|
clearTimer();
|
||||||
|
clearRevealFrame();
|
||||||
|
positioned.value = false;
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
removePositionListeners();
|
removePositionListeners();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@
|
||||||
<span class="text-[2.75rem] font-600" v-if="index > 2">{{ index + 1 }}</span>
|
<span class="text-[2.75rem] font-600" v-if="index > 2">{{ index + 1 }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #name="{ data }">
|
<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>
|
||||||
<template #total="{ data }">
|
<template #total="{ data }">
|
||||||
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.total }}</span>
|
<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>
|
<span class="text-[2.75rem] font-600" v-if="index > 2">{{ index + 1 }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #name="{ data }">
|
<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>
|
||||||
<template #total="{ data }">
|
<template #total="{ data }">
|
||||||
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.total }}</span>
|
<span class="text-[#C0EEFF] text-[2.75rem]">{{ data.total }}</span>
|
||||||
|
|
@ -60,6 +64,7 @@
|
||||||
import SvgComponent from "@/components/SvgComponent.vue";
|
import SvgComponent from "@/components/SvgComponent.vue";
|
||||||
import RankingTable from "@/components/table/RankingTable.vue";
|
import RankingTable from "@/components/table/RankingTable.vue";
|
||||||
import MobileDrawer from "./MobileDrawer.vue";
|
import MobileDrawer from "./MobileDrawer.vue";
|
||||||
|
import Tooltip from "./Tooltip.vue";
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ field: "rank", header: "名次", align: "justify-center", width: "6rem" },
|
{ field: "rank", header: "名次", align: "justify-center", width: "6rem" },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue