mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
refactor: replace css fade animations with gsap, optimize post page animations and mobile responsiveness
This commit is contained in:
parent
90c2099fec
commit
db4aa56987
9 changed files with 239 additions and 211 deletions
|
@ -19,8 +19,7 @@ const { waline: { serverURL = '', emoji = [], search = false, imageUploader = fa
|
|||
|
||||
<div
|
||||
id="waline"
|
||||
class="animation-fade-in mt-16"
|
||||
style="--animation-delay: 0.8s;"
|
||||
class="mt-16"
|
||||
></div>
|
||||
|
||||
<!-- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
|
|
|
@ -4,7 +4,7 @@ import GoBackIcon from '@/assets/icons/go-back.svg';
|
|||
|
||||
<button
|
||||
id="back-button"
|
||||
class="animation-fade-goback hidden"
|
||||
class="hidden"
|
||||
lg="block absolute c-secondary/40 left--10 top-1/2 aspect-square w-4.5 translate-y--1/2 transition-colors duration-300 ease-out c-secondary active:scale-90 hover:c-primary/80"
|
||||
aria-label="Go back"
|
||||
>
|
97
src/components/Widgets/GsapAnimation.astro
Normal file
97
src/components/Widgets/GsapAnimation.astro
Normal file
|
@ -0,0 +1,97 @@
|
|||
<script>
|
||||
import { gsap } from 'gsap'
|
||||
|
||||
function setupPostPageAnimation() {
|
||||
const allElements = Array.from(document.querySelectorAll('#gsap-post-page-content > *, #gsap-post-page-tags, #waline'))
|
||||
const tocListChildren = Array.from(document.querySelectorAll('#toc-list > *')).slice(0, 20)
|
||||
const dateElement = document.getElementById('gsap-post-page-date')
|
||||
const backButton = document.getElementById('back-button')
|
||||
const tocIcon = document.getElementById('toc-icon')
|
||||
const tocContainer = document.getElementById('toc-container')
|
||||
|
||||
const isLargeScreen = window.matchMedia('(min-width: 1024px)').matches
|
||||
|
||||
// Post Content + Tags + Comments (First 15 elements)
|
||||
gsap.from(allElements.slice(0, 15), {
|
||||
opacity: 0,
|
||||
y: '3rem',
|
||||
duration: 0.5,
|
||||
delay: 0.1,
|
||||
ease: 'power2.out',
|
||||
stagger: 0.05,
|
||||
})
|
||||
|
||||
// Post Content + Tags + Comments (Rest elements)
|
||||
if (allElements.length > 15) {
|
||||
gsap.from(allElements.slice(15), {
|
||||
opacity: 0,
|
||||
y: '3rem',
|
||||
duration: 0.5,
|
||||
delay: 0.05 * 15 + 0.1,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
|
||||
if (isLargeScreen) {
|
||||
// Desktop Post Date
|
||||
if (dateElement) {
|
||||
gsap.from(dateElement, {
|
||||
opacity: 0,
|
||||
y: '1.5rem',
|
||||
duration: 0.5,
|
||||
delay: 0.1,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
|
||||
// Desktop TOC Icon
|
||||
if (tocIcon) {
|
||||
gsap.from(tocIcon, {
|
||||
opacity: 0,
|
||||
y: '0.5rem',
|
||||
duration: 0.5,
|
||||
delay: 0.125,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
|
||||
// Desktop Toc List
|
||||
if (tocListChildren.length > 0) {
|
||||
gsap.from(tocListChildren, {
|
||||
opacity: 0,
|
||||
y: '1.5rem',
|
||||
duration: 0.5,
|
||||
delay: 0.15,
|
||||
ease: 'power2.out',
|
||||
stagger: 0.025,
|
||||
})
|
||||
}
|
||||
|
||||
// Desktop Back Button
|
||||
if (backButton) {
|
||||
gsap.from(backButton, {
|
||||
opacity: 0,
|
||||
x: '0.5rem',
|
||||
duration: 0.5,
|
||||
delay: 0.15,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Mobile TOC Container
|
||||
if (tocContainer) {
|
||||
gsap.from(tocContainer, {
|
||||
opacity: 0,
|
||||
y: '3rem',
|
||||
duration: 0.5,
|
||||
delay: 0.1,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupPostPageAnimation()
|
||||
document.addEventListener('astro:after-swap', setupPostPageAnimation)
|
||||
</script>
|
|
@ -19,7 +19,10 @@ const filteredHeadings = headings.filter(heading =>
|
|||
---
|
||||
|
||||
{filteredHeadings.length > 0 && (
|
||||
<div class="mb-4 uno-round-border bg-secondary/5 2xl:(fixed left-0 top-43.5 max-w-[min(calc(50vw-38rem),13rem)] border-none bg-secondary/0)">
|
||||
<div
|
||||
id="toc-container"
|
||||
class="mb-4 uno-round-border bg-secondary/5 2xl:(fixed left-0 top-43.5 max-w-[min(calc(50vw-38rem),13rem)] border-none bg-secondary/0)"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="toc-toggle"
|
||||
|
@ -36,8 +39,9 @@ const filteredHeadings = headings.filter(heading =>
|
|||
</span>
|
||||
|
||||
<TocIcon
|
||||
id="toc-icon"
|
||||
aria-hidden="true"
|
||||
class="animation-fade-in ml-1 hidden aspect-square w-4.2 2xl:(mt-4 block origin-center active:scale-90)"
|
||||
class="ml-1 hidden aspect-square w-4.2 2xl:(mt-4 block origin-center active:scale-90)"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</label>
|
||||
|
@ -51,8 +55,8 @@ const filteredHeadings = headings.filter(heading =>
|
|||
aria-label="Table of Contents"
|
||||
>
|
||||
<ul
|
||||
class="animation-fade-up toc-list"
|
||||
style="--animation-interval: 0.04s;"
|
||||
id="toc-list"
|
||||
class="toc-list"
|
||||
>
|
||||
{filteredHeadings.map(heading => (
|
||||
<li
|
||||
|
@ -83,13 +87,13 @@ const filteredHeadings = headings.filter(heading =>
|
|||
<!-- Override heti default styles >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
<style>
|
||||
.toc-title {
|
||||
--at-apply: 'font-semibold ml-4 select-none 2xl:hidden';
|
||||
--at-apply: 'font-semibold ml-4 2xl:hidden';
|
||||
}
|
||||
.toc-list {
|
||||
--at-apply: 'list-none pl-0 space-y-2 mt-1 mb-4 2xl:space-y-1.2';
|
||||
--at-apply: 'list-none pb-3.3 pl-0 space-y-2 mt-1 mb-4 2xl:space-y-1.2';
|
||||
}
|
||||
.toc-link-h2, .toc-link-h3, .toc-link-h4 {
|
||||
--at-apply: 'text-sm no-underline font-normal text-balance select-none 2xl:(text-3.2 c-secondary/60 transition-colors transition-font-weight duration-300 ease-out hover:(c-secondary font-medium))';
|
||||
--at-apply: 'text-sm no-underline font-normal text-balance 2xl:(text-3.2 c-secondary/60 transition-colors transition-font-weight duration-300 ease-out hover:(c-secondary font-medium))';
|
||||
}
|
||||
|
||||
/* Initial collapsed state with zero height grid row */
|
||||
|
@ -97,7 +101,7 @@ const filteredHeadings = headings.filter(heading =>
|
|||
--at-apply: 'grid rows-[0fr] duration-300 ease-in-out';
|
||||
}
|
||||
.accordion-content {
|
||||
--at-apply: 'max-h-66 overflow-hidden pl-4 pr-6 2xl:(max-h-[calc(100vh-21.5rem)] pl-1)';
|
||||
--at-apply: 'max-h-66 overflow-hidden pl-4 pr-6 2xl:(max-h-[calc(100vh-26rem)] pl-1)';
|
||||
}
|
||||
|
||||
/* When toggle is checked, expand the wrapper to show content */
|
||||
|
|
|
@ -3,13 +3,12 @@ import Button from '@/components/Button.astro'
|
|||
import Footer from '@/components/Footer.astro'
|
||||
import Header from '@/components/Header.astro'
|
||||
import Navbar from '@/components/Navbar.astro'
|
||||
import FadeUpAnimation from '@/components/Widgets/FadeUpAnimation.astro'
|
||||
import GithubCard from '@/components/Widgets/GithubCard.astro'
|
||||
import GsapAnimation from '@/components/Widgets/GsapAnimation.astro'
|
||||
import PhotoSwipe from '@/components/Widgets/PhotoSwipe.astro'
|
||||
import themeConfig from '@/config'
|
||||
import Head from '@/layouts/Head.astro'
|
||||
import { getPageInfo } from '@/utils/page'
|
||||
import '@/styles/animation.css'
|
||||
import '@/styles/global.css'
|
||||
import '@/styles/font.css'
|
||||
import '@/styles/heti.css'
|
||||
|
@ -48,7 +47,7 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
|
|||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
<FadeUpAnimation />
|
||||
<GsapAnimation />
|
||||
<Button supportedLangs={supportedLangs} />
|
||||
<GithubCard />
|
||||
<PhotoSwipe />
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { CollectionEntry } from 'astro:content'
|
|||
import { getCollection, render } from 'astro:content'
|
||||
import Comments from '@/components/Comments/index.astro'
|
||||
import PostDate from '@/components/PostDate.astro'
|
||||
import GoBack from '@/components/Widgets/GoBack.astro'
|
||||
import BackButton from '@/components/Widgets/BackButton.astro'
|
||||
import TOC from '@/components/Widgets/TOC.astro'
|
||||
import { allLocales, defaultLocale, moreLocales } from '@/config'
|
||||
import { getTagPath } from '@/i18n/path'
|
||||
|
@ -109,7 +109,7 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
|||
<article class="heti mb-12.6">
|
||||
<div class="relative">
|
||||
<!-- Go Back Button On Desktop -->
|
||||
<GoBack />
|
||||
<BackButton />
|
||||
<!-- Title -->
|
||||
<h1 class="post-title">
|
||||
<span
|
||||
|
@ -123,8 +123,8 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
|||
|
||||
<!-- Date -->
|
||||
<div
|
||||
class="animation-fade-in mb-16.3 block c-primary font-time"
|
||||
style="--animation-distance: 1rem;"
|
||||
id="gsap-post-page-date"
|
||||
class="mb-16.3 block c-primary font-time"
|
||||
transition:name={`time-${post.data.abbrlink || post.id}-${lang}`}
|
||||
data-disable-theme-transition
|
||||
>
|
||||
|
@ -137,26 +137,25 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
|||
<!-- TOC -->
|
||||
{post.data.toc && <TOC headings={headings} />}
|
||||
<!-- Content -->
|
||||
<div class="animation-fade-up">
|
||||
<div id="gsap-post-page-content">
|
||||
<Content />
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<!-- Tags -->
|
||||
{post.data.tags && post.data.tags.length > 0 && (
|
||||
<div
|
||||
class="animation-fade-in uno-decorative-line"
|
||||
style="--animation-delay: 0.8s;"
|
||||
></div>
|
||||
<div class="uno-tags-wrapper">
|
||||
{post.data.tags.map((tag: string) => (
|
||||
<a
|
||||
href={getTagPath(tag, lang)}
|
||||
class="uno-tags-style"
|
||||
>
|
||||
{tag}
|
||||
</a>
|
||||
))}
|
||||
<div id="gsap-post-page-tags">
|
||||
<div class="uno-decorative-line"></div>
|
||||
<div class="uno-tags-wrapper">
|
||||
{post.data.tags.map((tag: string) => (
|
||||
<a
|
||||
href={getTagPath(tag, lang)}
|
||||
class="uno-tags-style"
|
||||
>
|
||||
{tag}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<!-- Comments -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue