mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-29 18:13:47 +00:00
fix: Aurora uses theme colors from API with blur overlay
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import { useEffect, useRef, useMemo } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { Renderer, Program, Mesh, Color, Triangle } from 'ogl';
|
import { Renderer, Program, Mesh, Color, Triangle } from 'ogl';
|
||||||
import { brandingApi } from '@/api/branding';
|
import { brandingApi } from '@/api/branding';
|
||||||
|
import { ThemeSettings, DEFAULT_THEME_COLORS } from '@/types/theme';
|
||||||
|
|
||||||
const VERT = /* glsl */ `#version 300 es
|
const VERT = /* glsl */ `#version 300 es
|
||||||
in vec2 position;
|
in vec2 position;
|
||||||
@@ -77,7 +78,6 @@ const FRAG = /* glsl */ `#version 300 es
|
|||||||
void main() {
|
void main() {
|
||||||
vec2 uv = gl_FragCoord.xy / uResolution;
|
vec2 uv = gl_FragCoord.xy / uResolution;
|
||||||
|
|
||||||
// Build color stops with fixed positions - optimized for visual appeal
|
|
||||||
ColorStop cyclingColors[3];
|
ColorStop cyclingColors[3];
|
||||||
cyclingColors[0] = ColorStop(uColorStops[0], 0.0);
|
cyclingColors[0] = ColorStop(uColorStops[0], 0.0);
|
||||||
cyclingColors[1] = ColorStop(uColorStops[1], 0.5);
|
cyclingColors[1] = ColorStop(uColorStops[1], 0.5);
|
||||||
@@ -92,13 +92,6 @@ const FRAG = /* glsl */ `#version 300 es
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface AuroraProps {
|
|
||||||
colorStops?: string[];
|
|
||||||
amplitude?: number;
|
|
||||||
blend?: number;
|
|
||||||
speed?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hexToRgb(hex: string): [number, number, number] {
|
function hexToRgb(hex: string): [number, number, number] {
|
||||||
hex = hex.replace('#', '');
|
hex = hex.replace('#', '');
|
||||||
if (hex.length === 3) {
|
if (hex.length === 3) {
|
||||||
@@ -113,52 +106,35 @@ function hexToRgb(hex: string): [number, number, number] {
|
|||||||
return [r, g, b];
|
return [r, g, b];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccentColorFromCSS(): string {
|
function generateColorStops(accent: string, background: string): string[] {
|
||||||
// Get accent-500 RGB value from CSS variable
|
const [ar, ag, ab] = hexToRgb(accent);
|
||||||
const root = document.documentElement;
|
|
||||||
const accentRgb = getComputedStyle(root).getPropertyValue('--color-accent-500').trim();
|
|
||||||
|
|
||||||
if (accentRgb) {
|
// Color 1: Dark background
|
||||||
// Convert "r g b" format to hex
|
const color1 = background;
|
||||||
const parts = accentRgb.split(' ').map(Number);
|
|
||||||
if (parts.length === 3 && parts.every((n) => !isNaN(n))) {
|
|
||||||
const hex = parts.map((n) => Math.round(n).toString(16).padStart(2, '0')).join('');
|
|
||||||
return `#${hex}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default accent color fallback
|
// Color 2: Accent at 40% intensity
|
||||||
return '#a78bfa';
|
const midR = Math.round(ar * 255 * 0.4);
|
||||||
}
|
const midG = Math.round(ag * 255 * 0.4);
|
||||||
|
const midB = Math.round(ab * 255 * 0.4);
|
||||||
function generateColorStops(baseColor: string): string[] {
|
|
||||||
const [r, g, b] = hexToRgb(baseColor);
|
|
||||||
|
|
||||||
// Create vibrant color stops for aurora effect
|
|
||||||
// Color 1: Very dark background
|
|
||||||
const color1 = '#0a0a0a';
|
|
||||||
|
|
||||||
// Color 2: Accent at ~50% intensity (main aurora color)
|
|
||||||
const midR = Math.round(r * 255 * 0.5);
|
|
||||||
const midG = Math.round(g * 255 * 0.5);
|
|
||||||
const midB = Math.round(b * 255 * 0.5);
|
|
||||||
const color2 = `#${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
const color2 = `#${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
||||||
|
|
||||||
// Color 3: Accent at full intensity (bright aurora edge)
|
// Color 3: Accent at 70% intensity
|
||||||
const brightR = Math.round(r * 255);
|
const brightR = Math.round(ar * 255 * 0.7);
|
||||||
const brightG = Math.round(g * 255);
|
const brightG = Math.round(ag * 255 * 0.7);
|
||||||
const brightB = Math.round(b * 255);
|
const brightB = Math.round(ab * 255 * 0.7);
|
||||||
const color3 = `#${brightR.toString(16).padStart(2, '0')}${brightG.toString(16).padStart(2, '0')}${brightB.toString(16).padStart(2, '0')}`;
|
const color3 = `#${brightR.toString(16).padStart(2, '0')}${brightG.toString(16).padStart(2, '0')}${brightB.toString(16).padStart(2, '0')}`;
|
||||||
|
|
||||||
return [color1, color2, color3];
|
return [color1, color2, color3];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProps) {
|
export function Aurora() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const animationFrameRef = useRef<number>(0);
|
const animationFrameRef = useRef<number>(0);
|
||||||
const rendererRef = useRef<Renderer | null>(null);
|
const rendererRef = useRef<Renderer | null>(null);
|
||||||
const programRef = useRef<Program | null>(null);
|
const programRef = useRef<Program | null>(null);
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
// Fetch animation setting
|
// Fetch animation setting
|
||||||
const { data: animationSetting } = useQuery({
|
const { data: animationSetting } = useQuery({
|
||||||
queryKey: ['animation-enabled'],
|
queryKey: ['animation-enabled'],
|
||||||
@@ -168,12 +144,9 @@ export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProp
|
|||||||
|
|
||||||
const isEnabled = animationSetting?.enabled ?? false;
|
const isEnabled = animationSetting?.enabled ?? false;
|
||||||
|
|
||||||
// Get color stops based on theme
|
// Get theme colors from cache (already fetched by ThemeColorsProvider)
|
||||||
const colorStops = useMemo(() => {
|
const themeColors =
|
||||||
if (typeof window === 'undefined') return ['#0a0a0a', '#1a1a2e', '#0a0a0a'];
|
queryClient.getQueryData<ThemeSettings>(['theme-colors']) || DEFAULT_THEME_COLORS;
|
||||||
const accent = getAccentColorFromCSS();
|
|
||||||
return generateColorStops(accent);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEnabled || !containerRef.current) return;
|
if (!isEnabled || !containerRef.current) return;
|
||||||
@@ -195,6 +168,7 @@ export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProp
|
|||||||
|
|
||||||
const geometry = new Triangle(gl);
|
const geometry = new Triangle(gl);
|
||||||
|
|
||||||
|
const colorStops = generateColorStops(themeColors.accent, themeColors.darkBackground);
|
||||||
const colorStopsArray = colorStops
|
const colorStopsArray = colorStops
|
||||||
.map((hex) => {
|
.map((hex) => {
|
||||||
const c = new Color(hex);
|
const c = new Color(hex);
|
||||||
@@ -207,10 +181,10 @@ export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProp
|
|||||||
fragment: FRAG,
|
fragment: FRAG,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uTime: { value: 0 },
|
uTime: { value: 0 },
|
||||||
uAmplitude: { value: amplitude },
|
uAmplitude: { value: 1.0 },
|
||||||
uColorStops: { value: colorStopsArray },
|
uColorStops: { value: colorStopsArray },
|
||||||
uResolution: { value: [container.offsetWidth, container.offsetHeight] },
|
uResolution: { value: [container.offsetWidth, container.offsetHeight] },
|
||||||
uBlend: { value: blend },
|
uBlend: { value: 1.0 },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
programRef.current = program;
|
programRef.current = program;
|
||||||
@@ -229,8 +203,9 @@ export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProp
|
|||||||
resize();
|
resize();
|
||||||
|
|
||||||
let lastTime = 0;
|
let lastTime = 0;
|
||||||
const targetFPS = 30; // Limit to 30fps for performance
|
const targetFPS = 30;
|
||||||
const frameInterval = 1000 / targetFPS;
|
const frameInterval = 1000 / targetFPS;
|
||||||
|
const speed = 0.3; // Slow and smooth
|
||||||
|
|
||||||
function animate(currentTime: number) {
|
function animate(currentTime: number) {
|
||||||
animationFrameRef.current = requestAnimationFrame(animate);
|
animationFrameRef.current = requestAnimationFrame(animate);
|
||||||
@@ -256,17 +231,33 @@ export function Aurora({ amplitude = 1.0, blend = 1.0, speed = 1.0 }: AuroraProp
|
|||||||
rendererRef.current = null;
|
rendererRef.current = null;
|
||||||
programRef.current = null;
|
programRef.current = null;
|
||||||
};
|
};
|
||||||
}, [isEnabled, colorStops, amplitude, blend, speed]);
|
}, [isEnabled, themeColors.accent, themeColors.darkBackground]);
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blur overlay color from accent (very subtle)
|
||||||
|
const [r, g, b] = hexToRgb(themeColors.accent);
|
||||||
|
const blurColor = `rgba(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(b * 255)}, 0.03)`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
ref={containerRef}
|
{/* WebGL Aurora canvas */}
|
||||||
className="pointer-events-none fixed inset-0 z-0"
|
<div
|
||||||
style={{ width: '100%', height: '100%' }}
|
ref={containerRef}
|
||||||
/>
|
className="pointer-events-none fixed inset-0 z-0"
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
/>
|
||||||
|
{/* Blur overlay */}
|
||||||
|
<div
|
||||||
|
className="pointer-events-none fixed inset-0 z-0"
|
||||||
|
style={{
|
||||||
|
backdropFilter: 'blur(80px)',
|
||||||
|
WebkitBackdropFilter: 'blur(80px)',
|
||||||
|
backgroundColor: blurColor,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user