mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-15 19:22:52 +02:00
✨ feat: add reducemotion config option to optimize performance
- Add `reduceMotion` option in theme config to improve performance - Update Button component to support reduced animations - Modify GSAP animation logic to adapt to the new configuration - Update documentation to reflect the new feature
This commit is contained in:
parent
120ebbbb3f
commit
4d247cfb93
12 changed files with 77 additions and 42 deletions
|
@ -10,6 +10,7 @@ interface Props {
|
|||
}
|
||||
|
||||
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||||
const reduceMotion = themeConfig.global.reduceMotion
|
||||
|
||||
const { supportedLangs } = Astro.props
|
||||
const currentPath = Astro.url.pathname
|
||||
|
@ -61,7 +62,10 @@ const nextUrl = useSupportedLangs
|
|||
</div>
|
||||
|
||||
<!-- Theme Toggle Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
<script is:inline define:vars={{ lightMode, darkMode }}>
|
||||
<script
|
||||
is:inline
|
||||
define:vars={{ lightMode, darkMode, reduceMotion }}
|
||||
>
|
||||
// Update theme
|
||||
function updateTheme() {
|
||||
// Toggle website theme
|
||||
|
@ -82,13 +86,18 @@ function updateTheme() {
|
|||
|
||||
// Bind click event to the button
|
||||
function setupThemeToggle() {
|
||||
// Add reduce-motion class if enabled in config
|
||||
if (reduceMotion) {
|
||||
document.documentElement.classList.add('reduce-motion')
|
||||
}
|
||||
|
||||
// Locate theme toggle button
|
||||
const themeToggleButton = document.getElementById('theme-toggle-button')
|
||||
// Add click listener to the button
|
||||
if (themeToggleButton) {
|
||||
themeToggleButton.addEventListener('click', () => {
|
||||
// If browser doesn't support View Transitions API, update theme directly
|
||||
if (!document.startViewTransition) {
|
||||
// If reduceMotion is enabled or browser doesn't support View Transitions API, update theme directly
|
||||
if (reduceMotion || !document.startViewTransition) {
|
||||
updateTheme()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,13 +2,22 @@
|
|||
import { gsap } from 'gsap'
|
||||
|
||||
function setupPostPageAnimation() {
|
||||
const allElements = Array.from(document.querySelectorAll('#gsap-post-page-content > *, #gsap-post-page-tags, #waline'))
|
||||
// Post Content + Tags + Comments
|
||||
const postContent = document.getElementById('gsap-post-page-content')
|
||||
const postContentChildren = postContent ? Array.from(postContent.children) : []
|
||||
const tagsElement = document.getElementById('gsap-post-page-tags')
|
||||
const walineElement = document.getElementById('waline')
|
||||
const allElements = [...postContentChildren, tagsElement, walineElement].filter(Boolean)
|
||||
|
||||
// TOC + Date + Back Button + TOC Icon
|
||||
const tocList = document.getElementById('toc-list')
|
||||
const tocListChildren = tocList ? Array.from(tocList.children) : []
|
||||
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')
|
||||
|
||||
// Screen Size Check
|
||||
const isLargeScreen = window.matchMedia('(min-width: 1024px)').matches
|
||||
const isSmallScreen = window.matchMedia('(max-width: 1535px)').matches
|
||||
|
||||
|
@ -81,8 +90,8 @@ function setupPostPageAnimation() {
|
|||
}
|
||||
else {
|
||||
// Post Content + Tags + Comments
|
||||
// First 7 elements
|
||||
gsap.from(allElements.slice(0, 7), {
|
||||
// First 5 elements
|
||||
gsap.from(allElements.slice(0, 5), {
|
||||
opacity: 0,
|
||||
y: '3rem',
|
||||
duration: 0.5,
|
||||
|
@ -90,16 +99,16 @@ function setupPostPageAnimation() {
|
|||
ease: 'power2.out',
|
||||
stagger: 0.05,
|
||||
})
|
||||
// Rest elements as the 8 element
|
||||
if (allElements.length > 7) {
|
||||
gsap.from(allElements.slice(7), {
|
||||
opacity: 0,
|
||||
y: '3rem',
|
||||
duration: 0.5,
|
||||
delay: 0.2 + 0.05 * 5,
|
||||
ease: 'power2.out',
|
||||
})
|
||||
}
|
||||
// Rest elements as the 6 element
|
||||
// if (allElements.length > 5) {
|
||||
// gsap.from(allElements.slice(7), {
|
||||
// opacity: 0,
|
||||
// y: '3rem',
|
||||
// duration: 0.5,
|
||||
// delay: 0.2 + 0.05 * 5,
|
||||
// ease: 'power2.out',
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
// Mobile Animation (for screens smaller than 1536px)
|
||||
|
|
|
@ -58,10 +58,12 @@ export const themeConfig: ThemeConfig = {
|
|||
fontStyle: 'sans', // sans, serif
|
||||
// date format for posts
|
||||
dateFormat: 'YYYY-MM-DD', // YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
// enable KaTeX for mathematical formulas rendering
|
||||
katex: true, // true, false
|
||||
// enable table of contents for all posts by default
|
||||
toc: true, // true, false
|
||||
// enable KaTeX for mathematical formulas rendering
|
||||
katex: true, // true, false
|
||||
// reduce animations and transitions to improve performance
|
||||
reduceMotion: false, // true, false
|
||||
},
|
||||
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
||||
|
||||
|
@ -143,7 +145,7 @@ export const themeConfig: ThemeConfig = {
|
|||
{
|
||||
name: 'Email',
|
||||
url: 'email@radishzz.cc',
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: 'X',
|
||||
// url: 'https://x.com/radishzz_',
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// enable KaTeX for mathematical formulas rendering
|
||||
katex: true // true, false
|
||||
// enable table of contents for all posts by default
|
||||
toc: true // true, false
|
||||
// enable KaTeX for mathematical formulas rendering
|
||||
katex: true // true, false
|
||||
// reduce animations and transitions to improve performance
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ Pins the article to the top. The higher the number, the higher the priority of t
|
|||
|
||||
#### toc
|
||||
|
||||
Generate table of contents. Shows h2 to h4 headings. Uses the global `global.toc` configuration by default, but can be overridden individually in each article.
|
||||
Generate table of contents. Shows h2 to h4 headings. Determined by the global configuration `global.toc` by default, but can be overridden individually in each article.
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// habilitar KaTeX para renderizar fórmulas matemáticas
|
||||
katex: true // true, false
|
||||
// habilitar tabla de contenidos para todos los artículos por defecto
|
||||
toc: true // true, false
|
||||
// habilitar KaTeX para renderizar fórmulas matemáticas
|
||||
katex: true // true, false
|
||||
// reducir animaciones y transiciones para mejorar el rendimiento
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ Fija el artículo en la parte superior. Cuanto mayor sea el número, mayor será
|
|||
|
||||
#### toc
|
||||
|
||||
Genera tabla de contenidos. Muestra encabezados de h2 a h4. Utiliza la configuración global `global.toc` por defecto, pero puede ser modificada individualmente en cada artículo.
|
||||
Genera tabla de contenidos. Muestra encabezados de h2 a h4. Determinado por la configuración global `global.toc` por defecto, pero puede ser modificada individualmente en cada artículo.
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// 数式表示のためのKaTeXを有効化
|
||||
katex: true // true, false
|
||||
// デフォルトですべての記事に目次を表示
|
||||
toc: true // true, false
|
||||
// 数式表示のためのKaTeXを有効化
|
||||
katex: true // true, false
|
||||
// アニメーションと遷移効果を減らしてパフォーマンスを向上させる
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ abbrlink: theme-guide
|
|||
|
||||
#### toc
|
||||
|
||||
目次を生成するかどうか。h2からh4までの見出しを表示します。デフォルトではグローバル設定 `global.toc` を使用しますが、記事ごとに個別に設定することも可能です。
|
||||
目次を生成するかどうか。h2からh4までの見出しを表示します。デフォルトではグローバル設定項目 `global.toc` によって決定されますが、記事ごとに個別に設定して上書きすることもできます。
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// включить KaTeX для отображения математических формул
|
||||
katex: true // true, false
|
||||
// включить оглавление для всех статей по умолчанию
|
||||
toc: true // true, false
|
||||
// включить KaTeX для отображения математических формул
|
||||
katex: true // true, false
|
||||
// уменьшить анимации и переходы для повышения производительности
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ abbrlink: theme-guide
|
|||
|
||||
#### toc
|
||||
|
||||
Генерировать оглавление. Показывает заголовки от h2 до h4. По умолчанию использует глобальный параметр `global.toc`, но может быть изменен индивидуально в каждой статье.
|
||||
Генерировать оглавление. Показывает заголовки от h2 до h4. По умолчанию определяется глобальным параметром `global.toc`, но может быть изменен индивидуально в каждой статье.
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// 啟用 KaTeX 數學公式渲染
|
||||
katex: true // true, false
|
||||
// 預設為所有文章開啟目錄
|
||||
toc: true // true, false
|
||||
// 啟用 KaTeX 數學公式渲染
|
||||
katex: true // true, false
|
||||
// 減少動畫和過渡效果以提高性能
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ abbrlink: theme-guide
|
|||
|
||||
#### toc
|
||||
|
||||
是否生成目錄。顯示 h2 至 h4 標題。預設為全域配置 `global.toc` 的選項,可在文章中單獨設定以覆蓋全域配置。
|
||||
是否生成目錄。顯示 h2 至 h4 標題。預設由全域配置項 `global.toc` 決定,可在文章中單獨設定以覆蓋全域配置。
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -84,10 +84,12 @@ global: {
|
|||
// 2025-04-13, 04-13-2025, 13-04-2025, Apr 13 2025,13 Apr 2025
|
||||
// YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||
dateFormat: 'YYYY-MM-DD'
|
||||
// 启用 KaTeX 数学公式渲染
|
||||
katex: true // true, false
|
||||
// 默认为所有文章开启目录
|
||||
toc: true // true, false
|
||||
// 启用 KaTeX 数学公式渲染
|
||||
katex: true // true, false
|
||||
// 减少动画和过渡效果以提高性能
|
||||
reduceMotion: false // true, false
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,7 +319,7 @@ abbrlink: theme-guide
|
|||
|
||||
#### toc
|
||||
|
||||
是否生成目录。显示 h2 至 h4 标题。默认为全局配置 `global.toc` 的选项,可在文章中单独设置以覆盖全局配置。
|
||||
是否生成目录。显示 h2 至 h4 标题。默认由全局配置项 `global.toc` 决定,可在文章中单独设置以覆盖全局配置。
|
||||
|
||||
#### lang
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ interface Props {
|
|||
const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
|
||||
const { isPost } = getPageInfo(Astro.url.pathname)
|
||||
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
||||
const showAnimation = !themeConfig.global.reduceMotion
|
||||
const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||
? 'mb-10' // Post page with comments
|
||||
: 'mb-12' // Other pages without comments
|
||||
|
@ -48,11 +49,9 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
|
|||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
<GsapAnimation />
|
||||
{showAnimation && <GsapAnimation />}
|
||||
<Button supportedLangs={supportedLangs} />
|
||||
<GithubCard />
|
||||
<PhotoSwipe />
|
||||
<!-- Fix bottom space being cut off before page transition on mobile -->
|
||||
<div class="fixed bottom-0 w-full"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,9 +26,12 @@ html[data-theme-changing] [data-disable-theme-transition] {
|
|||
view-transition-name: none !important;
|
||||
}
|
||||
|
||||
/* Fallback animation when view-transition-name is not supported */
|
||||
/* Fallback transition for browsers not supporting view-transitions or when reduceMotion enabled */
|
||||
@supports not (view-transition-name: none) {
|
||||
html {
|
||||
--at-apply: 'transition-colors duration-300 ease-out';
|
||||
}
|
||||
}
|
||||
html.reduce-motion {
|
||||
--at-apply: 'transition-colors duration-300 ease-out';
|
||||
}
|
3
src/types/index.d.ts
vendored
3
src/types/index.d.ts
vendored
|
@ -33,8 +33,9 @@ export interface ThemeConfig {
|
|||
moreLocales: typeof supportedLangs[number][]
|
||||
fontStyle: 'sans' | 'serif'
|
||||
dateFormat: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MONTH DAY YYYY' | 'DAY MONTH YYYY'
|
||||
katex: boolean
|
||||
toc: boolean
|
||||
katex: boolean
|
||||
reduceMotion: boolean
|
||||
}
|
||||
|
||||
comment: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue