This commit is contained in:
Aleksey_Levin 2024-01-17 12:30:05 +03:00
commit db9c2829fd
5 changed files with 17021 additions and 75 deletions

16933
frontend/casino/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -2,67 +2,76 @@ import { useState, useEffect, useRef, useLayoutEffect } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import symbols2 from "../../../pages/SlotGamePage/symbols2"; import symbols2 from "../../../pages/SlotGamePage/symbols2";
function Reel({ isHorizontal, rng, rngReverse, cellCount }) {
const carousel = useRef(null);
const refs = useRef([]);
const cells = refs.current.map((value) => value);
const [selectedIndex, setSelectedIndex] = useState(null);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
let rotateFn = isHorizontal ? "rotateY" : "rotateX";
let radius;
let theta;
let cellAngle;
function randomNumberInRange(min, max) { interface ReelProps {
isHorizontal: boolean;
cellCount: string | number;
rng: boolean;
rngReverse: boolean;
}
function Reel({ isHorizontal, rng, rngReverse, cellCount }: ReelProps) {
const carousel = useRef<HTMLDivElement | null>(null);
const refs = useRef<(HTMLDivElement | null)[]>([]);
const cells = refs.current.map((value) => value);
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
const [width, setWidth] = useState<number>(0);
const [height, setHeight] = useState<number>(0);
let rotateFn = isHorizontal ? "rotateY" : "rotateX";
let radius: number;
let theta: number;
let cellAngle: number;
function randomNumberInRange(min: number, max: number): number {
// 👇️ get number between min (inclusive) and max (inclusive) // 👇️ get number between min (inclusive) and max (inclusive)
return Math.floor(Math.random() * (max - min + 1)) + min; return Math.floor(Math.random() * (max - min + 1)) + min;
} }
useEffect(() => { useEffect(() => {
return cellCount < 7 return Number(cellCount) < 7
? setSelectedIndex(selectedIndex + randomNumberInRange(3, 6)) ? setSelectedIndex(selectedIndex! + randomNumberInRange(3, 6))
: setSelectedIndex(selectedIndex + randomNumberInRange(6, 14)); : setSelectedIndex(selectedIndex! + randomNumberInRange(6, 14));
}, [rng]); }, [rng]);
useEffect(() => { useEffect(() => {
return cellCount < 7 return Number(cellCount) < 7
? setSelectedIndex(selectedIndex + randomNumberInRange(-3, -6)) ? setSelectedIndex(selectedIndex! + randomNumberInRange(-3, -6))
: setSelectedIndex(selectedIndex + randomNumberInRange(-6, -14)); : setSelectedIndex(selectedIndex! + randomNumberInRange(-6, -14));
}, [rngReverse]); }, [rngReverse]);
useLayoutEffect(() => { useLayoutEffect(() => {
setWidth(carousel.current.offsetWidth); setWidth(carousel.current!.offsetWidth);
setHeight(carousel.current.offsetHeight); setHeight(carousel.current!.offsetHeight);
setSelectedIndex(0); setSelectedIndex(0);
}, []); }, []);
useEffect(() => { useEffect(() => {
theta = 360 / cellCount; theta = 360 / Number(cellCount);
rotateFn = isHorizontal ? "rotateY" : "rotateX"; rotateFn = isHorizontal ? "rotateY" : "rotateX";
const angle = theta * selectedIndex * -1; const angle = theta * selectedIndex! * -1;
carousel.current.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angle}deg)`; carousel.current!.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angle}deg)`;
}, [selectedIndex]); }, [selectedIndex]);
function rotateCarousel() { function rotateCarousel() {
const angles = theta * selectedIndex * -1; const angles = theta * selectedIndex! * -1;
carousel.current.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angles}deg)`; carousel.current!.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angles}deg)`;
} }
function changeCarousel() { function changeCarousel() {
theta = 360 / cellCount; theta = 360 / Number(cellCount);
const cellSize = isHorizontal ? width : height; const cellSize = isHorizontal ? width : height;
radius = Math.round(cellSize / 2 / Math.tan(Math.PI / cellCount)); radius = Math.round(cellSize / 2 / Math.tan(Math.PI / Number(cellCount)));
// eslint-disable-next-line no-plusplus // eslint-disable-next-line no-plusplus
for (let i = 0; i < cells.length; i++) { for (let i = 0; i < cells.length; i++) {
const cell = cells[i]; const cell = cells[i];
if (i < cellCount) { if (i < Number(cellCount)) {
cell.style.opacity = 1; cell!.style.opacity = "1";
cellAngle = theta * i; cellAngle = theta * i;
cell.style.transform = `${rotateFn}(${cellAngle}deg) translateZ(${radius}px)`; cell!.style.transform = `${rotateFn}(${cellAngle}deg) translateZ(${radius}px)`;
rotateCarousel(); rotateCarousel();
} else { } else {
cell.style.opacity = 0; cell!.style.opacity = "0";
cell.style.transform = "none"; cell!.style.transform = "none";
} }
} }
} }
@ -71,6 +80,7 @@ function Reel({ isHorizontal, rng, rngReverse, cellCount }) {
rotateFn = isHorizontal ? "rotateY" : "rotateX"; rotateFn = isHorizontal ? "rotateY" : "rotateX";
changeCarousel(); changeCarousel();
} }
// set initials // set initials
onOrientationChange(); onOrientationChange();

View file

