Anonymous
Я хочу изменить направление шлепа
Сообщение
Anonymous » 14 сен 2025, 03:16
Я хочу изменить направление шлепка, на данный момент она находится снизу вверх. Секунды, когда я нашел результат, как это может быть любым из них, поэтому снизу вверх он создает иллюзию, но сверху вниз он не мог, и в результате он показывает разрыв в верхней части, так что можно сделать, любой другой лучший подход, пожалуйста! < /p>
Код: Выделить всё
import { FC, useEffect, useRef, useMemo, useCallback } from 'react';
import styles from './SpinningBarWheel.module.css';
import SlotItem from './spinBarHighlight/slotItem/SlotBackgroundItem';
import WheelHighlight from './spinBarHighlight/wheelHighlight/WheelHighlight';
// import { isMatchingPrize } from '../wheelDropModals/spinBarUtils';
import type { WinNotificationType, PrizedropPrizeType } from '@pp/core/src/api/fetchers/promotionsV2/types/promotions';
interface Props {
spinBarItems: { text: string; color: string; isBaseColor?: boolean; prize?: PrizedropPrizeType }[];
result: WinNotificationType;
}
const SpinningBarWheel: FC = ({ result, spinBarItems }) => {
console.log(result, "result");
const reelRef = useRef(null);
const posRef = useRef(0);
const animRef = useRef();
const winningIndexRef = useRef(null);
const rowHeight = 100;
const reelLength = spinBarItems.length * rowHeight;
const getMiddleOffset = () => window.innerHeight / 2 - rowHeight / 2;
console.log(getMiddleOffset(), 'getMiddleOffset');
// useEffect(() => {
// const handleResize = () => {
// if (winningIndexRef.current !== null && reelRef.current) {
// const loops = 10;
// const newOffset = getMiddleOffset();
// const targetPos = -((winningIndexRef.current + loops * spinBarItems.length) * rowHeight) + newOffset;
// posRef.current = targetPos;
// reelRef.current.style.transform = `translateY(${posRef.current % reelLength}px)`;
// }
// };
// window.addEventListener('resize', handleResize);
// return () => window.removeEventListener('resize', handleResize);
// }, [spinBarItems.length, reelLength, rowHeight]);
const getMiddleTextElement = useCallback(() => {
if (!reelRef.current) return null;
const rects = Array.from(reelRef.current.children) as HTMLDivElement[];
const middleY = window.innerHeight / 2;
for (const child of rects) {
const rect = child.getBoundingClientRect();
if (rect.top = middleY) {
return child.querySelector('span') as HTMLSpanElement;
}
}
return null;
}, []);
const renderedSlotItems = useMemo(() => {
const loops = 6;
return Array.from({ length: Math.ceil(loops) }).flatMap((_, i) =>
spinBarItems.map((item, j) => (
))
);
}, [spinBarItems]);
const easeOutCubic = useCallback((t: number) => 1 - Math.pow(1 - t, 3), []);
useEffect(() => {
const candidatePositions: number[] = [];
spinBarItems.forEach((item, idx) => {
if (idx === 3) {
winningIndexRef.current = idx; // Save for snapping later
console.log(idx, "idx");
for (let loop = 0; loop < 20; loop++) {
const pos = getMiddleOffset() - ((idx + loop * spinBarItems.length) * rowHeight);
console.log(pos, "pos");
candidatePositions.push(pos);
}
}
});
const target = candidatePositions[candidatePositions.length - 1];
const start = posRef.current;
const distance = target - start;
const duration = 500;
const startTime = Date.now();
console.log({ target, start, distance }, 'animation start');
const animate = () => {
const elapsed = Date.now() - startTime;
const t = Math.min(1, elapsed / duration);
const eased = easeOutCubic(t);
posRef.current = start + distance * eased;
if (reelRef.current) {
reelRef.current.style.transform = `translateY(${posRef.current % reelLength}px)`;
console.log(posRef.current % reelLength, 'current pos');
}
if (t < 1) {
animRef.current = requestAnimationFrame(animate);
} else {
const middleSpan = getMiddleTextElement();
if (middleSpan) {
middleSpan.classList.add(styles.resultScale);
setTimeout(() => middleSpan.classList.remove(styles.resultScale), 4000);
}
}
};
animRef.current = requestAnimationFrame(animate);
return () => {
if (animRef.current) {
cancelAnimationFrame(animRef.current);
}
};
}, [result, spinBarItems, reelLength, easeOutCubic, getMiddleTextElement]);
return (
{renderedSlotItems}
);
};
export default SpinningBarWheel;< /code>
Подробнее здесь:
https://stackoverflow.com/questions/797 ... -bottom-to
1757809018
Anonymous
Я хочу изменить направление шлепка, на данный момент она находится снизу вверх. Секунды, когда я нашел результат, как это может быть любым из них, поэтому снизу вверх он создает иллюзию, но сверху вниз он не мог, и в результате он показывает разрыв в верхней части, так что можно сделать, любой другой лучший подход, пожалуйста! < /p> [code]import { FC, useEffect, useRef, useMemo, useCallback } from 'react'; import styles from './SpinningBarWheel.module.css'; import SlotItem from './spinBarHighlight/slotItem/SlotBackgroundItem'; import WheelHighlight from './spinBarHighlight/wheelHighlight/WheelHighlight'; // import { isMatchingPrize } from '../wheelDropModals/spinBarUtils'; import type { WinNotificationType, PrizedropPrizeType } from '@pp/core/src/api/fetchers/promotionsV2/types/promotions'; interface Props { spinBarItems: { text: string; color: string; isBaseColor?: boolean; prize?: PrizedropPrizeType }[]; result: WinNotificationType; } const SpinningBarWheel: FC = ({ result, spinBarItems }) => { console.log(result, "result"); const reelRef = useRef(null); const posRef = useRef(0); const animRef = useRef(); const winningIndexRef = useRef(null); const rowHeight = 100; const reelLength = spinBarItems.length * rowHeight; const getMiddleOffset = () => window.innerHeight / 2 - rowHeight / 2; console.log(getMiddleOffset(), 'getMiddleOffset'); // useEffect(() => { // const handleResize = () => { // if (winningIndexRef.current !== null && reelRef.current) { // const loops = 10; // const newOffset = getMiddleOffset(); // const targetPos = -((winningIndexRef.current + loops * spinBarItems.length) * rowHeight) + newOffset; // posRef.current = targetPos; // reelRef.current.style.transform = `translateY(${posRef.current % reelLength}px)`; // } // }; // window.addEventListener('resize', handleResize); // return () => window.removeEventListener('resize', handleResize); // }, [spinBarItems.length, reelLength, rowHeight]); const getMiddleTextElement = useCallback(() => { if (!reelRef.current) return null; const rects = Array.from(reelRef.current.children) as HTMLDivElement[]; const middleY = window.innerHeight / 2; for (const child of rects) { const rect = child.getBoundingClientRect(); if (rect.top = middleY) { return child.querySelector('span') as HTMLSpanElement; } } return null; }, []); const renderedSlotItems = useMemo(() => { const loops = 6; return Array.from({ length: Math.ceil(loops) }).flatMap((_, i) => spinBarItems.map((item, j) => ( )) ); }, [spinBarItems]); const easeOutCubic = useCallback((t: number) => 1 - Math.pow(1 - t, 3), []); useEffect(() => { const candidatePositions: number[] = []; spinBarItems.forEach((item, idx) => { if (idx === 3) { winningIndexRef.current = idx; // Save for snapping later console.log(idx, "idx"); for (let loop = 0; loop < 20; loop++) { const pos = getMiddleOffset() - ((idx + loop * spinBarItems.length) * rowHeight); console.log(pos, "pos"); candidatePositions.push(pos); } } }); const target = candidatePositions[candidatePositions.length - 1]; const start = posRef.current; const distance = target - start; const duration = 500; const startTime = Date.now(); console.log({ target, start, distance }, 'animation start'); const animate = () => { const elapsed = Date.now() - startTime; const t = Math.min(1, elapsed / duration); const eased = easeOutCubic(t); posRef.current = start + distance * eased; if (reelRef.current) { reelRef.current.style.transform = `translateY(${posRef.current % reelLength}px)`; console.log(posRef.current % reelLength, 'current pos'); } if (t < 1) { animRef.current = requestAnimationFrame(animate); } else { const middleSpan = getMiddleTextElement(); if (middleSpan) { middleSpan.classList.add(styles.resultScale); setTimeout(() => middleSpan.classList.remove(styles.resultScale), 4000); } } }; animRef.current = requestAnimationFrame(animate); return () => { if (animRef.current) { cancelAnimationFrame(animRef.current); } }; }, [result, spinBarItems, reelLength, easeOutCubic, getMiddleTextElement]); return ( {renderedSlotItems} ); }; export default SpinningBarWheel;< /code> [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79764024/i-want-to-reverse-the-direction-of-the-slotreel-as-of-now-it-is-from-bottom-to[/url]