import React, { useState, useEffect } from 'react';
import { Card } from '@/components/ui/card';
const EntangledStates = () => {
const [time, setTime] = useState(0);
const [isPlaying, setIsPlaying] = useState(true);
const [trails, setTrails] = useState([[], [], []]);
const [particles, setParticles] = useState([]);
// Constants
const width = 400;
const height = 400;
const centerX = width / 2;
const centerY = height / 2;
const radius = 150;
useEffect(() => {
let animationFrame;
const animate = () => {
setTime(t => (t + 0.02) % (2 * Math.PI));
if (isPlaying) {
animationFrame = requestAnimationFrame(animate);
}
};
animationFrame = requestAnimationFrame(animate);
return () => cancelAnimationFrame(animationFrame);
}, [isPlaying]);
// Calculate positions for three entangled states
const getStatePosition = (timeOffset, phaseOffset) => {
const theta = (time + timeOffset) * Math.PI;
const phi = (time + timeOffset) * 2 * Math.PI + phaseOffset;
const x = radius * Math.sin(theta) * Math.cos(phi);
const y = radius * Math.sin(theta) * Math.sin(phi);
const z = radius * Math.cos(theta);
const scale = 1 + z / (radius * 4);
return {
x: centerX + x * scale,
y: centerY + y * scale,
z: z
};
};
const states = [
getStatePosition(0, 0),
getStatePosition(2/3 * Math.PI, 2 * Math.PI / 3),
getStatePosition(4/3 * Math.PI, 4 * Math.PI / 3)
];
// Update trails and particles
useEffect(() => {
// Update trails for each state
setTrails(prevTrails =>
prevTrails.map((trail, index) => {
const newPoint = {
x: states[index].x,
y: states[index].y,
opacity: 1
};
const newTrail = [...trail, newPoint];
return newTrail.length > 15 ? newTrail.slice(-15) : newTrail;
})
);
// Generate connecting particles
if (Math.random() < 0.2) {
const sourceIndex = Math.floor(Math.random() * 3);
const targetIndex = (sourceIndex + 1 + Math.floor(Math.random() * 2)) % 3;
const particle = {
x: states[sourceIndex].x,
y: states[sourceIndex].y,
targetX: states[targetIndex].x,
targetY: states[targetIndex].y,
progress: 0,
id: Date.now() + Math.random(),
sourceIndex,
targetIndex
};
setParticles(prev => [...prev, particle]);
}
// Update particles
setParticles(prev =>
prev
.map(p => ({
...p,
progress: p.progress + 0.05
}))
.filter(p => p.progress < 1)
);
}, [time]);
const getParticlePosition = (particle) => {
const progress = particle.progress;
return {
x: particle.x + (particle.targetX - particle.x) * progress,
y: particle.y + (particle.targetY - particle.y) * progress
};
};
return (
<Card className="w-full p-4">
<div className="flex flex-col items-center gap-4">
<svg width={width} height={height} className="bg-gradient-to-b from-blue-50 to-white">
{/* Background glow */}
<defs>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stopColor="rgba(135, 206, 250, 0.3)" />
<stop offset="100%" stopColor="rgba(135, 206, 250, 0)" />
</radialGradient>
{/* Entanglement line gradient */}
<linearGradient id="entanglementLine" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="rgba(147, 51, 234, 0.5)" />
<stop offset="100%" stopColor="rgba(236, 72, 153, 0.5)" />
</linearGradient>
</defs>
<circle cx={centerX} cy={centerY} r={radius + 20} fill="url(#glow)" />
{/* Bloch sphere */}
<circle
cx={centerX}
cy={centerY}
r={radius}
fill="none"
stroke="rgba(0,0,0,0.7)"
strokeWidth="1.5"
/>
{/* Equator */}
<ellipse
cx={centerX}
cy={centerY}
rx={radius}
ry={radius * 0.3}
fill="none"
stroke="rgba(0,0,0,0.3)"
strokeDasharray="5,5"
/>
{/* Entanglement connections */}
{states.map((state1, i) =>
states.map((state2, j) => {
if (j > i) {
return (
<line
key={`connection-${i}-${j}`}
x1={state1.x}
y1={state1.y}
x2={state2.x}
y2={state2.y}
stroke="url(#entanglementLine)"
strokeWidth="1"
strokeOpacity="0.3"
/>
);
}
return null;
})
)}
{/* Trails */}
{trails.map((trail, stateIndex) =>
trail.map((point, i) => (
<circle
key={`trail-${stateIndex}-${i}`}
cx={point.x}
cy={point.y}
r={2}
fill={`hsl(${120 * stateIndex}, 70%, 60%)`}
opacity={i / trail.length * 0.5}
/>
))
)}
{/* Entanglement particles */}
{particles.map(particle => {
const pos = getParticlePosition(particle);
return (
<circle
key={particle.id}
cx={pos.x}
cy={pos.y}
r={3}
fill="rgba(147, 51, 234, 0.6)"
opacity={1 - particle.progress}
>
<animate
attributeName="r"
values="3;4;3"
dur="0.5s"
repeatCount="indefinite"
/>
</circle>
);
})}
{/* Quantum states */}
{states.map((state, index) => (
<g key={`state-${index}`}>
<circle
cx={state.x}
cy={state.y}
r={8}
fill={`hsla(${120 * index}, 70%, 60%, 0.3)`}
>
<animate
attributeName="r"
values="8;10;8"
dur="1s"
repeatCount="indefinite"
/>
</circle>
<circle
cx={state.x}
cy={state.y}
r={4}
fill={`hsl(${120 * index}, 70%, 50%)`}
/>
</g>
))}
</svg>
<button
onClick={() => setIsPlaying(!isPlaying)}
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200"
>
{isPlaying ? '暫停' : '播放'}
</button>
</div>
</Card>
);
};
export default EntangledStates;
コメント