@ -1,14 +1,22 @@
import {useSlotMachine} from "../../web3/functions/SlotMachine/useSlotMachine.ts"; import PropTypes from "prop-types";
export const SlotPlayButton = () => { interface SlotPlayButtonProps {
onClick: () => void;
const { playSlot } = useSlotMachine() }
const SlotPlayButton: React.FC<SlotPlayButtonProps> = ({ onClick }) => {
return ( return (
<button <button
onClick={() => { playSlot() }} className="bg-rose-700 rounded-[100px] shadow text-white text-2xl font-bold py-5 px-10 hover:bg-rose-600 max-w-[200px]"
className="bg-rose-700 rounded-[100px] shadow text-white text-2xl font-bold py-5 px-10 hover:bg-rose-600"> onClick={onClick}
>
Крутить Крутить
</button> </button>
) );
} };
SlotPlayButton.propTypes = {
onClick: PropTypes.func.isRequired,
};
export default SlotPlayButton;

View file

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import { useState } from 'react';
import ContainerLayout from "../../utils/ContainerLayout" import ContainerLayout from "../../utils/ContainerLayout"
import { RPSPlayButton } from "../../components/web3/RPSPlayButton" import { RPSPlayButton } from "../../components/web3/RPSPlayButton"

View file

@ -1,68 +1,63 @@
import ContainerLayout from "../../utils/ContainerLayout" import {useEffect, useState} from "react";
import PropTypes from 'prop-types'; import ContainerLayout from "../../utils/ContainerLayout.tsx";
import Reel from '../../components/App/Slot/Reel'; import Reel from "../../components/App/Slot/Reel.tsx";
import { useEffect, useState } from 'react'; import SlotPlayButton from "../../components/web3/SlotPlayButton.tsx";
import { RPSPlayButton } from '../../components/web3/RPSPlayButton';
import {SlotPlayButton} from "../../components/web3/SlotPlayButton.tsx";
export const SlotGamePage = () => { export const SlotGamePage = () => {
const [isHorizontal, setIsHorizontal] = useState(false) const [isHorizontal, setIsHorizontal] = useState(false);
const [cellCount, setCellCount] = useState(7) const [rng, setRng] = useState(false);
const [rng, setRng] = useState(false) const [rngReverse, setRngReverse] = useState(false);
const [rngReverse, setRngReverse] = useState(false)
const mql = window.matchMedia('(orientation: portrait)') const mql = window.matchMedia("(orientation: portrait)");
mql.onchange = (e) => { mql.onchange = (e) => {
if (e.matches) { if (e.matches) {
setIsHorizontal(true) setIsHorizontal(true);
} else { } else {
setIsHorizontal(false) setIsHorizontal(false);
} }
} };
const handleRng = () => { const spinReels = () => {
setRng(!rng) // Trigger the spinning effect in each reel
} setRng(!rng);
const handleRngReverse = () => { setRngReverse(!rngReverse);
setRngReverse(!rngReverse) };
}
useEffect(() => { useEffect(() => {
if (mql.matches) { if (mql.matches) {
setIsHorizontal(true) setIsHorizontal(true);
} else { } else {
setIsHorizontal(false) setIsHorizontal(false);
} }
}, []) }, []);
return ( return (
<ContainerLayout> <ContainerLayout>
<div className="flex flex-row gap-4"> <div className="flex flex-row gap-4">
<div className="max-h-[180px] bg-green-700 flex flex-col justify-between shadow text-white text-2xl font-bold py-4 px-6 rounded-xl"> <div className="max-h-[180px] bg-green-700 flex flex-col justify-between shadow text-white text-2xl font-bold py-4 px-6 rounded-xl">
<div className="flex flex-col"> <div className="flex flex-col">
<p>выигрыш:</p><span className="text-yellow-400">5000</span> <p>выигрыш:</p>
<span className="text-yellow-400">5000</span>
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<p>ставка:</p><span className="text-yellow-400">10 000</span> <p>ставка:</p>
<span className="text-yellow-400">10 000</span>
</div> </div>
</div> </div>
<div className="min-h-[800px] w-full bg-fuchsia-600 flex items-center justify-center"> <div className="min-h-[800px] w-full flex items-center justify-center">
<div className="flex flex-row portrait:flex-col justify-center items-center my-auto"> <div className="flex flex-row portrait:flex-col justify-center items-center my-auto">
<Reel rng={rng} rngReverse={rngReverse} cellCount={cellCount} isHorizontal={isHorizontal} /> <Reel rng={rng} rngReverse={rngReverse} cellCount={7} isHorizontal={isHorizontal} />
<Reel rng={rng} rngReverse={rngReverse} cellCount={cellCount} isHorizontal={isHorizontal} /> <Reel rng={rng} rngReverse={rngReverse} cellCount={7} isHorizontal={isHorizontal} />
<Reel rng={rng} rngReverse={rngReverse} cellCount={cellCount} isHorizontal={isHorizontal} /> <Reel rng={rng} rngReverse={rngReverse} cellCount={7} isHorizontal={isHorizontal} />
</div> </div>
</div> </div>
<div className="max-w-[100px]"> <div className="max-w-[100px]">
<SlotPlayButton /> <SlotPlayButton onClick={spinReels} />
</div> </div>
</div> </div>
</ContainerLayout> </ContainerLayout>
); );
}
SlotGamePage.propTypes = {
cellCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
}; };