This commit is contained in:
李志鹏
2026-05-14 13:01:52 +08:00
parent 5668ec3747
commit e986861e72
3 changed files with 196 additions and 2 deletions

View File

@@ -0,0 +1,92 @@
<template>
<div
class="back-top"
@click="handleClick"
:class="{ active: progress > 0, hidden: progress === 0 }"
>
<svg width="100%" height="100%" viewBox="-1 -1 102 102">
<path
d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"
:style="{
transition: 'stroke-dashoffset 10ms linear',
strokeDasharray: `${progress}, ${max}`,
stroke: '#222',
strokeWidth: 4,
}"
fill="none"
></path>
</svg>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, h } from "vue";
const max = ref(98 * Math.PI);
const progress = ref(0);
const handleScroll = () => {
const el = document.documentElement;
const num = el.scrollTop / (el.scrollHeight - el.clientHeight);
progress.value = max.value * num;
};
const handleClick = () => {
document.documentElement.scrollTo({ top: 0, behavior: "smooth" });
};
onMounted(() => {
handleScroll();
document.addEventListener("scroll", handleScroll);
});
onUnmounted(() => {
document.removeEventListener("scroll", handleScroll);
});
</script>
<style scoped>
.back-top {
position: fixed;
right: 30px;
bottom: 30px;
width: 46px;
height: 46px;
cursor: pointer;
color: #222;
background-color: #fff;
border-radius: 50%;
-webkit-box-shadow: inset 0 0 0 1px #e1e1e1;
box-shadow: inset 0 0 0 1px #e1e1e1;
z-index: 999;
}
.back-top svg {
width: 100%;
height: 100%;
}
.back-top path {
transition: stroke-dashoffset 10ms linear;
}
.back-top.active {
animation: active 0.2s linear both;
}
.back-top.hidden {
animation: hidden 0.2s linear both;
}
@keyframes active {
0% {
display: none;
opacity: 0;
transform: translateY(50px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes hidden {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(50px);
display: none;
}
}
</style>