feat:
This commit is contained in:
commit
db9c2829fd
5 changed files with 17021 additions and 75 deletions
16933
frontend/casino/package-lock.json
generated
Normal file
16933
frontend/casino/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,67 +2,76 @@ import { useState, useEffect, useRef, useLayoutEffect } from "react";
|
|||
import PropTypes from "prop-types";
|
||||
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)
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
return cellCount < 7
|
||||
? setSelectedIndex(selectedIndex + randomNumberInRange(3, 6))
|
||||
: setSelectedIndex(selectedIndex + randomNumberInRange(6, 14));
|
||||
return Number(cellCount) < 7
|
||||
? setSelectedIndex(selectedIndex! + randomNumberInRange(3, 6))
|
||||
: setSelectedIndex(selectedIndex! + randomNumberInRange(6, 14));
|
||||
}, [rng]);
|
||||
|
||||
useEffect(() => {
|
||||
return cellCount < 7
|
||||
? setSelectedIndex(selectedIndex + randomNumberInRange(-3, -6))
|
||||
: setSelectedIndex(selectedIndex + randomNumberInRange(-6, -14));
|
||||
return Number(cellCount) < 7
|
||||
? setSelectedIndex(selectedIndex! + randomNumberInRange(-3, -6))
|
||||
: setSelectedIndex(selectedIndex! + randomNumberInRange(-6, -14));
|
||||
}, [rngReverse]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setWidth(carousel.current.offsetWidth);
|
||||
setHeight(carousel.current.offsetHeight);
|
||||
setWidth(carousel.current!.offsetWidth);
|
||||
setHeight(carousel.current!.offsetHeight);
|
||||
setSelectedIndex(0);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
theta = 360 / cellCount;
|
||||
theta = 360 / Number(cellCount);
|
||||
rotateFn = isHorizontal ? "rotateY" : "rotateX";
|
||||
const angle = theta * selectedIndex * -1;
|
||||
carousel.current.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angle}deg)`;
|
||||
const angle = theta * selectedIndex! * -1;
|
||||
carousel.current!.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angle}deg)`;
|
||||
}, [selectedIndex]);
|
||||
|
||||
function rotateCarousel() {
|
||||
const angles = theta * selectedIndex * -1;
|
||||
carousel.current.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angles}deg)`;
|
||||
const angles = theta * selectedIndex! * -1;
|
||||
carousel.current!.style.transform = `translateZ(${-radius}px) ${rotateFn}(${angles}deg)`;
|
||||
}
|
||||
|
||||
function changeCarousel() {
|
||||
theta = 360 / cellCount;
|
||||
theta = 360 / Number(cellCount);
|
||||
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
|
||||
for (let i = 0; i < cells.length; i++) {
|
||||
const cell = cells[i];
|
||||
if (i < cellCount) {
|
||||
cell.style.opacity = 1;
|
||||
if (i < Number(cellCount)) {
|
||||
cell!.style.opacity = "1";
|
||||
cellAngle = theta * i;
|
||||
cell.style.transform = `${rotateFn}(${cellAngle}deg) translateZ(${radius}px)`;
|
||||
cell!.style.transform = `${rotateFn}(${cellAngle}deg) translateZ(${radius}px)`;
|
||||
rotateCarousel();
|
||||
} else {
|
||||
cell.style.opacity = 0;
|
||||
cell.style.transform = "none";
|
||||
cell!.style.opacity = "0";
|
||||
cell!.style.transform = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +80,7 @@ function Reel({ isHorizontal, rng, rngReverse, cellCount }) {
|
|||
rotateFn = isHorizontal ? "rotateY" : "rotateX";
|
||||
changeCarousel();
|
||||
}
|
||||
|
||||
// set initials
|
||||
onOrientationChange();
|
||||
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
import {useSlotMachine} from "../../web3/functions/SlotMachine/useSlotMachine.ts";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export const SlotPlayButton = () => {
|
||||
|
||||
const { playSlot } = useSlotMachine()
|
||||
interface SlotPlayButtonProps {
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const SlotPlayButton: React.FC<SlotPlayButtonProps> = ({ onClick }) => {
|
||||
return (
|
||||
<button
|
||||
onClick={() => { playSlot() }}
|
||||
className="bg-rose-700 rounded-[100px] shadow text-white text-2xl font-bold py-5 px-10 hover:bg-rose-600">
|
||||
className="bg-rose-700 rounded-[100px] shadow text-white text-2xl font-bold py-5 px-10 hover:bg-rose-600 max-w-[200px]"
|
||||
onClick={onClick}
|
||||
>
|
||||
Крутить
|
||||
</button>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
SlotPlayButton.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default SlotPlayButton;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import ContainerLayout from "../../utils/ContainerLayout"
|
||||
import { RPSPlayButton } from "../../components/web3/RPSPlayButton"
|
||||
|
||||
|
|
|
@ -1,68 +1,63 @@
|
|||
import ContainerLayout from "../../utils/ContainerLayout"
|
||||
import PropTypes from 'prop-types';
|
||||
import Reel from '../../components/App/Slot/Reel';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { RPSPlayButton } from '../../components/web3/RPSPlayButton';
|
||||
import {SlotPlayButton} from "../../components/web3/SlotPlayButton.tsx";
|
||||
import {useEffect, useState} from "react";
|
||||
import ContainerLayout from "../../utils/ContainerLayout.tsx";
|
||||
import Reel from "../../components/App/Slot/Reel.tsx";
|
||||
import SlotPlayButton from "../../components/web3/SlotPlayButton.tsx";
|
||||
|
||||
export const SlotGamePage = () => {
|
||||
const [isHorizontal, setIsHorizontal] = useState(false)
|
||||
const [cellCount, setCellCount] = useState(7)
|
||||
const [rng, setRng] = useState(false)
|
||||
const [rngReverse, setRngReverse] = useState(false)
|
||||
const [isHorizontal, setIsHorizontal] = useState(false);
|
||||
const [rng, setRng] = useState(false);
|
||||
const [rngReverse, setRngReverse] = useState(false);
|
||||
|
||||
const mql = window.matchMedia('(orientation: portrait)')
|
||||
const mql = window.matchMedia("(orientation: portrait)");
|
||||
|
||||
mql.onchange = (e) => {
|
||||
if (e.matches) {
|
||||
setIsHorizontal(true)
|
||||
setIsHorizontal(true);
|
||||
} else {
|
||||
setIsHorizontal(false)
|
||||
setIsHorizontal(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleRng = () => {
|
||||
setRng(!rng)
|
||||
}
|
||||
const handleRngReverse = () => {
|
||||
setRngReverse(!rngReverse)
|
||||
}
|
||||
const spinReels = () => {
|
||||
// Trigger the spinning effect in each reel
|
||||
setRng(!rng);
|
||||
setRngReverse(!rngReverse);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (mql.matches) {
|
||||
setIsHorizontal(true)
|
||||
setIsHorizontal(true);
|
||||
} else {
|
||||
setIsHorizontal(false)
|
||||
setIsHorizontal(false);
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ContainerLayout>
|
||||
<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="flex flex-col">
|
||||
<p>выигрыш:</p><span className="text-yellow-400">5000</span>
|
||||
<p>выигрыш:</p>
|
||||
<span className="text-yellow-400">5000</span>
|
||||
</div>
|
||||
<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 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">
|
||||
<Reel rng={rng} rngReverse={rngReverse} cellCount={cellCount} isHorizontal={isHorizontal} />
|
||||
<Reel rng={rng} rngReverse={rngReverse} cellCount={cellCount} 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={7} isHorizontal={isHorizontal} />
|
||||
<Reel rng={rng} rngReverse={rngReverse} cellCount={7} isHorizontal={isHorizontal} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-[100px]">
|
||||
<SlotPlayButton />
|
||||
<SlotPlayButton onClick={spinReels} />
|
||||
</div>
|
||||
</div>
|
||||
</ContainerLayout>
|
||||
);
|
||||
}
|
||||
|
||||
SlotGamePage.propTypes = {
|
||||
cellCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
|
||||
};
|
Loading…
Reference in a new issue