strip theme transition on load to use early script
This commit is contained in:
@@ -35,18 +35,13 @@
|
|||||||
|
|
||||||
if (themeToggle && overlay) {
|
if (themeToggle && overlay) {
|
||||||
themeToggle.addEventListener('click', () => {
|
themeToggle.addEventListener('click', () => {
|
||||||
// Add transitioning class to optimize performance
|
|
||||||
document.documentElement.classList.add('theme-transitioning');
|
document.documentElement.classList.add('theme-transitioning');
|
||||||
|
|
||||||
// Fade in overlay
|
|
||||||
overlay.style.opacity = '0.15';
|
overlay.style.opacity = '0.15';
|
||||||
overlay.style.transition = 'opacity 0.3s ease';
|
overlay.style.transition = 'opacity 0.3s ease';
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Fade out overlay
|
|
||||||
overlay.style.opacity = '0';
|
overlay.style.opacity = '0';
|
||||||
|
|
||||||
// Remove transitioning class after animation completes
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.documentElement.classList.remove('theme-transitioning');
|
document.documentElement.classList.remove('theme-transitioning');
|
||||||
}, 700);
|
}, 700);
|
||||||
|
@@ -52,19 +52,6 @@
|
|||||||
function setupThemeToggle() {
|
function setupThemeToggle() {
|
||||||
const themeToggles = document.querySelectorAll('[data-theme-toggle]');
|
const themeToggles = document.querySelectorAll('[data-theme-toggle]');
|
||||||
|
|
||||||
// Check for dark mode preference at the system level
|
|
||||||
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
||||||
|
|
||||||
// Check for saved theme preference or use the system preference
|
|
||||||
const currentTheme = localStorage.getItem('theme') || (prefersDarkMode ? 'dark' : 'light');
|
|
||||||
|
|
||||||
// Apply the theme on initial load
|
|
||||||
if (currentTheme === 'dark') {
|
|
||||||
document.documentElement.classList.add('dark');
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove('dark');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create theme switch overlay element if it doesn't exist
|
// Create theme switch overlay element if it doesn't exist
|
||||||
if (!document.querySelector('.theme-switch-overlay')) {
|
if (!document.querySelector('.theme-switch-overlay')) {
|
||||||
const overlay = document.createElement('div');
|
const overlay = document.createElement('div');
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
import Layout from './Layout.astro';
|
|
||||||
|
|
||||||
import directus from '../../lib/directus';
|
|
||||||
import { readSingleton } from '@directus/sdk';
|
|
||||||
|
|
||||||
const global = await directus.request(readSingleton('global'));
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
title: string;
|
|
||||||
description?: string;
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title={global.title} description={global.title}>
|
|
||||||
<slot />
|
|
||||||
</Layout>
|
|
@@ -15,45 +15,3 @@ export interface Props {
|
|||||||
<Layout title={global.title} description={global.title}>
|
<Layout title={global.title} description={global.title}>
|
||||||
<slot />
|
<slot />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const themeToggle = document.getElementById('theme-toggle');
|
|
||||||
|
|
||||||
if (themeToggle) {
|
|
||||||
themeToggle.addEventListener('click', () => {
|
|
||||||
document.documentElement.classList.add('theme-switching');
|
|
||||||
|
|
||||||
const rippleElements = document.querySelectorAll('.theme-ripple');
|
|
||||||
rippleElements.forEach((el) => {
|
|
||||||
el.classList.add('ripple-active');
|
|
||||||
setTimeout(() => {
|
|
||||||
el.classList.remove('ripple-active');
|
|
||||||
}, 600);
|
|
||||||
});
|
|
||||||
|
|
||||||
const event = new CustomEvent('themeChange', {
|
|
||||||
detail: {
|
|
||||||
theme: document.documentElement.classList.contains('dark') ? 'dark' : 'light',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
document.dispatchEvent(event);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
document.documentElement.classList.remove('theme-switching');
|
|
||||||
}, 600);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const socialLinks = document.querySelectorAll('.social-link');
|
|
||||||
socialLinks.forEach((link) => {
|
|
||||||
link.addEventListener('mouseenter', () => {
|
|
||||||
link.classList.add('hover-active');
|
|
||||||
});
|
|
||||||
|
|
||||||
link.addEventListener('mouseleave', () => {
|
|
||||||
link.classList.remove('hover-active');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
@@ -27,16 +27,29 @@ const { title, description } = Astro.props;
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
|
<!-- Load theme early to prevent flashes between light and dark modes -->
|
||||||
|
<script is:inline>
|
||||||
|
const theme = (() => {
|
||||||
|
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||||
|
return localStorage.getItem('theme');
|
||||||
|
}
|
||||||
|
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
return 'dark';
|
||||||
|
}
|
||||||
|
return 'light';
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (theme === 'light') {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
}
|
||||||
|
window.localStorage.setItem('theme', theme);
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
class="flex min-h-screen flex-col bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100"
|
class="flex min-h-screen flex-col bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<!-- Page transition overlay - for smooth transitions between pages -->
|
|
||||||
<div
|
|
||||||
class="pointer-events-none fixed inset-0 z-40 flex items-center justify-center bg-white opacity-0 transition-opacity duration-300 dark:bg-zinc-900"
|
|
||||||
>
|
|
||||||
<div class="transition-spinner"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Background component with dot pattern and ambient glow -->
|
<!-- Background component with dot pattern and ambient glow -->
|
||||||
<Background />
|
<Background />
|
||||||
@@ -48,36 +61,6 @@ const { title, description } = Astro.props;
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
<script>
|
|
||||||
// Theme handling with transition effects
|
|
||||||
function setupThemeHandling() {
|
|
||||||
// Apply theme from localStorage or system preference
|
|
||||||
const theme = localStorage.getItem('theme');
|
|
||||||
if (
|
|
||||||
theme === 'dark' ||
|
|
||||||
(!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
||||||
) {
|
|
||||||
document.documentElement.classList.add('dark');
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove('dark');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for theme changes
|
|
||||||
document.addEventListener('themeChanged', () => {
|
|
||||||
// Add transition class to body
|
|
||||||
document.body.classList.add('theme-transitioning');
|
|
||||||
|
|
||||||
// Remove class after transition completes
|
|
||||||
setTimeout(() => {
|
|
||||||
document.body.classList.remove('theme-transitioning');
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize theme handling
|
|
||||||
document.addEventListener('DOMContentLoaded', setupThemeHandling);
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user