| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- import styles from "./styles.module.scss";
- import d_bg from "@assets/wheel/d.png";
- import bg_light from "@assets/wheel/bg_light.png";
- import light1 from "@assets/wheel/light1.png";
- import light2 from "@assets/wheel/light2.png";
- import spinBg from "@assets/wheel/spinBg.png";
- import pointer from "@assets/wheel/pointer.png"
- import styled from 'styled-components/macro';
- import React, {useEffect, useRef, useState} from "react";
- import spin_1 from "@assets/wheel/spin-1.png";
- import spin_2 from "@assets/wheel/spin-2.png";
- import spin_4 from "@assets/wheel/spin-4.png";
- import spin_5 from "@assets/wheel/spin-5.png";
- import draw from "@assets/wheel/draw.png";
- import {useDispatch, useSelector} from "react-redux";
- import {getIsHelp, getTurnplate, updateCollect, updateTimes} from "@features/turnplateSlice";
- import {formatCash, formatTime, localStorageGet} from "@utils/helpers";
- import SvgIcon from "@components/SvgIcon";
- import {ReactComponent as ShareIcon} from '@assets/singlesvg/share.svg';
- import {isLogined} from "@features/mainSlice";
- import {useNavigate} from "react-router";
- import {ROUTE_PATH} from "@constants/routes";
- import {reqTurnplateHelp, reqTurnplateKan} from "@features/api";
- import CountUp from "react-countup";
- import WPopInfo from "@widgets/WCashWheel/WPopInfo/WPopInfo";
- import {LOCAL_WHEEL_INVITE_CODE} from "@constants/localkey";
- const i18n=global.i18n;
- const spinImgSrc=[
- null,
- spin_1,
- spin_2,
- null,
- spin_4,
- spin_5
- ]
- const spinImg=[];
- const StyledCanvas=styled.canvas`
- background-image:url('${spinBg}');
- `
- const turnObj={
- timer:null,
- cdTimer:null,
- count:0,
- result:null,
- resTimer:null,
- flashTimer:null,
- resetTimer:null,
- ishelp:false
- };
- const WWheel=({openShare,showShare=true,onClose=null})=>{
- let turnplate=useSelector(getTurnplate);
- if(turnplate==null)turnplate={times:0};
- const data=[
- {id:0,type: 1,value: 0},
- {id:1,type: 0,value: 1000},
- {id:2,type: 0,value: 50},
- {id:3,type: 5,value: 0},
- {id:4,type: 1,value: 0},
- {id:5,type: 4,value: 0},
- {id:6,type: 2,value: 0},
- {id:7,type: 0,value: 1},
- ]
- const drawRef=useRef(null);
- const [imgLoaded,setImgLoaded]=useState(false);
- const dataLen=8;
- const startRotateDegree=3240;
- const startRotateDegreeDynamic=3240;
- const [drawStyle,setDrawStyle]=useState({});
- const [countdown,setCountdown]=useState(turnplate?turnplate.countdown:0);
- const isLogin=useSelector(isLogined);
- const navigate=useNavigate();
- const dispatch = useDispatch();
- const stopduring=5.5;
- const resetduring=2;
- const [collect,setCollect]=useState(0);
- const [isLock,setIsLock]=useState(false);
- const [openPopInfo,setOpenPopInfo]=useState(false);
- const isHelpdone=useSelector(getIsHelp);
- const loadImgs=()=>{
- let totalCount=spinImgSrc.length;
- let loadedCount=0;
- let checkDone=()=>{
- if (loadedCount===totalCount){
- setImgLoaded(true);
- }
- }
- for (let i = 0; i < totalCount; i++) {
- let imgSrc=spinImgSrc[i];
- if (imgSrc==null){
- loadedCount++;
- spinImg[i]=null;
- checkDone();
- }
- else{
- let img=new Image;
- img.src=imgSrc;
- spinImg[i]=img;
- img.onload=()=>{
- loadedCount++;
- checkDone();
- }
- }
- }
- }
- const clearCDTimer=()=>{
- if (turnObj.cdTimer!=null){
- clearInterval(turnObj.cdTimer);
- turnObj.cdTimer=null;
- }
- }
- const checkCountdown=()=>{
- if (countdown>0){
- clearCDTimer();
- let left=countdown;
- turnObj.cdTimer=setInterval(()=>{
- left--;
- if (left<=0){
- clearCDTimer();
- setCountdown(0);
- return;
- }
- setCountdown(left);
- },1000);
- }
- }
- const onTurnResult=(data,code=200)=>{
- if (code!==200){
- resetWheel(0);
- return;
- }
- let type=data.type;
- let curr_amount=turnplate.collect_amount;
- let collect_amount=data.collect_amount;
- let change=(collect_amount-curr_amount);
- let id=-1;
- if (type===1){
- id=5;
- }
- else if (type===2){
- let ids=[0,4];
- let index=Math.floor(Math.random()*ids.length);
- id=ids[index];
- }
- turnObj.result={
- type:type,
- reward:id,
- amount:collect_amount,
- change:change
- };
- // turnObj.ishelp=ishelp;
- }
- const startSpin=()=>{
- // if (!isLogin){
- // if (onClose)onClose();
- // navigate(ROUTE_PATH.SIGN_IN);
- // return;
- // }
- if (isLock)return;
- if (turnplate.times<=0)return;
- startTurn();
- dispatch(reqTurnplateKan(onTurnResult));
- dispatch(updateTimes({times:(turnplate.times-1)}))
- setIsLock(true);
- }
- const clearTurnTimer=()=>{
- if (turnObj.timer!=null){
- clearInterval(turnObj.timer);
- turnObj.timer=null;
- }
- }
- const startTurn=()=>{
- clearTurnTimer();
- turnObj.count=0;
- let turnCount=turnObj.count;
- let during=0.333;
- let roteStyle={
- transform:`rotate(360deg)`,
- transition:`transform ${during*2}s cubic-bezier(0.42, 0.00, 1.00, 1.00)`,
- }
- setDrawStyle(roteStyle);
- let timer=setInterval(()=>{
- turnCount++;
- turnObj.count++;
- roteStyle={
- transform:`rotate(${turnCount*360}deg)`,
- transition:`transform ${during}s cubic-bezier(1.00, 1.00, 0.00, 0.00)`,
- }
- setDrawStyle(roteStyle);
- if(turnCount>2){
- if (turnObj.result){
- stopTurn(turnObj.result.reward);
- }
- }
- },during*1000);
- turnObj.timer=timer;
- }
- const stopTurn=(reward)=>{
- let index=0;
- for (let i = 0; i < dataLen; i++) {
- let item=data[i];
- if (item&&item.id===reward){
- index=i;
- break;
- }
- }
- let per=360/dataLen;
- let angle=turnObj.count*360+startRotateDegreeDynamic-(per*index);
- drawAnimation(angle);
- }
- const drawAnimation=(angle=startRotateDegreeDynamic)=>{
- clearTurnTimer();
- let roteStyle={
- transform:"rotate(".concat(angle, "deg)"),
- transition:`transform ${stopduring}s cubic-bezier(0.250, 0.460, 0.455, 0.995)`,
- };
- setDrawStyle(roteStyle);
- playRes(angle);
- }
- const flashDraw=()=>{
- let show=false;
- turnObj.flashTimer=setInterval(()=>{
- show=!show;
- let result=show?turnObj.result:null;
- drawWheel(result)
- },260)
- }
- const playRes=(angle=0)=>{
- clearResTimer();
- let during=(stopduring+0.5)*1000;
- turnObj.resTimer=setTimeout(()=>{
- flashDraw();
- if (turnObj.result.type===2){
- setCollect(turnObj.result.change);
- }
- else if (turnObj.result.type===1){
- }
- if(!turnObj.ishelp)dispatch(updateCollect({collect_amount:turnObj.result.amount}))
- startReset(angle);
- },during)
- }
- // const
- const clearResTimer=()=>{
- if (turnObj.resTimer){
- clearTimeout(turnObj.resTimer);
- turnObj.resTimer=null;
- }
- if (turnObj.flashTimer){
- clearInterval(turnObj.flashTimer);
- turnObj.flashTimer=null;
- }
- }
- const startReset=(angle=0)=>{
- turnObj.resetTimer=setTimeout(()=>{
- checkShowPopInfo();
- resetWheel(angle);
- },resetduring*1000)
- }
- const checkShowPopInfo=()=>{
- let type=2;
- if (turnObj.result){
- type=turnObj.result.type;
- }
- if(type===2)setOpenPopInfo(true);
- }
- const resetWheel=(angle=0)=>{
- clearTurnTimer();
- turnObj.result=null;
- turnObj.count=0;
- turnObj.ishelp=false;
- if (angle==null)angle=0;
- else angle=angle%360;
- let roteStyle={
- transform:"rotate("+angle+"deg)",
- transition:``,
- };
- setDrawStyle(roteStyle);
- drawWheel(null);
- setCollect(0);
- setIsLock(false);
- clearResTimer();
- }
- const clearResetTimer=()=>{
- if (turnObj.resetTimer){
- clearTimeout(turnObj.resetTimer);
- turnObj.resetTimer=null;
- }
- }
- const drawWheel=(result)=>{
- let draw=drawRef.current;
- if (draw==null)return;
- let colors=["#B90615","#FFD760"];
- let color_len=colors.length;
- let fontSizeNum=25;
- if (data!=null){
- let s=draw;
- let rdat=data.slice(0,dataLen);
- let c=draw.getContext("2d");
- let dcwidth=draw.clientWidth;
- let dcheight=draw.clientHeight;
- let devicePixelRatioNum = window.devicePixelRatio < 1 ? 1 : window.devicePixelRatio;
- s.width=dcwidth*devicePixelRatioNum;
- s.height=dcheight*devicePixelRatioNum;
- c.clearRect(0, 0, s.width, s.height);
- let l = 2 * Math.PI / dataLen;
- let g = -s.width / 2 + s.width / 2 / 2.5;
- c.translate(s.width / 2, s.width / 2);
- c.rotate(-2*l);
- c.save();
- for (let i = 0; i < dataLen; i++) {
- let item=rdat[i];
- if (item==null)continue;
- let color=colors[i%color_len];
- if (result){
- if(result.reward===item.id){
- c.beginPath();
- c.moveTo(0, 0);
- c.arc(0, 0, s.width / 2 - 6, -l / 2, l / 2.08);
- c.strokeStyle = "#fff";
- c.fillStyle = "#fff";
- c.lineWidth = 10;
- c.lineTo(0, -5);
- c.stroke();
- c.closePath();
- }
- }
- c.rotate(l);
- c.save();
- c.beginPath();
- c.fillStyle = color;
- c.textBaseline = "middle";
- c.textAlign = "center";
- c.font = "".concat(devicePixelRatioNum * fontSizeNum, "px SWISSC-BT");
- c.translate(s.width / 5.2, -s.width / dataLen);
- c.rotate(.8);
- c.translate(-s.width / 5.2, s.width / dataLen);
- if (item.type===0){
- c.fillText(item.value,s.width / 7.2, g + devicePixelRatioNum * fontSizeNum * .36, 3 * s.width / dataLen);
- }
- else{
- let img=spinImg[item.type];
- if(img)c.drawImage(img, s.width / 23, g - 11 * devicePixelRatioNum, s.width / 5, s.width / 4.37);
- }
- c.restore();
- }
- }
- }
- const onHelpResult=(data)=>{
- console.log(data);
- }
- const checkHelpOther=()=>{
- let act=localStorageGet(LOCAL_WHEEL_INVITE_CODE);
- if (act!=null&&act!==""){
- if (!isHelpdone){
- dispatch(reqTurnplateHelp(onHelpResult));
- }
- }
- }
- useEffect(()=>{
- loadImgs();
- checkHelpOther();
- return ()=>{
- clearTurnTimer();
- clearCDTimer();
- clearResTimer();
- turnObj.result=null;
- clearResetTimer();
- }
- },[]);
- useEffect(()=>{
- if (imgLoaded){
- drawWheel();
- }
- },[imgLoaded])
- useEffect(()=>{
- checkCountdown();
- },[turnplate.countdown])
- const renderSpinInfo=()=>{
- let times=turnplate?turnplate.times:0;
- return (
- <>
- <div className={styles.spin_con}>
- <button className={styles.spin_btn} onClick={()=>{
- startSpin();
- }}>
- <img src={draw} className={styles.spin_img}/>
- <div className={styles.spin_content}>
- {
- collect>0?(
- <CountUp
- start={0}
- end={Number(formatCash(collect))}
- duration={1}
- separator=" "
- decimals={2}
- prefix={"+"}
- >
- {({ countUpRef, start }) => {
- return (
- <div ref={(ref)=>{
- countUpRef.current=ref;
- if (countUpRef.collect!==collect){
- countUpRef.collect=collect;
- start();
- }
- }} className={styles.collect_num}/>
- )
- }}
- </CountUp>
- ):(
- <div className={styles.spin_num}>{times}</div>
- )
- }
- </div>
- </button>
- </div>
- </>
- )
- }
- const renderCountDown=()=>{
- let d=Math.floor(countdown/86400);
- let time=countdown-d*86400;
- let stime=formatTime(time);
- let sd=i18n.language==="ru"?'д':'d';
- return (
- <div className={styles.cd_con}>
- <div>{i18n.t("turnplate.expires_in")}</div>
- <div className={styles.text}>{d+sd}</div>
- <div className={styles.text}>{stime}</div>
- </div>
- )
- }
- const renderShareBar=()=>{
- if (showShare){
- return (
- <button className={styles.share_con} onClick={()=>{
- if (openShare)openShare();
- }}>
- <div className={styles.share_bar}>
- <div className={styles.text}>{i18n.t("turnplate.invite_tips")}</div>
- <ShareIcon className={styles.icon}/>
- </div>
- </button>
- )
- }
- else {
- return (<></>);
- }
- }
- const renderPopInfo=()=>{
- return (
- <WPopInfo open={openPopInfo} onClose={()=>{
- setOpenPopInfo(false);
- }} openShare={openShare}></WPopInfo>
- )
- }
- return (
- <div className={styles.container}>
- <div className={styles.wheel}>
- <img src={bg_light} className={styles.bg_light}/>
- <img src={d_bg} className={styles.lamp}/>
- <div className={styles.drawContent}>
- <StyledCanvas ref={drawRef} className={styles.draw} style={drawStyle}/>
- </div>
- <img src={light1} className={`${styles.light} ${styles.light_ani_1}`}/>
- <img src={light2} className={`${styles.light} ${styles.light_ani_2}`}/>
- <img src={pointer} className={styles.pointer}/>
- {
- renderSpinInfo()
- }
- </div>
- {renderCountDown()}
- {renderShareBar()}
- {renderPopInfo()}
- </div>
- )
- }
- export default WWheel;
|