aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
443 lines (440 loc) • 18.7 kB
JavaScript
'use client';
import { jsx, jsxs } from 'react/jsx-runtime';
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
import { forwardRef, useRef, useState, useEffect, useMemo } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import '../../primitives/GlassCore.js';
import '../../primitives/glass/GlassAdvanced.js';
import { OptimizedGlassCore } from '../../primitives/OptimizedGlassCore.js';
import '../../primitives/glass/OptimizedGlassAdvanced.js';
import '../../primitives/MotionNative.js';
import '../../primitives/motion/MotionFramer.js';
import { useA11yId } from '../../utils/a11y.js';
import { useMotionPreference } from '../../hooks/useMotionPreference.js';
import { createGlassStyle } from '../../utils/createGlassStyle.js';
import { cn } from '../../lib/utilsComprehensive.js';
const generateQuantumNoise = (amplitude = 0.1) => (Math.random() - 0.5) * amplitude * 2;
const waveFunction = (x, y, t, frequency = 1) => Math.sin(x * frequency + t) * Math.cos(y * frequency + t * 0.7);
const probabilityDensity = waveAmp => waveAmp * waveAmp;
const GlassProbabilityCloud = /*#__PURE__*/forwardRef(({
width = 600,
height = 400,
depth = 200,
probabilityPoints = [],
uncertaintyPrinciple = true,
quantumFluctuations = true,
observerEffect = true,
heisenbergUncertainty = 0.5,
waveParticleDuality = true,
showProbabilityDensity = true,
showWaveFunction = true,
showUncertaintyBounds = true,
animationSpeed = 1,
particleCount = 100,
measurementPrecision = 0.1,
realTimeMode = false,
onMeasurement,
onUncertaintyChange,
className = "",
...props
}, ref) => {
const prefersReducedMotion = useReducedMotion();
const canvasRef = useRef(null);
const [quantumTime, setQuantumTime] = useState(0);
const [measurements, setMeasurements] = useState([]);
const [particles, setParticles] = useState([]);
const [totalUncertainty, setTotalUncertainty] = useState(heisenbergUncertainty);
// Motion preference hook
useMotionPreference();
const [isObserved, setIsObserved] = useState(false);
useA11yId("glass-probability-cloud");
// Initialize quantum particles
useEffect(() => {
const initialParticles = Array.from({
length: particleCount
}, (_, i) => ({
id: `particle-${i}`,
x: Math.random() * width,
y: Math.random() * height,
z: Math.random() * depth,
probability: Math.random(),
uncertainty: heisenbergUncertainty + generateQuantumNoise(0.1),
waveFunction: Math.random() * 2 - 1,
phase: Math.random() * Math.PI * 2,
observationCount: 0
}));
setParticles([...probabilityPoints, ...initialParticles]);
}, [particleCount, width, height, depth, heisenbergUncertainty, probabilityPoints]);
// Quantum time evolution
useEffect(() => {
const interval = setInterval(() => {
setQuantumTime(prev => prev + 0.1 * animationSpeed);
}, 16);
return () => clearInterval(interval);
}, [animationSpeed]);
// Update quantum system
useEffect(() => {
if (!realTimeMode) return;
const interval = setInterval(() => {
setParticles(prev => prev.map(particle => {
// Wave function evolution
const newWaveFunction = waveFunction(particle.x / width * 4 * Math.PI, particle.y / height * 4 * Math.PI, quantumTime, 1 + particle.phase / Math.PI);
// Probability density from wave function
const newProbability = probabilityDensity(newWaveFunction);
// Quantum fluctuations
let deltaX = 0,
deltaY = 0,
deltaZ = 0;
if (quantumFluctuations) {
const fluctuationStrength = particle.uncertainty * 0.5;
deltaX = generateQuantumNoise(fluctuationStrength);
deltaY = generateQuantumNoise(fluctuationStrength);
deltaZ = generateQuantumNoise(fluctuationStrength);
}
// Heisenberg uncertainty principle
let newUncertainty = particle.uncertainty;
if (uncertaintyPrinciple) {
const momentum = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
const positionPrecision = 1 - momentum;
newUncertainty = Math.max(heisenbergUncertainty, 1 / (positionPrecision + 0.1));
}
// Observer effect - collapse wave function when observed
if (observerEffect && isObserved) {
const distance = Math.sqrt(Math.pow(particle.x - width / 2, 2) + Math.pow(particle.y - height / 2, 2));
if (distance < 50) {
return {
...particle,
waveFunction: Math.sign(newWaveFunction) * 0.9,
probability: 0.8,
uncertainty: Math.max(0.1, particle.uncertainty * 0.5),
observationCount: particle.observationCount + 1,
lastObserved: Date.now()
};
}
}
return {
...particle,
x: Math.max(0, Math.min(width, particle.x + deltaX)),
y: Math.max(0, Math.min(height, particle.y + deltaY)),
z: Math.max(0, Math.min(depth, particle.z + deltaZ)),
waveFunction: newWaveFunction,
probability: Math.max(0.01, Math.min(1, newProbability + 0.1)),
uncertainty: Math.max(0.05, Math.min(2, newUncertainty)),
phase: (particle.phase + 0.05) % (2 * Math.PI)
};
}));
}, 50);
return () => clearInterval(interval);
}, [realTimeMode, quantumTime, width, height, depth, uncertaintyPrinciple, quantumFluctuations, observerEffect, heisenbergUncertainty, isObserved]);
// Update total uncertainty
useEffect(() => {
const avgUncertainty = particles.reduce((sum, p) => sum + p.uncertainty, 0) / particles.length;
setTotalUncertainty(avgUncertainty || heisenbergUncertainty);
onUncertaintyChange?.(avgUncertainty);
}, [particles, heisenbergUncertainty, onUncertaintyChange]);
// Canvas rendering
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Background quantum field
if (showProbabilityDensity) {
const imageData = ctx.createImageData(width, height);
for (let x = 0; x < width; x += 4) {
for (let y = 0; y < height; y += 4) {
const wave = waveFunction(x / width * 4 * Math.PI, y / height * 4 * Math.PI, quantumTime);
const density = probabilityDensity(wave);
const intensity = Math.floor(density * 50 + 10);
const index = (y * width + x) * 4;
if (index < imageData.data.length - 3) {
imageData.data[index] = 100 + intensity; // R
imageData.data[index + 1] = 50 + intensity; // G
imageData.data[index + 2] = 200 + intensity; // B
imageData.data[index + 3] = 30; // A
}
}
}
ctx.putImageData(imageData, 0, 0);
}
// Draw particles
particles.forEach(particle => {
const opacity = observerEffect && particle.lastObserved && Date.now() - particle.lastObserved < 1000 ? 0.9 : particle.probability * 0.7 + 0.1;
// Particle size based on uncertainty
const baseSize = 2 + particle.uncertainty * 3;
const pulseSize = waveParticleDuality ? baseSize * (1 + Math.sin(quantumTime * 3 + particle.phase) * 0.3) : baseSize;
// Wave or particle rendering based on duality
if (waveParticleDuality && particle.uncertainty > 0.3) {
// Wave representation
ctx.beginPath();
ctx.arc(particle.x, particle.y, pulseSize * 2, 0, 2 * Math.PI);
ctx.fillStyle = `rgba(100, 150, 255, ${opacity * 0.3})`;
ctx.fill();
// Wave rings
for (let i = 1; i <= 3; i++) {
ctx.beginPath();
ctx.arc(particle.x, particle.y, pulseSize * i * 0.7, 0, 2 * Math.PI);
ctx.strokeStyle = `rgba(150, 200, 255, ${opacity * 0.2 / i})`;
ctx.lineWidth = 1;
ctx.stroke();
}
} else {
// Particle representation
ctx.beginPath();
ctx.arc(particle.x, particle.y, pulseSize, 0, 2 * Math.PI);
const gradient = ctx.createRadialGradient(particle.x, particle.y, 0, particle.x, particle.y, pulseSize);
gradient.addColorStop(0, `rgba(255, 255, 255, ${opacity})`);
gradient.addColorStop(1, `rgba(100, 150, 255, ${opacity * 0.3})`);
ctx.fillStyle = gradient;
ctx.fill();
}
// Uncertainty bounds
if (showUncertaintyBounds && particle.uncertainty > 0.2) {
ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.uncertainty * 20, 0, 2 * Math.PI);
ctx.strokeStyle = `rgba(255, 100, 100, ${particle.uncertainty * 0.3})`;
ctx.lineWidth = 1;
ctx.setLineDash([2, 3]);
ctx.stroke();
ctx.setLineDash([]);
}
});
// Wave function visualization
if (showWaveFunction) {
ctx.strokeStyle = "rgba(200, 200, 255, 0.4)";
ctx.lineWidth = 1;
ctx.beginPath();
for (let x = 0; x < width; x += 10) {
const wave = waveFunction(x / width * 4 * Math.PI, height / 2 / height * 4 * Math.PI, quantumTime);
const y = height / 2 + wave * 30;
if (x === 0) ctx.moveTo(x, y);else ctx.lineTo(x, y);
}
ctx.stroke();
// Vertical wave function
ctx.beginPath();
for (let y = 0; y < height; y += 10) {
const wave = waveFunction(width / 2 / width * 4 * Math.PI, y / height * 4 * Math.PI, quantumTime);
const x = width / 2 + wave * 30;
if (y === 0) ctx.moveTo(x, y);else ctx.lineTo(x, y);
}
ctx.stroke();
}
}, [particles, quantumTime, width, height, showProbabilityDensity, showWaveFunction, showUncertaintyBounds, waveParticleDuality, observerEffect]);
const handleCanvasClick = e => {
const canvas = canvasRef.current;
if (!canvas) return;
const rect = canvas.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const clickY = e.clientY - rect.top;
// Find nearest particle for measurement
let nearestParticle = null;
let minDistance = Infinity;
particles.forEach(particle => {
const distance = Math.sqrt(Math.pow(particle.x - clickX, 2) + Math.pow(particle.y - clickY, 2));
if (distance < minDistance && distance < 30) {
minDistance = distance;
nearestParticle = particle;
}
});
if (nearestParticle) {
// Perform measurement
const measurement = {
point: nearestParticle,
timestamp: Date.now(),
uncertainty: nearestParticle.uncertainty
};
setMeasurements(prev => [...prev.slice(-9), measurement]);
onMeasurement?.(nearestParticle);
// Update particle due to measurement
setParticles(prev => prev.map(p => p.id === nearestParticle.id ? {
...p,
observationCount: p.observationCount + 1,
lastObserved: Date.now(),
uncertainty: Math.max(0.1, p.uncertainty * 0.7)
} : p));
}
};
const averageProbability = useMemo(() => particles.reduce((sum, p) => sum + p.probability, 0) / particles.length || 0, [particles]);
const quantumCoherence = useMemo(() => 1 - (totalUncertainty - heisenbergUncertainty), [totalUncertainty, heisenbergUncertainty]);
return jsx(OptimizedGlassCore, {
ref: ref,
variant: "frosted",
className: `relative ${className}`,
...props,
children: jsxs("div", {
className: 'glass-p-4 space-y-4',
children: [jsxs("div", {
className: "glass-flex glass-items-center glass-justify-between",
children: [jsxs("div", {
children: [jsx("h2", {
className: cn("glass-text-xl glass-font-semibold glass-text-primary"),
children: "Probability Cloud"
}), jsxs("p", {
className: cn("glass-text-sm glass-text-secondary"),
children: [particles.length, " quantum states"]
})]
}), jsxs("div", {
className: 'glass-flex glass-items-center space-x-4',
children: [jsx("button", {
onClick: () => setIsObserved(!isObserved),
className: `
px-3 py-1 rounded text-sm font-medium transition-colors duration-200
${createGlassStyle({
variant: "default"
})}
glass-border-subtle
${isObserved ? "glass-text-danger glass-border-danger" : "glass-text-secondary hover:glass-text-primary"}
`,
children: isObserved ? "👁️ Observing" : "👁️🗨️ Observe"
}), jsxs("div", {
className: cn("glass-text-sm glass-text-muted"),
children: ["t: ", quantumTime.toFixed(1)]
})]
})]
}), jsxs("div", {
className: 'relative',
children: [jsx("canvas", {
ref: canvasRef,
width: width,
height: height,
className: cn("glass-border-subtle glass-radius-lg glass-cursor-crosshair glass-surface-overlay"),
onClick: handleCanvasClick,
onMouseEnter: () => setIsObserved(true),
onMouseLeave: () => setIsObserved(false)
}), jsx(AnimatePresence, {
children: measurements.map(measurement => jsx(motion.div, {
className: 'absolute pointer-events-none',
style: {
left: measurement.point.x,
top: measurement.point.y,
transform: "translate(-50%, -50%)"
},
initial: {
scale: 0,
opacity: 1
},
animate: prefersReducedMotion ? {} : {
scale: 2,
opacity: 0
},
exit: {
opacity: 0
},
transition: prefersReducedMotion ? {
duration: 0
} : {
duration: 1
},
children: jsx("div", {
className: cn("glass-w-4 glass-h-4 glass-border-2 glass-border-danger glass-radius-full")
})
}, measurement.timestamp))
})]
}), jsxs("div", {
className: cn("glass-p-4 glass-radius-lg glass-border-subtle glass-space-y-3", createGlassStyle({
variant: "default"
})),
children: [jsxs("div", {
className: 'glass-grid glass-grid-cols-2 md:grid-cols-4 glass-gap-4 glass-text-sm',
children: [jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Uncertainty:"
}), jsxs("div", {
className: cn("glass-flex glass-items-center glass-space-x-2 glass-mt-1"),
children: [jsx("div", {
className: cn("glass-flex-1 glass-h-2 glass-surface-muted glass-radius-full glass-overflow-hidden"),
children: jsx(motion.div, {
className: cn("glass-h-full glass-gradient-primary glass-radius-full"),
animate: {
width: `${Math.min(100, totalUncertainty * 100)}%`
},
transition: prefersReducedMotion ? {
duration: 0
} : {
duration: 0.3
}
})
}), jsxs("span", {
className: cn("glass-text-primary glass-text-xs"),
children: [(totalUncertainty * 100).toFixed(1), "%"]
})]
})]
}), jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Avg Probability:"
}), jsxs("div", {
className: cn("glass-text-primary glass-font-medium"),
children: [(averageProbability * 100).toFixed(1), "%"]
})]
}), jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Coherence:"
}), jsxs("div", {
className: cn("glass-text-primary glass-font-medium"),
children: [Math.max(0, Math.min(100, quantumCoherence * 100)).toFixed(1), "%"]
})]
}), jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Measurements:"
}), jsx("div", {
className: cn("glass-text-primary glass-font-medium"),
children: measurements.length
})]
})]
}), measurements.length > 0 && jsxs("div", {
className: 'space-y-1',
children: [jsx("span", {
className: cn("glass-text-secondary glass-text-sm"),
children: "Recent Measurements:"
}), jsx("div", {
className: "glass-flex glass-flex-wrap glass-gap-1",
children: measurements.slice(-5).map(measurement => jsxs("div", {
className: cn("glass-px-2 glass-py-1 glass-text-xs glass-surface-muted glass-radius glass-border-subtle"),
children: ["P: ", (measurement.point.probability * 100).toFixed(0), "%", measurement.uncertainty > 0.5 && jsxs("span", {
className: 'text-primary ml-1',
children: ["\u00B1", measurement.uncertainty.toFixed(1)]
})]
}, measurement.timestamp))
})]
})]
}), jsxs("div", {
className: cn("glass-flex glass-items-center glass-justify-between glass-text-sm glass-text-muted"),
children: [jsx("span", {
children: "Click particles to measure \u2022 Hover to observe"
}), jsxs("div", {
className: 'glass-flex glass-items-center space-x-4',
children: [uncertaintyPrinciple && jsxs("span", {
className: 'glass-flex glass-items-center space-x-1',
children: [jsx("span", {
children: "\u269B"
}), jsx("span", {
children: "Heisenberg"
})]
}), waveParticleDuality && jsxs("span", {
className: 'glass-flex glass-items-center space-x-1',
children: [jsx("span", {
children: "\u3030\uFE0F"
}), jsx("span", {
children: "Wave-Particle"
})]
}), realTimeMode && jsxs("span", {
className: 'glass-flex glass-items-center space-x-1 text-primary',
children: [jsx("div", {
className: cn("glass-w-2 glass-h-2 glass-surface-success glass-radius-full glass-animate-pulse")
}), jsx("span", {
children: "Live"
})]
})]
})]
})]
})
});
});
export { GlassProbabilityCloud };
//# sourceMappingURL=GlassProbabilityCloud.js.map