Scroll to top button

This commit is contained in:
DarkCat09 2023-08-11 13:40:37 +04:00
parent 4bd4d08f06
commit 4869352450
Signed by: DarkCat09
GPG key ID: 4785B6FB1C50A540
2 changed files with 84 additions and 0 deletions

View file

@ -0,0 +1,82 @@
---
import Icon from "./Icon.astro";
---
<div id="scroll-to-top" data-show="0">
<a href="#">
<Icon code="&#xf106;" />
</a>
</div>
<style lang="less">
@size: 2.25rem;
@font: 1.50rem;
div {
position: absolute;
&[data-show="0"] a {
height: 0;
opacity: 0;
transition: opacity 0.2s ease, height 0.2s step-end;
}
&[data-show="1"] a {
height: @size;
opacity: 1;
transition: opacity 0.2s ease, height 0.2s step-start;
}
}
a {
position: fixed;
bottom: 0.5rem;
right: 0.625rem;
display: inline-flex;
justify-content: center;
align-items: center;
padding: 0.25rem;
width: @size;
height: @size;
border-radius: @size;
font-size: @font;
background: var(--accent-bg);
color: var(--fg);
&:hover {
background: var(--bg-sec);
color: var(--fg);
}
}
</style>
<script>
const stt = document.getElementById('scroll-to-top')
const doc = document.documentElement
let scrollPos = 0
let ticking = false
const handler = (pos: number) => {
if (pos > doc.clientHeight / 2) {
stt.dataset.show = '1'
}
else {
stt.dataset.show = '0'
}
}
addEventListener('scroll', () => {
scrollPos = window.scrollY
if (!ticking) {
window.requestAnimationFrame(() => {
handler(scrollPos)
ticking = false
})
ticking = true
}
})
</script>

View file

@ -2,6 +2,7 @@
import Layout from "./Layout.astro";
import NavMenu from "./NavMenu.astro";
import MenuItem from "../components/MenuItem.astro";
import ScrollToTop from "../components/ScrollToTop.astro";
export interface Props {
title: string;
@ -14,6 +15,7 @@ const { title, description, mainpage = false } = Astro.props;
<Layout title={"Blog | " + title} description={description}>
<slot name="metadata" slot="metadata" />
<ScrollToTop />
<NavMenu>
{
mainpage ?