Gestionado todo el frontend para domain driven design
feat: Implement LlamadorAPI component for API interaction with dynamic request handling feat: Create MetodoSelect component for selecting HTTP methods with visual feedback feat: Add VisualizacionesRandom component to display various charts using ECharts feat: Develop custom 404 Error page with holographic shader effect feat: Create HoloShader component for dynamic background effects on 404 page style: Add CSS styles for Appshell layout and navigation feat: Build Appshell component to manage application layout and navigation feat: Add ColorSchemeToggle component for switching between light and dark themes feat: Create Plantilla component as a template for future pages style: Define styles for Welcome component feat: Implement Welcome component with introductory text and links feat: Develop HomePage component to serve as the main entry point of the application feat: Create Biblioteca component for managing notes and libraries with rich text editor feat: Add Editor_Test component for testing rich text editor functionality style: Define styles for the rich text editor in Biblioteca
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import { Card, Title, Box, useMantineTheme } from '@mantine/core';
|
||||
import { Canvas, extend, useFrame, useThree } from '@react-three/fiber';
|
||||
import { useRef, useMemo } from 'react';
|
||||
import * as THREE from 'three';
|
||||
|
||||
// 🎨 Utilidad para convertir hex a RGB [0–1]
|
||||
function hexToRGBArray(hex: string): [number, number, number] {
|
||||
const bigint = parseInt(hex.replace('#', ''), 16);
|
||||
return [
|
||||
((bigint >> 16) & 255) / 255,
|
||||
((bigint >> 8) & 255) / 255,
|
||||
(bigint & 255) / 255,
|
||||
];
|
||||
}
|
||||
|
||||
// ✨ Shader personalizado estilo holográfico, con color dinámico
|
||||
class HoloShaderMaterial extends THREE.ShaderMaterial {
|
||||
constructor(color: [number, number, number]) {
|
||||
super({
|
||||
uniforms: {
|
||||
u_time: { value: 0 },
|
||||
u_resolution: { value: new THREE.Vector2() },
|
||||
u_color: { value: new THREE.Vector3(...color) },
|
||||
},
|
||||
vertexShader: `
|
||||
void main() {
|
||||
gl_Position = vec4(position, 1.0);
|
||||
}
|
||||
`,
|
||||
fragmentShader: `
|
||||
precision mediump float;
|
||||
uniform float u_time;
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec3 u_color;
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / u_resolution;
|
||||
vec2 pos = uv * 10.0;
|
||||
pos.x += u_time * 0.3;
|
||||
pos.y += sin(u_time * 0.2) * 2.0;
|
||||
|
||||
float color = sin(pos.x + sin(pos.y + sin(pos.x))) * 0.5 + 0.5;
|
||||
|
||||
vec3 c = vec3(
|
||||
u_color.r + 0.2 * sin(u_time + pos.x),
|
||||
u_color.g + 0.2 * cos(u_time + pos.y),
|
||||
u_color.b + 0.2 * sin(pos.x + pos.y + u_time)
|
||||
);
|
||||
|
||||
gl_FragColor = vec4(c * color, 1.0);
|
||||
}
|
||||
`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extend({ HoloShaderMaterial });
|
||||
|
||||
// 🎥 Plano con el shader
|
||||
function HoloPlane({ color }: { color: [number, number, number] }) {
|
||||
const mat = useRef<any>(null);
|
||||
const { size } = useThree();
|
||||
|
||||
useFrame(({ clock }) => {
|
||||
if (mat.current) {
|
||||
mat.current.uniforms.u_time.value = clock.getElapsedTime();
|
||||
mat.current.uniforms.u_resolution.value.set(size.width, size.height);
|
||||
}
|
||||
});
|
||||
|
||||
const material = useMemo(() => new HoloShaderMaterial(color), [color]);
|
||||
|
||||
return (
|
||||
<mesh>
|
||||
<planeGeometry args={[2, 2]} />
|
||||
<primitive object={material} ref={mat} attach="material" />
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
// 🎨 Fondo que ocupa todo el contenedor
|
||||
function HolographicBackground({ color }: { color: [number, number, number] }) {
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
zIndex: 0,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<Canvas orthographic camera={{ zoom: 1, position: [0, 0, 1] }}>
|
||||
<HoloPlane color={color} />
|
||||
</Canvas>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// 🧩 Componente final con fondo shader y texto 404
|
||||
export function MantineCardWithShader() {
|
||||
const theme = useMantineTheme();
|
||||
const hex = theme.colors[theme.primaryColor][6];
|
||||
const rgb = hexToRGBArray(hex);
|
||||
|
||||
return (
|
||||
<Card
|
||||
withBorder
|
||||
radius="lg"
|
||||
shadow="xl"
|
||||
style={{
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
minHeight: 300,
|
||||
minWidth: 400,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<HolographicBackground color={rgb} />
|
||||
|
||||
<Box style={{ position: 'relative', zIndex: 1, textAlign: 'center' }}>
|
||||
<Title
|
||||
order={1}
|
||||
style={{
|
||||
fontSize: '15rem',
|
||||
fontWeight: 900,
|
||||
backgroundImage: 'linear-gradient(to bottom, rgba(255,255,255,1), rgba(255,255,255,0))',
|
||||
WebkitBackgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent',
|
||||
textAlign: 'center',
|
||||
lineHeight: 1,
|
||||
userSelect: 'none', // <-- evita selección
|
||||
textDecoration: 'none', // <-- evita subrayado
|
||||
}}
|
||||
>
|
||||
404
|
||||
</Title>
|
||||
</Box>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user