removed parallax, added flags to footer
This commit is contained in:
@@ -7,7 +7,7 @@ export interface Props {
|
|||||||
disableParallax?: boolean;
|
disableParallax?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { isDark = false, showIcons = true, disableParallax = false } = Astro.props;
|
const { isDark = false, showIcons = true, disableParallax = true } = Astro.props;
|
||||||
|
|
||||||
// Define color palettes for light and dark modes with higher contrast
|
// Define color palettes for light and dark modes with higher contrast
|
||||||
const lightModeColors = [
|
const lightModeColors = [
|
||||||
@@ -22,14 +22,14 @@ const lightModeColors = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const darkModeColors = [
|
const darkModeColors = [
|
||||||
'dark:text-blue-400/45',
|
'dark:text-blue-500/65',
|
||||||
'dark:text-indigo-400/45',
|
'dark:text-indigo-500/65',
|
||||||
'dark:text-purple-400/45',
|
'dark:text-purple-500/65',
|
||||||
'dark:text-cyan-400/45',
|
'dark:text-cyan-500/65',
|
||||||
'dark:text-teal-400/45',
|
'dark:text-teal-500/65',
|
||||||
'dark:text-emerald-400/45',
|
'dark:text-emerald-500/65',
|
||||||
'dark:text-sky-400/45',
|
'dark:text-sky-500/65',
|
||||||
'dark:text-violet-400/45',
|
'dark:text-violet-500/65',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Define interfaces for our icon objects
|
// Define interfaces for our icon objects
|
||||||
@@ -98,14 +98,20 @@ const getRandomRotation = (): string => {
|
|||||||
return `${getRandomInRange(-30, 30)}deg`;
|
return `${getRandomInRange(-30, 30)}deg`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to get a random size (restored to original dimensions)
|
// Function to get a random size
|
||||||
const getRandomSize = (): string => {
|
const getRandomSize = (isDarkMode: boolean = false): string => {
|
||||||
return `${getRandomInRange(140, 180)}px`;
|
// Slightly larger size range for dark mode for better visibility
|
||||||
|
return isDarkMode
|
||||||
|
? `${getRandomInRange(160, 200)}px`
|
||||||
|
: `${getRandomInRange(140, 180)}px`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to get a random opacity
|
// Function to get a random opacity
|
||||||
const getRandomOpacity = (): string => {
|
const getRandomOpacity = (isDarkMode: boolean = false): string => {
|
||||||
return getRandomInRange(0.32, 0.38).toFixed(2);
|
// Higher opacity range for dark mode for better visibility
|
||||||
|
return isDarkMode
|
||||||
|
? getRandomInRange(0.45, 0.55).toFixed(2)
|
||||||
|
: getRandomInRange(0.32, 0.38).toFixed(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a spacious layout with well-separated icons
|
// Create a spacious layout with well-separated icons
|
||||||
@@ -172,8 +178,8 @@ const createSpacedIcons = (): BaseIconObject[] => {
|
|||||||
icon: iconNames[iconIndex],
|
icon: iconNames[iconIndex],
|
||||||
x: `${x}%`,
|
x: `${x}%`,
|
||||||
y: `${y}%`,
|
y: `${y}%`,
|
||||||
size: getRandomSize(),
|
size: getRandomSize(isDark),
|
||||||
opacity: getRandomOpacity(),
|
opacity: getRandomOpacity(isDark),
|
||||||
rotate: getRandomRotation(),
|
rotate: getRandomRotation(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -200,15 +206,12 @@ const iconsWithColors: IconWithColors[] = icons.map(icon => ({
|
|||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
{showIcons && (
|
{showIcons && (
|
||||||
/* Decorative background icons with parallax effect */
|
/* Decorative background icons with random placement */
|
||||||
<div id="parallax-background" class="absolute inset-0 overflow-hidden pointer-events-none z-[-5]">
|
<div id="background-icons" class="absolute inset-0 overflow-hidden pointer-events-none z-[-5]">
|
||||||
{iconsWithColors.map(({ icon, x, y, size, opacity, rotate, lightColor, darkColor }, index) => (
|
{iconsWithColors.map(({ icon, x, y, size, opacity, rotate, lightColor, darkColor }) => (
|
||||||
<div
|
<div
|
||||||
class={`absolute ${lightColor} ${darkColor} parallax-icon`}
|
class={`absolute ${lightColor} ${darkColor} background-icon`}
|
||||||
style={`left: ${x}; top: ${y}; opacity: ${opacity}; transform: rotate(${rotate}); will-change: transform; transition: transform 0.1s ease-out;`}
|
style={`left: ${x}; top: ${y}; opacity: ${opacity}; transform: rotate(${rotate});`}
|
||||||
data-depth={`${0.5 + (index % 3) * 0.2}`}
|
|
||||||
data-initial-x={x}
|
|
||||||
data-initial-y={y}
|
|
||||||
>
|
>
|
||||||
<Icon name={icon} style={`width: ${size}; height: ${size};`} />
|
<Icon name={icon} style={`width: ${size}; height: ${size};`} />
|
||||||
</div>
|
</div>
|
||||||
|
@@ -20,14 +20,14 @@ const lightModeColors = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const darkModeColors = [
|
const darkModeColors = [
|
||||||
'dark:text-blue-400/45',
|
'dark:text-blue-500/65',
|
||||||
'dark:text-indigo-400/45',
|
'dark:text-indigo-500/65',
|
||||||
'dark:text-purple-400/45',
|
'dark:text-purple-500/65',
|
||||||
'dark:text-cyan-400/45',
|
'dark:text-cyan-500/65',
|
||||||
'dark:text-teal-400/45',
|
'dark:text-teal-500/65',
|
||||||
'dark:text-emerald-400/45',
|
'dark:text-emerald-500/65',
|
||||||
'dark:text-sky-400/45',
|
'dark:text-sky-500/65',
|
||||||
'dark:text-violet-400/45',
|
'dark:text-violet-500/65',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Define interfaces for our icon objects
|
// Define interfaces for our icon objects
|
||||||
@@ -99,13 +99,19 @@ const getRandomRotation = (): string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Function to get a random size
|
// Function to get a random size
|
||||||
const getRandomSize = (): string => {
|
const getRandomSize = (isDarkMode: boolean = false): string => {
|
||||||
return `${getRandomInRange(140, 180)}px`;
|
// Slightly larger size range for dark mode for better visibility
|
||||||
|
return isDarkMode
|
||||||
|
? `${getRandomInRange(160, 200)}px`
|
||||||
|
: `${getRandomInRange(140, 180)}px`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to get a random opacity
|
// Function to get a random opacity
|
||||||
const getRandomOpacity = (): string => {
|
const getRandomOpacity = (isDarkMode: boolean = false): string => {
|
||||||
return getRandomInRange(0.32, 0.38).toFixed(2);
|
// Higher opacity range for dark mode for better visibility
|
||||||
|
return isDarkMode
|
||||||
|
? getRandomInRange(0.45, 0.55).toFixed(2)
|
||||||
|
: getRandomInRange(0.32, 0.38).toFixed(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a spacious layout with well-separated icons
|
// Create a spacious layout with well-separated icons
|
||||||
@@ -188,8 +194,8 @@ const createSpacedIcons = (): BaseIconObject[] => {
|
|||||||
icon: iconNames[iconIndex],
|
icon: iconNames[iconIndex],
|
||||||
x: `${x}%`,
|
x: `${x}%`,
|
||||||
y: `${y}%`,
|
y: `${y}%`,
|
||||||
size: getRandomSize(),
|
size: getRandomSize(isDark),
|
||||||
opacity: getRandomOpacity(),
|
opacity: getRandomOpacity(isDark),
|
||||||
rotate: getRandomRotation(),
|
rotate: getRandomRotation(),
|
||||||
visibilityClass, // Add the visibility class to the icon object
|
visibilityClass, // Add the visibility class to the icon object
|
||||||
});
|
});
|
||||||
@@ -219,15 +225,12 @@ const iconsWithColors: IconWithColors[] = icons.map(icon => ({
|
|||||||
<div class="fixed inset-0 overflow-hidden pointer-events-none z-[-5]" aria-hidden="true">
|
<div class="fixed inset-0 overflow-hidden pointer-events-none z-[-5]" aria-hidden="true">
|
||||||
<div class:list={['absolute inset-0', { 'backdrop-blur-sm bg-white/5 dark:bg-gray-900/10': isDark }]}></div>
|
<div class:list={['absolute inset-0', { 'backdrop-blur-sm bg-white/5 dark:bg-gray-900/10': isDark }]}></div>
|
||||||
|
|
||||||
{/* Decorative background icons with parallax effect */}
|
{/* Decorative background icons with random placement */}
|
||||||
<div id="parallax-background" class="absolute inset-0 overflow-hidden">
|
<div id="background-icons" class="absolute inset-0 overflow-hidden">
|
||||||
{iconsWithColors.map(({ icon, x, y, size, opacity, rotate, lightColor, darkColor, visibilityClass }, index) => (
|
{iconsWithColors.map(({ icon, x, y, size, opacity, rotate, lightColor, darkColor, visibilityClass }) => (
|
||||||
<div
|
<div
|
||||||
class={`absolute ${lightColor} ${darkColor} parallax-icon ${visibilityClass}`}
|
class={`absolute ${lightColor} ${darkColor} ${visibilityClass}`}
|
||||||
style={`left: ${x}; top: ${y}; opacity: ${opacity}; transform: rotate(${rotate}); will-change: transform; transition: transform 0.1s ease-out;`}
|
style={`left: ${x}; top: ${y}; opacity: ${opacity}; transform: rotate(${rotate});`}
|
||||||
data-depth={`${0.5 + (index % 3) * 0.2}`}
|
|
||||||
data-initial-x={x}
|
|
||||||
data-initial-y={y}
|
|
||||||
>
|
>
|
||||||
<Icon name={icon} style={`width: ${size}; height: ${size};`} />
|
<Icon name={icon} style={`width: ${size}; height: ${size};`} />
|
||||||
</div>
|
</div>
|
||||||
@@ -235,82 +238,4 @@ const iconsWithColors: IconWithColors[] = icons.map(icon => ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<!-- Parallax effect removed while maintaining random icon placement -->
|
||||||
// Parallax scrolling effect for background icons
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
// Get all parallax icons
|
|
||||||
const parallaxIcons = document.querySelectorAll<HTMLElement>('.parallax-icon');
|
|
||||||
|
|
||||||
// Skip parallax on mobile devices for better performance
|
|
||||||
const isMobile = window.matchMedia('(max-width: 768px)').matches;
|
|
||||||
if (isMobile) return;
|
|
||||||
|
|
||||||
// Variables to track scroll position
|
|
||||||
let lastScrollY = window.scrollY;
|
|
||||||
let ticking = false;
|
|
||||||
|
|
||||||
// Function to update icon positions based on scroll
|
|
||||||
const updateParallax = () => {
|
|
||||||
parallaxIcons.forEach((icon) => {
|
|
||||||
const depth = parseFloat(icon.getAttribute('data-depth') || '0.5');
|
|
||||||
|
|
||||||
// Calculate parallax offset based on scroll position and depth
|
|
||||||
// Lower depth value means the icon moves slower (appears further away)
|
|
||||||
const yOffset = (lastScrollY * depth * 0.15);
|
|
||||||
|
|
||||||
// Get the original rotation
|
|
||||||
const transformValue = icon.style.transform;
|
|
||||||
const rotateMatch = transformValue.match(/rotate\([^)]+\)/);
|
|
||||||
const rotateValue = rotateMatch ? rotateMatch[0] : 'rotate(0deg)';
|
|
||||||
|
|
||||||
// Apply transform with the original rotation plus the parallax offset
|
|
||||||
icon.style.transform = `${rotateValue} translate3d(0, ${yOffset}px, 0)`;
|
|
||||||
});
|
|
||||||
|
|
||||||
ticking = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Throttle scroll events for better performance
|
|
||||||
const onScroll = () => {
|
|
||||||
lastScrollY = window.scrollY;
|
|
||||||
|
|
||||||
if (!ticking) {
|
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
updateParallax();
|
|
||||||
ticking = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
ticking = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add scroll event listener
|
|
||||||
window.addEventListener('scroll', onScroll, { passive: true });
|
|
||||||
|
|
||||||
// Update on resize (debounced)
|
|
||||||
let resizeTimer: number;
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
clearTimeout(resizeTimer);
|
|
||||||
resizeTimer = setTimeout(() => {
|
|
||||||
// Check if device is now mobile and disable parallax if needed
|
|
||||||
const isMobileNow = window.matchMedia('(max-width: 768px)').matches;
|
|
||||||
|
|
||||||
if (isMobileNow) {
|
|
||||||
// Reset positions on mobile
|
|
||||||
parallaxIcons.forEach((icon) => {
|
|
||||||
const transformValue = icon.style.transform;
|
|
||||||
const rotateMatch = transformValue.match(/rotate\([^)]+\)/);
|
|
||||||
const rotateValue = rotateMatch ? rotateMatch[0] : 'rotate(0deg)';
|
|
||||||
icon.style.transform = rotateValue;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Update parallax on desktop
|
|
||||||
updateParallax();
|
|
||||||
}
|
|
||||||
}, 200) as unknown as number;
|
|
||||||
}, { passive: true });
|
|
||||||
|
|
||||||
// Initial update
|
|
||||||
updateParallax();
|
|
||||||
});
|
|
||||||
</script>
|
|
@@ -76,8 +76,13 @@ const {
|
|||||||
<!-- Left Section: Company Name and Business Details -->
|
<!-- Left Section: Company Name and Business Details -->
|
||||||
<div class="flex flex-col items-start space-y-2">
|
<div class="flex flex-col items-start space-y-2">
|
||||||
<!-- Site Title -->
|
<!-- Site Title -->
|
||||||
<a class="inline-block font-bold text-xl" href={getHomePermalink(currentLang)}>
|
<a class="inline-block font-bold text-2xl" href={getHomePermalink(currentLang)}>
|
||||||
{SITE?.name}
|
{SITE?.name}
|
||||||
|
<span class="inline-flex items-center ml-2">
|
||||||
|
<Icon name="circle-flags:nl" class="h-5 w-auto flag-square" />
|
||||||
|
<span class="mx-1 text-gray-600 text-xl">🤝</span>
|
||||||
|
<Icon name="circle-flags:eu" class="h-5 w-auto flag-square" />
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Business Information (Dutch Law Requirements) -->
|
<!-- Business Information (Dutch Law Requirements) -->
|
||||||
@@ -121,3 +126,10 @@ const {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.flag-square {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -7,8 +7,8 @@ export const getHeaderData = (lang = 'en') => {
|
|||||||
// For hash links on the homepage, we need special handling
|
// For hash links on the homepage, we need special handling
|
||||||
const homeHashLink = (hash) => {
|
const homeHashLink = (hash) => {
|
||||||
// Create an absolute path to the homepage with the language prefix
|
// Create an absolute path to the homepage with the language prefix
|
||||||
// and then append the hash
|
// and include the hash in the permalink generation
|
||||||
return getPermalink('/', 'page', lang) + hash;
|
return getPermalink('/' + hash, 'page', lang);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@@ -57,7 +57,6 @@ const metadata = {
|
|||||||
<!-- Hero Widget -->
|
<!-- Hero Widget -->
|
||||||
<Hero
|
<Hero
|
||||||
id="hero"
|
id="hero"
|
||||||
title="About Me"
|
|
||||||
isDark={false}
|
isDark={false}
|
||||||
>
|
>
|
||||||
<Fragment slot="subtitle">
|
<Fragment slot="subtitle">
|
||||||
|
@@ -85,7 +85,7 @@ const tocItems = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Privacy Policy Content -->
|
<!-- Privacy Policy Content -->
|
||||||
<div class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg">
|
<div class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg backdrop-blur-sm bg-white/15 dark:bg-slate-900/30 p-6 rounded-lg border border-gray-200 dark:border-slate-800">
|
||||||
<h2 id="introduction" class="text-2xl font-bold mt-8 mb-4">1. Introduction</h2>
|
<h2 id="introduction" class="text-2xl font-bold mt-8 mb-4">1. Introduction</h2>
|
||||||
<p>
|
<p>
|
||||||
This Privacy Policy explains how we handle information when you visit our website. We are committed to protecting your privacy and complying with applicable data protection laws, including the General Data Protection Regulation (GDPR).
|
This Privacy Policy explains how we handle information when you visit our website. We are committed to protecting your privacy and complying with applicable data protection laws, including the General Data Protection Regulation (GDPR).
|
||||||
|
@@ -83,7 +83,7 @@ const tocItems = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Terms Content -->
|
<!-- Terms Content -->
|
||||||
<div class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg">
|
<div class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg backdrop-blur-sm bg-white/15 dark:bg-slate-900/30 p-6 rounded-lg border border-gray-200 dark:border-slate-800">
|
||||||
<p>
|
<p>
|
||||||
Please read these terms and conditions carefully before using our website. By accessing or using our website, you agree to be bound by these terms and conditions.
|
Please read these terms and conditions carefully before using our website. By accessing or using our website, you agree to be bound by these terms and conditions.
|
||||||
</p>
|
</p>
|
||||||
|
Reference in New Issue
Block a user