Skip to content

Commit 11a49db

Browse files
committed
init
1 parent e27494d commit 11a49db

File tree

2 files changed

+10
-135
lines changed

2 files changed

+10
-135
lines changed

src/components/TraceCarousel.tsx

Lines changed: 10 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -16,67 +16,19 @@ export default function TraceCarousel({
1616
autoplayInterval = 10000
1717
}: TraceCarouselProps) {
1818
const [activeIndex, setActiveIndex] = useState(0);
19-
const [rotation, setRotation] = useState(0);
20-
const [tiltY, setTiltY] = useState(0);
2119
const [isTransitioning, setIsTransitioning] = useState(false);
2220
const [isAutoPlaying, setIsAutoPlaying] = useState(autoplay);
23-
const [isUserInteracting, setIsUserInteracting] = useState(false);
24-
const containerRef = useRef<HTMLDivElement>(null);
2521
const autoplayTimerRef = useRef<NodeJS.Timeout | null>(null);
2622

2723
// Generate IDs if not provided
2824
const viewerIds = ids.length === traceDatas.length
2925
? ids
3026
: traceDatas.map((_, index) => `viewer-${index}`);
31-
32-
// Handle mouse movement to control rotation
33-
const handleMouseMove = (e: React.MouseEvent) => {
34-
if (!containerRef.current || isTransitioning) return;
35-
setIsUserInteracting(true);
36-
37-
const rect = containerRef.current.getBoundingClientRect();
38-
const centerX = rect.left + rect.width / 2;
39-
const centerY = rect.top + rect.height / 2;
40-
41-
// Calculate angle based on mouse position relative to center
42-
const angleX = ((e.clientX - centerX) / (rect.width / 2)) * 8; // Max 8 degrees rotation
43-
const angleY = ((e.clientY - centerY) / (rect.height / 2)) * 5; // Max 5 degrees tilt
44-
45-
setRotation(angleX);
46-
setTiltY(angleY);
47-
48-
// Reset user interaction state after 3 seconds of inactivity
49-
resetUserInteractionTimeout();
50-
};
51-
52-
// Reset user interaction after delay
53-
const resetUserInteractionTimeout = () => {
54-
if (autoplayTimerRef.current) {
55-
clearTimeout(autoplayTimerRef.current);
56-
}
57-
58-
autoplayTimerRef.current = setTimeout(() => {
59-
setIsUserInteracting(false);
60-
}, 3000);
61-
};
62-
63-
// Reset rotation when mouse leaves
64-
const handleMouseLeave = () => {
65-
setRotation(0);
66-
setTiltY(0);
67-
setIsUserInteracting(false);
68-
69-
if (autoplayTimerRef.current) {
70-
clearTimeout(autoplayTimerRef.current);
71-
}
72-
};
7327

7428
// Navigate to previous trace
7529
const prevTrace = () => {
7630
if (isTransitioning) return;
7731

78-
setIsUserInteracting(true);
79-
resetUserInteractionTimeout();
8032
setIsTransitioning(true);
8133
setTimeout(() => {
8234
setActiveIndex((prevIndex) =>
@@ -90,8 +42,6 @@ export default function TraceCarousel({
9042
const nextTrace = () => {
9143
if (isTransitioning) return;
9244

93-
setIsUserInteracting(true);
94-
resetUserInteractionTimeout();
9545
setIsTransitioning(true);
9646
setTimeout(() => {
9747
setActiveIndex((prevIndex) =>
@@ -105,8 +55,6 @@ export default function TraceCarousel({
10555
const goToTrace = (index: number) => {
10656
if (isTransitioning || index === activeIndex) return;
10757

108-
setIsUserInteracting(true);
109-
resetUserInteractionTimeout();
11058
setIsTransitioning(true);
11159
setTimeout(() => {
11260
setActiveIndex(index);
@@ -141,7 +89,7 @@ export default function TraceCarousel({
14189
useEffect(() => {
14290
let interval: NodeJS.Timeout | null = null;
14391

144-
if (isAutoPlaying && !isUserInteracting && traceDatas.length > 1) {
92+
if (isAutoPlaying && traceDatas.length > 1) {
14593
interval = setInterval(() => {
14694
nextTrace();
14795
}, autoplayInterval);
@@ -150,7 +98,7 @@ export default function TraceCarousel({
15098
return () => {
15199
if (interval) clearInterval(interval);
152100
};
153-
}, [isAutoPlaying, isUserInteracting, activeIndex, traceDatas.length]);
101+
}, [isAutoPlaying, activeIndex, traceDatas.length]);
154102

155103
// Clean up autoplay timer on unmount
156104
useEffect(() => {
@@ -163,63 +111,20 @@ export default function TraceCarousel({
163111

164112
return (
165113
<div className="relative pb-16">
166-
<div
167-
ref={containerRef}
168-
className="relative w-full h-[600px] overflow-hidden rounded-xl shadow-2xl"
169-
onMouseMove={handleMouseMove}
170-
onMouseLeave={handleMouseLeave}
171-
>
172-
{/* Carousel container with 3D effect */}
173-
<div className="w-full h-full relative perspective-1000">
114+
<div className="relative w-full h-[600px] overflow-hidden rounded-xl shadow-lg">
115+
{/* Carousel container */}
116+
<div className="w-full h-full relative">
174117
{traceDatas.map((data, index) => {
175-
// Calculate styles based on position relative to active index
176118
const isActive = index === activeIndex;
177-
const offset = index - activeIndex;
178-
179-
// Handle wraparound for better visual effect
180-
const wrappedOffset = offset > traceDatas.length / 2
181-
? offset - traceDatas.length
182-
: offset < -traceDatas.length / 2
183-
? offset + traceDatas.length
184-
: offset;
185-
186-
// Calculate z-index to ensure proper stacking
187-
const zIndex = isActive ? traceDatas.length : traceDatas.length - Math.abs(wrappedOffset);
188-
189-
// Calculate transform for 3D effect
190-
// Active element - rotates with mouse movement
191-
// Inactive elements - positioned to sides based on their relation to active
192-
let transform = isActive
193-
? `rotateY(${rotation}deg) rotateX(${-tiltY}deg) translateZ(0)`
194-
: `rotateY(${rotation + (wrappedOffset * 25)}deg) translateZ(${-250}px) translateX(${wrappedOffset * 200}px)`;
195-
196-
// Apply additional scaling for distance effect
197-
const scale = isActive ? 1 : 1 - Math.min(0.3, Math.abs(wrappedOffset) * 0.15);
198-
transform += ` scale(${scale})`;
199-
200-
// Calculate opacity based on distance
201-
const opacity = isActive ? 1 : Math.max(0.2, 0.8 - Math.abs(wrappedOffset) * 0.2);
202-
203-
// Only render traces that would be visible (performance optimization)
204-
const isVisible = Math.abs(wrappedOffset) <= 2;
205-
206-
if (!isVisible) return null;
207119

208120
return (
209121
<div
210122
key={viewerIds[index]}
211-
className={`absolute top-0 left-0 w-full h-full transition-3d ${
212-
isTransitioning ? 'duration-300' : 'duration-500'
123+
className={`absolute top-0 left-0 w-full h-full transition-opacity duration-300 ${
124+
isActive ? 'opacity-100 z-10' : 'opacity-0 z-0'
213125
}`}
214-
style={{
215-
zIndex,
216-
transform,
217-
opacity,
218-
filter: isActive ? 'none' : `blur(${Math.min(4, Math.abs(wrappedOffset) * 2)}px)`,
219-
pointerEvents: isActive ? 'auto' : 'none',
220-
}}
221126
>
222-
<div className={`w-full h-full ${isActive && 'shadow-2xl'}`}>
127+
<div className="w-full h-full">
223128
<TraceViewer data={data} id={viewerIds[index]} />
224129
</div>
225130
</div>
@@ -228,7 +133,7 @@ export default function TraceCarousel({
228133
</div>
229134

230135
{/* Trace information and controls */}
231-
<div className="absolute top-4 left-4 right-4 flex justify-between items-center z-50">
136+
<div className="absolute -top-12 left-4 right-4 flex justify-between items-center z-50">
232137
<div className="bg-black/50 text-white px-4 py-2 rounded-lg text-sm font-medium flex items-center gap-2">
233138
<span>Trace {activeIndex + 1} of {traceDatas.length}</span>
234139
<button
@@ -250,14 +155,10 @@ export default function TraceCarousel({
250155
)}
251156
</button>
252157
</div>
253-
{/* <div className="bg-blue-600/80 text-white px-4 py-2 rounded-lg text-sm flex items-center">
254-
<div className="h-2 w-2 rounded-full bg-white mr-2 animate-pulse"></div>
255-
<span>Move mouse to rotate view</span>
256-
</div> */}
257158
</div>
258159
</div>
259160

260-
{/* Navigation controls - now outside the main carousel container */}
161+
{/* Navigation controls */}
261162
<div className="absolute bottom-0 left-0 right-0 flex justify-center gap-3 z-50">
262163
<button
263164
onClick={prevTrace}

src/styles/globals.css

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,4 @@ html, body {
2525
width: 100%;
2626
margin: 0;
2727
padding: 0;
28-
}
29-
30-
/* 3D Perspective Styles */
31-
.perspective-1000 {
32-
perspective: 1000px;
33-
transform-style: preserve-3d;
34-
}
35-
36-
.transition-3d {
37-
transition: transform 0.5s ease-out, opacity 0.5s ease-out;
38-
}
39-
40-
/* Carousel Animation */
41-
@keyframes carousel-slide-in {
42-
from {
43-
transform: translateX(100%) rotateY(30deg);
44-
opacity: 0;
45-
}
46-
to {
47-
transform: translateX(0) rotateY(0deg);
48-
opacity: 1;
49-
}
50-
}
51-
52-
.carousel-slide-in {
53-
animation: carousel-slide-in 0.5s ease-out forwards;
5428
}

0 commit comments

Comments
 (0)