mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
fix: resolve gsap animation flash on page load
- Add initial state styles for animated elements in CSS - Change GSAP animations from .from() to .to() method - Move reduce-motion class from JS to server-side HTML - Improve performance by eliminating DOM flash - Enhance code readability with better formatting
This commit is contained in:
parent
ead71483ec
commit
c1996585a8
5 changed files with 68 additions and 43 deletions
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
|
@ -1927,8 +1927,8 @@ packages:
|
||||||
eslint-flat-config-utils@2.1.0:
|
eslint-flat-config-utils@2.1.0:
|
||||||
resolution: {integrity: sha512-6fjOJ9tS0k28ketkUcQ+kKptB4dBZY2VijMZ9rGn8Cwnn1SH0cZBoPXT8AHBFHxmHcLFQK9zbELDinZ2Mr1rng==}
|
resolution: {integrity: sha512-6fjOJ9tS0k28ketkUcQ+kKptB4dBZY2VijMZ9rGn8Cwnn1SH0cZBoPXT8AHBFHxmHcLFQK9zbELDinZ2Mr1rng==}
|
||||||
|
|
||||||
eslint-import-context@0.1.4:
|
eslint-import-context@0.1.5:
|
||||||
resolution: {integrity: sha512-x3+etvB5TPxjFIq2m4tTnpt/9Ekp5GZKzXNp5ExLaS7Qv9E5BVs/Td7jxSnRtSzrgTCExXZlc0MuOdSuDLURiQ==}
|
resolution: {integrity: sha512-jalO1mLiEvTv0io0koz1AE4LwkHQxDBFLaSXWweWtJR0y/NC1yyxvU61Z54bghIFNeM1M4TvwRwVRhLunQJ3gw==}
|
||||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
unrs-resolver: ^1.0.0
|
unrs-resolver: ^1.0.0
|
||||||
|
@ -1977,8 +1977,8 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=8'
|
eslint: '>=8'
|
||||||
|
|
||||||
eslint-plugin-import-x@4.13.1:
|
eslint-plugin-import-x@4.13.3:
|
||||||
resolution: {integrity: sha512-Ua4HZBmG5TNr18q3Is+nT6mKCzNNpycqtv/+TkIK7E3w4LBlPlZI6vLwmDjXdIZtJPP2Z1Oh5+wksWwlcCjMpA==}
|
resolution: {integrity: sha512-CDewJDEeYQhm94KGCDYiuwU1SdaWc/vh+SziSKkF7kichAqAFnQYtSYUvSwSBbiBjYLxV5uUxocxxQobRI9YXA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
|
@ -4068,7 +4068,7 @@ snapshots:
|
||||||
eslint-merge-processors: 2.0.0(eslint@9.27.0(jiti@2.4.2))
|
eslint-merge-processors: 2.0.0(eslint@9.27.0(jiti@2.4.2))
|
||||||
eslint-plugin-antfu: 3.1.1(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-antfu: 3.1.1(eslint@9.27.0(jiti@2.4.2))
|
||||||
eslint-plugin-command: 3.2.1(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-command: 3.2.1(eslint@9.27.0(jiti@2.4.2))
|
||||||
eslint-plugin-import-x: 4.13.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)
|
eslint-plugin-import-x: 4.13.3(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)
|
||||||
eslint-plugin-jsdoc: 50.6.17(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-jsdoc: 50.6.17(eslint@9.27.0(jiti@2.4.2))
|
||||||
eslint-plugin-jsonc: 2.20.1(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-jsonc: 2.20.1(eslint@9.27.0(jiti@2.4.2))
|
||||||
eslint-plugin-n: 17.18.0(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-n: 17.18.0(eslint@9.27.0(jiti@2.4.2))
|
||||||
|
@ -6063,7 +6063,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
eslint-import-context@0.1.4(unrs-resolver@1.7.2):
|
eslint-import-context@0.1.5(unrs-resolver@1.7.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
get-tsconfig: 4.10.1
|
get-tsconfig: 4.10.1
|
||||||
stable-hash: 0.0.5
|
stable-hash: 0.0.5
|
||||||
|
@ -6118,13 +6118,13 @@ snapshots:
|
||||||
eslint: 9.27.0(jiti@2.4.2)
|
eslint: 9.27.0(jiti@2.4.2)
|
||||||
eslint-compat-utils: 0.5.1(eslint@9.27.0(jiti@2.4.2))
|
eslint-compat-utils: 0.5.1(eslint@9.27.0(jiti@2.4.2))
|
||||||
|
|
||||||
eslint-plugin-import-x@4.13.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3):
|
eslint-plugin-import-x@4.13.3(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)
|
'@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)
|
||||||
comment-parser: 1.4.1
|
comment-parser: 1.4.1
|
||||||
debug: 4.4.1
|
debug: 4.4.1
|
||||||
eslint: 9.27.0(jiti@2.4.2)
|
eslint: 9.27.0(jiti@2.4.2)
|
||||||
eslint-import-context: 0.1.4(unrs-resolver@1.7.2)
|
eslint-import-context: 0.1.5(unrs-resolver@1.7.2)
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
minimatch: 10.0.1
|
minimatch: 10.0.1
|
||||||
|
|
|
@ -9,8 +9,10 @@ interface Props {
|
||||||
supportedLangs: string[]
|
supportedLangs: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
const {
|
||||||
const reduceMotion = themeConfig.global.reduceMotion
|
light: { background: lightMode },
|
||||||
|
dark: { background: darkMode },
|
||||||
|
} = themeConfig.color
|
||||||
|
|
||||||
const { supportedLangs } = Astro.props
|
const { supportedLangs } = Astro.props
|
||||||
const currentPath = Astro.url.pathname
|
const currentPath = Astro.url.pathname
|
||||||
|
@ -63,7 +65,7 @@ const nextUrl = useSupportedLangs
|
||||||
<!-- Theme Toggle Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
<!-- Theme Toggle Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||||
<script
|
<script
|
||||||
is:inline
|
is:inline
|
||||||
define:vars={{ lightMode, darkMode, reduceMotion }}
|
define:vars={{ lightMode, darkMode }}
|
||||||
>
|
>
|
||||||
// Update theme
|
// Update theme
|
||||||
function updateTheme() {
|
function updateTheme() {
|
||||||
|
@ -85,18 +87,13 @@ function updateTheme() {
|
||||||
|
|
||||||
// Bind click event to the button
|
// Bind click event to the button
|
||||||
function setupThemeToggle() {
|
function setupThemeToggle() {
|
||||||
// Add reduce-motion class if enabled in config
|
|
||||||
if (reduceMotion) {
|
|
||||||
document.documentElement.classList.add('reduce-motion')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locate theme toggle button
|
// Locate theme toggle button
|
||||||
const themeToggleButton = document.getElementById('theme-toggle-button')
|
const themeToggleButton = document.getElementById('theme-toggle-button')
|
||||||
// Add click listener to the button
|
// Add click listener to the button
|
||||||
if (themeToggleButton) {
|
if (themeToggleButton) {
|
||||||
themeToggleButton.addEventListener('click', () => {
|
themeToggleButton.addEventListener('click', () => {
|
||||||
// If reduceMotion is enabled or browser doesn't support View Transitions API, update theme directly
|
// If reduceMotion is enabled or browser doesn't support View Transitions API, update theme directly
|
||||||
if (reduceMotion || !document.startViewTransition) {
|
if (document.documentElement.classList.contains('reduce-motion') || !document.startViewTransition) {
|
||||||
updateTheme()
|
updateTheme()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,9 @@ function setupPostPageAnimation() {
|
||||||
if (isLargeScreen) {
|
if (isLargeScreen) {
|
||||||
// Post Content + Tags + Comments
|
// Post Content + Tags + Comments
|
||||||
// First 15 elements
|
// First 15 elements
|
||||||
gsap.from(allElements.slice(0, 15), {
|
gsap.to(allElements.slice(0, 15), {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '3rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -34,9 +34,9 @@ function setupPostPageAnimation() {
|
||||||
})
|
})
|
||||||
// Rest elements as the 16th element
|
// Rest elements as the 16th element
|
||||||
if (allElements.length > 15) {
|
if (allElements.length > 15) {
|
||||||
gsap.from(allElements.slice(15), {
|
gsap.to(allElements.slice(15), {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '3rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2 + 0.05 * 15,
|
delay: 0.2 + 0.05 * 15,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -45,9 +45,9 @@ function setupPostPageAnimation() {
|
||||||
|
|
||||||
// Post Date
|
// Post Date
|
||||||
if (dateElement) {
|
if (dateElement) {
|
||||||
gsap.from(dateElement, {
|
gsap.to(dateElement, {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '1.5rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -56,9 +56,9 @@ function setupPostPageAnimation() {
|
||||||
|
|
||||||
// TOC Icon
|
// TOC Icon
|
||||||
if (tocIcon) {
|
if (tocIcon) {
|
||||||
gsap.from(tocIcon, {
|
gsap.to(tocIcon, {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '0.5rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -67,9 +67,9 @@ function setupPostPageAnimation() {
|
||||||
|
|
||||||
// Toc List
|
// Toc List
|
||||||
if (tocListChildren.length > 0) {
|
if (tocListChildren.length > 0) {
|
||||||
gsap.from(tocListChildren, {
|
gsap.to(tocListChildren, {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '1.5rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -79,9 +79,9 @@ function setupPostPageAnimation() {
|
||||||
|
|
||||||
// Back Button
|
// Back Button
|
||||||
if (backButton) {
|
if (backButton) {
|
||||||
gsap.from(backButton, {
|
gsap.to(backButton, {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
x: '0.5rem',
|
x: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -91,9 +91,9 @@ function setupPostPageAnimation() {
|
||||||
else {
|
else {
|
||||||
// Post Content + Tags + Comments
|
// Post Content + Tags + Comments
|
||||||
// First 7 elements
|
// First 7 elements
|
||||||
gsap.from(allElements.slice(0, 7), {
|
gsap.to(allElements.slice(0, 7), {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '3rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
@ -113,9 +113,9 @@ function setupPostPageAnimation() {
|
||||||
|
|
||||||
// Mobile Animation (for screens smaller than 1536px)
|
// Mobile Animation (for screens smaller than 1536px)
|
||||||
if (isSmallScreen && tocContainer) {
|
if (isSmallScreen && tocContainer) {
|
||||||
gsap.from(tocContainer, {
|
gsap.to(tocContainer, {
|
||||||
opacity: 0,
|
opacity: 1,
|
||||||
y: '3rem',
|
y: 0,
|
||||||
duration: 0.5,
|
duration: 0.5,
|
||||||
delay: 0.15,
|
delay: 0.15,
|
||||||
ease: 'power2.out',
|
ease: 'power2.out',
|
||||||
|
|
|
@ -33,7 +33,11 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||||
|
|
||||||
<html
|
<html
|
||||||
lang={Astro.currentLocale}
|
lang={Astro.currentLocale}
|
||||||
class:list={[fontStyle, { 'scroll-smooth': isPost }]}
|
class:list={[
|
||||||
|
fontStyle,
|
||||||
|
{ 'scroll-smooth': isPost },
|
||||||
|
{ 'reduce-motion': themeConfig.global.reduceMotion },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Head {postTitle} {postDescription} {postSlug} />
|
<Head {postTitle} {postDescription} {postSlug} />
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -35,3 +35,27 @@ html[data-theme-changing] [data-disable-theme-transition] {
|
||||||
html.reduce-motion {
|
html.reduce-motion {
|
||||||
--at-apply: 'transition-colors duration-300 ease-out';
|
--at-apply: 'transition-colors duration-300 ease-out';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GSAP Animation Elements Initial States */
|
||||||
|
html:not(.reduce-motion) #gsap-post-page-content > *,
|
||||||
|
html:not(.reduce-motion) #gsap-post-page-tags,
|
||||||
|
html:not(.reduce-motion) #waline {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(3rem);
|
||||||
|
}
|
||||||
|
html:not(.reduce-motion) #gsap-post-page-date {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(1.5rem);
|
||||||
|
}
|
||||||
|
html:not(.reduce-motion) #back-button {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(0.5rem);
|
||||||
|
}
|
||||||
|
html:not(.reduce-motion) #toc-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(0.5rem);
|
||||||
|
}
|
||||||
|
html:not(.reduce-motion) #toc-list > * {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(1.5rem);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue