random reel
Mon Mar 03 2025 13:27:45 GMT+0000 (Coordinated Universal Time)
Saved by @Urvashi
import React, { useState, useEffect, useRef } from 'react';
import '../styles/reel.css';
import gameconfig from '../../gameconfig';
import { mediaUrl } from '../utils/axiosInstance';
interface SlotImage {
id: number;
image_path: string;
section_number: number;
}
interface ReelProps {
slotImages: SlotImage[];
isSpinning: boolean;
spinDuration?: number;
onSpinComplete?: () => void;
targetId?: number; // The section_number
}
const Reel: React.FC<ReelProps> = ({
slotImages,
isSpinning,
spinDuration = 2000,
onSpinComplete,
targetId = -1,
}) => {
const reelRef = useRef<HTMLDivElement>(null);
const [spinning, setSpinning] = useState(false);
const [displaySequence, setDisplaySequence] = useState<SlotImage[]>([]);
useEffect(() => {
document.documentElement.style.setProperty('--reel-border-color', gameconfig.reelBorder);
}, []);
// Generate a sequence with the target image centered in the viewport
useEffect(() => {
if (slotImages.length === 0) return;
// Find the target image by section_number
const targetImage = slotImages.find((img) => img.section_number === targetId) || slotImages[0];
const otherImages = slotImages.filter(
(img) => img.section_number !== targetImage.section_number,
);
// Function to get random image
const getRandomImage = () => {
const randomIndex = Math.floor(Math.random() * otherImages.length);
return otherImages[randomIndex] || slotImages[0]; // Fallback to first image
};
// Calculate viewport properties
const imageHeight = 113;
const viewportHeight = 339;
const imagesInViewport = Math.ceil(viewportHeight / imageHeight); // 3 images
const centerIndexInViewport = Math.floor(imagesInViewport / 2); // 1
// Create a much longer sequence for continuous spinning
const totalImages = 80; // more images for continuous spinning
const sequence: SlotImage[] = [];
// Fill sequence with random images before the target
for (let i = 0; i < totalImages / 2 - centerIndexInViewport; i++) {
sequence.push(getRandomImage());
}
// Add the target image at the center position
sequence.push(targetImage);
// Fill sequence with random images after the target
for (let i = sequence.length; i < totalImages; i++) {
sequence.push(getRandomImage());
}
setDisplaySequence(sequence);
}, [slotImages, targetId]);
useEffect(() => {
const reel = reelRef.current;
if (!reel || displaySequence.length === 0) return;
if (isSpinning && !spinning) {
setSpinning(true);
const imageHeight = 113;
const viewportHeight = 339;
const imagesInViewport = Math.ceil(viewportHeight / imageHeight); // 3
const centerIndexInViewport = Math.floor(imagesInViewport / 2); // 1
// Find the index of the target image in the sequence
const targetIndex = displaySequence.findIndex((img) => img.section_number === targetId);
if (targetIndex === -1) {
console.error(`Target image with section_number ${targetId} not found in sequence`);
return;
}
// Calculate stop position so target is centered in viewport
const stopPosition = -(targetIndex - centerIndexInViewport) * imageHeight;
console.log(
`Reel Stop Position: ${stopPosition}px for targetId (section_number): ${targetId}`,
);
// Reset the reel position
reel.style.transition = 'none';
reel.style.transform = 'translateY(0)';
void reel.offsetHeight; // Force reflow
const normalSpeedPhase = spinDuration * 0.5; //normal
const decelerationPhase = spinDuration * 1.0; //gradually slow
const spinDistance = displaySequence.length * imageHeight;
const midwayPosition = spinDistance * 0.5;
reel.style.transition = `transform ${normalSpeedPhase}ms linear`;
reel.style.transform = `translateY(-${midwayPosition}px)`;
setTimeout(() => {
reel.style.transition = `transform ${decelerationPhase}ms cubic-bezier(0.05, 0, 0.2, 1)`;
reel.style.transform = `translateY(${stopPosition}px)`;
}, normalSpeedPhase);
// Animation complete
setTimeout(() => {
setSpinning(false);
if (onSpinComplete) onSpinComplete();
}, spinDuration);
}
}, [isSpinning, spinning, spinDuration, displaySequence, slotImages, targetId, onSpinComplete]);
return (
<div className="reel-frames">
<div
className={`reels-machinery ${spinning ? 'spinning' : ''}`}
style={{ border: `4px solid ${gameconfig.reelBorder}` }}
>
<div className="reel-viewport">
<div className="reel" ref={reelRef}>
{displaySequence.map((image, index) => (
<div className="figures" key={`${image.id}-${index}`}>
<img
className="slot-image"
style={{ color: 'white' }}
src={`${mediaUrl}/${image.image_path}`}
alt={`imageno-> ${image.section_number},ID-> ${image.id}`}
/>
</div>
))}
</div>
</div>
</div>
</div>
);
};
export default Reel;



Comments