![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/lavocat.quebec/private_html/src/components/ |
import React from 'react';
import { useTheme } from '../context/ThemeContext';
import { ThemeColors } from '../types';
// Color harmony functions
const adjustHue = (hue: number, amount: number): number => {
return (hue + amount) % 360;
};
const getComplementaryColor = (hue: number): number => {
return adjustHue(hue, 180);
};
const getAnalogousColors = (hue: number): number[] => {
return [
adjustHue(hue, -30),
adjustHue(hue, 30)
];
};
const getTriadicColors = (hue: number): number[] => {
return [
adjustHue(hue, 120),
adjustHue(hue, 240)
];
};
const getSplitComplementaryColors = (hue: number): number[] => {
return [
adjustHue(hue, 150),
adjustHue(hue, 210)
];
};
const getTetradicColors = (hue: number): number[] => {
return [
adjustHue(hue, 90),
adjustHue(hue, 180),
adjustHue(hue, 270)
];
};
const hslToHex = (h: number, s: number, l: number): string => {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = (n: number) => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return `#${f(0)}${f(8)}${f(4)}`;
};
const getRandomTheme = (): Partial<ThemeColors> => {
// Generate a base hue (0-360)
const baseHue = Math.floor(Math.random() * 360);
// Randomly choose a color harmony scheme
const schemes = [
getTriadicColors,
getSplitComplementaryColors,
getTetradicColors,
getAnalogousColors
];
const selectedScheme = schemes[Math.floor(Math.random() * schemes.length)];
const [secondaryHue, accentHue] = selectedScheme(baseHue);
// Generate gradient colors with more variation
const primaryGradientStart = hslToHex(baseHue, 70 + Math.random() * 20, 40 + Math.random() * 10);
const primaryGradientEnd = hslToHex((baseHue + 20 + Math.random() * 20) % 360, 80 + Math.random() * 10, 35 + Math.random() * 10);
const secondaryGradientStart = hslToHex(secondaryHue, 70 + Math.random() * 20, 60 + Math.random() * 10);
const secondaryGradientEnd = hslToHex((secondaryHue + 20 + Math.random() * 20) % 360, 80 + Math.random() * 10, 55 + Math.random() * 10);
const accentGradientStart = hslToHex(accentHue, 70 + Math.random() * 20, 50 + Math.random() * 10);
const accentGradientEnd = hslToHex((accentHue + 20 + Math.random() * 20) % 360, 80 + Math.random() * 10, 45 + Math.random() * 10);
return {
primary: primaryGradientStart,
'primary-dark': primaryGradientEnd,
'primary-light': hslToHex(baseHue, 60 + Math.random() * 20, 70 + Math.random() * 10),
secondary: secondaryGradientStart,
'secondary-dark': secondaryGradientEnd,
'secondary-light': hslToHex(secondaryHue, 60 + Math.random() * 20, 80 + Math.random() * 10),
accent: accentGradientStart,
'accent-dark': accentGradientEnd,
'accent-light': hslToHex(accentHue, 60 + Math.random() * 20, 75 + Math.random() * 10),
gradientStart: primaryGradientStart,
gradientEnd: primaryGradientEnd,
};
};
const ThemeCustomizer = () => {
const { setTheme } = useTheme();
const handleRandomize = () => {
const newTheme = getRandomTheme();
setTheme(newTheme);
};
return (
<button
className="fixed bottom-6 right-6 z-50 bg-primary text-background-light rounded-full shadow-lg p-4 hover:bg-primary-dark focus:outline-none"
onClick={handleRandomize}
aria-label="Randomize Theme"
>
🎲
</button>
);
};
export default ThemeCustomizer;