Commit 3753bb8b authored by wanghuan's avatar wanghuan

1

parent 4864b784
import React,{useState, useEffect} from 'react' import React, { useState, useEffect } from "react";
import {View,Image,Text} from '@tarojs/components' import { View, Image, Text } from "@tarojs/components";
import styles from './RotateWheel.module.less' import styles from "./RotateWheel.module.less";
import {useThrottle} from '@/hooks/useThrottle' import { useThrottle } from "@/hooks/useThrottle";
import API from '@/api' import API from "@/api";
import { prizeList } from '@/mock' import { prizeList } from "@/mock";
import Taro,{showToast,redirectTo,navigateTo} from '@tarojs/taro' import Taro, { showToast, redirectTo, navigateTo } from "@tarojs/taro";
const oneTurn = 360; const oneTurn = 360;
const RotateWheel = (props) => { const RotateWheel = props => {
const {
const { containerInfo={width:600,height:600},
bg='https://yun.duiba.com.cn/spark/assets/8b6e920ffd09fab8f9ac2de09f9154879f4d0607.png', bg = "https://yun.duiba.com.cn/spark/assets/8b6e920ffd09fab8f9ac2de09f9154879f4d0607.png",
ratio=0.65, ratio = 0.65,
radius=300, radius = 300,
circles=4, circles = 4,
divideNum=8, divideNum = 8,
duration=5000, duration = 5000,
timeFunction='ease-out', timeFunction = "ease-out",
nodeInfo={width:100,height:100}, nodeInfo = { width: 100, height: 100 },
imgInfo={width:80,height:80}, imgInfo = { width: 80, height: 80 },
showWay="negative", showWay = "negative",
isShowPrizeName=true, isShowPrizeName = true,
prizeNameWidthRatio=1.2, prizeNameWidthRatio = 1.2,
callback=()=>{} callback = () => {}
} = props; } = props;
/* 奖品列表 */ /* 奖品列表 */
const [prizelist,setPrizelist] = useState(prizeList) const [prizelist, setPrizelist] = useState(prizeList);
/* 平分角度 */ /* 平分角度 */
const [angle,setAngle] = useState(oneTurn / divideNum) const [angle, setAngle] = useState(oneTurn / divideNum);
/* my.createAniamation */ /* my.createAniamation */
const [myAnimation,setMyAnimation] = useState() const [myAnimation, setMyAnimation] = useState();
/* 展示奖品列表 */ /* 展示奖品列表 */
const [show,setShow] = useState(false) const [show, setShow] = useState(false);
/* 转动一圈时的角度值 */ /* 转动一圈时的角度值 */
const [rotateInOneTurn,setRotateInOneTurn] = useState(0) const [rotateInOneTurn, setRotateInOneTurn] = useState(0);
/* 动画参数 */ /* 动画参数 */
const [ani,setAni] = useState({startFlag:false,option:{duration:duration,timeFunction:timeFunction,rotate:0}}) const [ani, setAni] = useState({
startFlag: false,
option: { duration: duration, timeFunction: timeFunction, rotate: 0 }
});
useEffect(()=>{ useEffect(() => {
computePosition() computePosition();
},[prizeList]) }, [prizeList]);
/** /**
* @description 获取奖品列表 * @description 获取奖品列表
*/ */
// const getPrizeListInfo = async () => { // const getPrizeListInfo = async () => {
// const {success,data,code,message} = await API.getRotatePrizeListInfo().catch((res)=>{ // const {success,data,code,message} = await API.getRotatePrizeListInfo().catch((res)=>{
// showToast({title:res?.message ? res?.message : '网络异常,请稍后再试'}) // showToast({title:res?.message ? res?.message : '网络异常,请稍后再试'})
// }) // })
// if(success && data){ // if(success && data){
// const {list} = data; // const {list} = data;
// // setPrizelist(list) // // setPrizelist(list)
// computePosition(list) // computePosition(list)
// } // }
// } // }
/**
* @description 计算奖品位置,旋转角度
*/
const computePosition = () => {
if(!prizeList.length) return;
let centerX,centerY,color,rotate;
/* 获取每块奖品的中心位置 */
prizelist.forEach((ele, i)=>{
if (i % 2 == 0) {
color = '#527aff';
} else {
color = '#f13082'
}
// 当前奖品左上角位置
if(showWay === 'negative'){
centerX = radius - ratio * radius * (Math.sin((angle / 2 + angle * (i)) / 180 * Math.PI));
centerY = radius - ratio * radius * (Math.cos((angle / 2 + angle * (i)) / 180 * Math.PI));
rotate = -(angle / 2 + angle * i);
} else {
centerX = radius - ratio * radius * (Math.sin((angle / 2 + angle * (-i)) / 180 * Math.PI));
centerY = radius - ratio * radius * (Math.cos((angle / 2 + angle * (-i)) / 180 * Math.PI));
// 旋转角度
rotate = -(angle / 2 + angle * (-i));
}
ele.rotate = rotate
ele.color = color
// 奖品位置
let disleft = centerX - nodeInfo.width / 2;
let distop = centerY - nodeInfo.height / 2;
ele.centerX = disleft
ele.centerY = distop
ele.num = i;
// 测试:设置奖品Id
ele.prizeId = 100 + i;
})
console.log('prizelist',prizelist);
setPrizelist(prizelist)
setShow(true)
}
/**
* @description 抽奖
*/
const drawPrize = useThrottle( async() => {
// const {success,data,message,code} = await API.drawRotatePrize().catch((res)=>{ /**
// showToast({title:res?.message ? res?.message : '网络异常,请稍后再试'}) * @description 计算奖品位置,旋转角度
// }); */
// if(success && data){ const computePosition = () => {
// const {prizeId,id} = data; if (!prizeList.length) return;
// } let centerX, centerY, color, rotate;
/* 获取每块奖品的中心位置 */
prizelist.forEach((ele, i) => {
if (i % 2 == 0) {
color = "#527aff";
} else {
color = "#f13082";
}
// test // 当前奖品左上角位置
let prizeId = Math.floor(Math.random() * prizelist.length) + 100; if (showWay === "negative") {
startRotation(prizeId) centerX =
setTimeout(() => { radius -
// 弹出弹窗 ratio * radius * Math.sin(((angle / 2 + angle * i) / 180) * Math.PI);
callback && callback()//prizeInfo centerY =
}, duration + 1000); radius -
},duration) ratio * radius * Math.cos(((angle / 2 + angle * i) / 180) * Math.PI);
rotate = -(angle / 2 + angle * i);
} else {
centerX =
radius -
ratio * radius * Math.sin(((angle / 2 + angle * -i) / 180) * Math.PI);
centerY =
radius -
ratio * radius * Math.cos(((angle / 2 + angle * -i) / 180) * Math.PI);
// 旋转角度
rotate = -(angle / 2 + angle * -i);
}
ele.rotate = rotate;
ele.color = color;
// 奖品位置
let disleft = centerX - nodeInfo.width / 2;
let distop = centerY - nodeInfo.height / 2;
ele.centerX = disleft;
ele.centerY = distop;
ele.num = i;
// 测试:设置奖品Id
ele.prizeId = 100 + i;
});
console.log("prizelist", prizelist);
setPrizelist(prizelist);
setShow(true);
};
/**
* @description 抽奖
*/
const drawPrize = useThrottle(async () => {
// const {success,data,message,code} = await API.drawRotatePrize().catch((res)=>{
// showToast({title:res?.message ? res?.message : '网络异常,请稍后再试'})
// });
// if(success && data){
// const {prizeId,id} = data;
// }
/** // test
* @description 根据奖品id开始旋转 let prizeId = Math.floor(Math.random() * prizelist.length) + 100;
* @param {*} prizeId 抽中的奖品id startRotation(prizeId);
*/ setTimeout(() => {
const startRotation = (prizeId) => { // 弹出弹窗
console.log('start'); callback && callback(); //prizeInfo
let rotateAngle; }, duration + 1000);
let num; }, duration);
let oneturnAngle;
prizelist.forEach((ele)=>{
if(ele.prizeId === prizeId){
num = ele.num;
}
})
// 旋转角度 ( 旋转圈数 + 对应位置(0,7) ) * 平分角度 + 平分角度 / 2 /**
if(showWay === 'negative'){ * @description 根据奖品id开始旋转
rotateAngle = oneTurn * circles + num * angle + angle / 2; * @param {*} prizeId 抽中的奖品id
oneturnAngle = num * angle + angle / 2; */
} else { const startRotation = prizeId => {
rotateAngle = oneTurn * circles + (prizelist.length - num) * angle + angle / 2; console.log("start");
oneturnAngle = (prizelist.length - num) * angle + angle / 2 let rotateAngle;
} let num;
console.log('rotateAngle',rotateAngle, num, prizeId); let oneturnAngle;
/* 执行动画 */ prizelist.forEach(ele => {
setAni({ if (ele.prizeId === prizeId) {
startFlag:true, num = ele.num;
option:{ }
...ani.option, });
rotate:ani.option.rotate - rotateInOneTurn + rotateAngle
}
})
setRotateInOneTurn(oneturnAngle)
// 旋转角度 ( 旋转圈数 + 对应位置(0,7) ) * 平分角度 + 平分角度 / 2
if (showWay === "negative") {
rotateAngle = oneTurn * circles + num * angle + angle / 2;
oneturnAngle = num * angle + angle / 2;
} else {
rotateAngle =
oneTurn * circles + (prizelist.length - num) * angle + angle / 2;
oneturnAngle = (prizelist.length - num) * angle + angle / 2;
} }
console.log("rotateAngle", rotateAngle, num, prizeId);
/* 执行动画 */
setAni({
startFlag: true,
option: {
...ani.option,
rotate: ani.option.rotate - rotateInOneTurn + rotateAngle
}
});
setRotateInOneTurn(oneturnAngle);
};
// my.createAnimation 旋转动画rot:旋转角度,timegap:旋转时间 // my.createAnimation 旋转动画rot:旋转角度,timegap:旋转时间
// const animateRotation = (rot, timegap) => { // const animateRotation = (rot, timegap) => {
// var animation = my.createAnimation({ // var animation = my.createAnimation({
// transformOrigin: "center center", // transformOrigin: "center center",
// duration: 5000, // duration: 5000,
// timeFunction: "ease-out", // timeFunction: "ease-out",
// delay: 0 // delay: 0
// }) // })
// console.log('animation',animation); // console.log('animation',animation);
// animation.rotate(rot).step();
// setMyAnimation(animation.export())
// setTimeout(() => {
// setMyAnimation()
// }, 5000);
// }
return( // animation.rotate(rot).step();
<> // setMyAnimation(animation.export())
<View className={`${styles['rotate_container']}`} // setTimeout(() => {
style={{ // setMyAnimation()
backgroundImage:`url(${bg})`, // }, 5000);
transform:ani.startFlag ? `rotate(${ani.option.rotate}deg)` : '', // }
transition:ani.startFlag ? `all ${ani.option.timeFunction} ${ani.option.duration}ms` : ''
}}
// animation={myAnimation}
>
{
show && prizelist.length && prizelist.map((ele, i)=>{
return(
<View
className={styles['item']}
style={{
// backgroundColor:`${ele?.color}`,
width:`${nodeInfo.width/100}rem`,
height:`${nodeInfo.height/100}rem`,
transform:`rotate(${ele?.rotate}deg)`,
top:`${ele.centerY/100}rem`,
left:`${ele.centerX/100}rem`,
position:'absolute'
}}
key={'item'+i}>
{
isShowPrizeName &&
<View
className={styles['prize_name']}
style={{
width:`${prizeNameWidthRatio * 100}%`,
height:`${30/100}rem`,
}} return (
>{ele.name}</View> <View
} className={styles["rotate"]}
<View className={styles['prize_img']} style={{
style={{ width: `${containerInfo.width / 100}rem`,
backgroundImage:`url(${ele.image})`, height: `${containerInfo.height / 100}rem`,
width:`${imgInfo.width/100}rem`, display: "flex",
height:`${imgInfo.height/100}rem` justifyContent: "center",
}} alignItems: "center"
></View> }}
</View> >
) <View
}) className={`${styles["rotate_container"]}`}
} style={{
</View> backgroundImage: `url(${bg})`,
<View className={styles['circle']} onTap={drawPrize}>draw</View> transform: ani.startFlag ? `rotate(${ani.option.rotate}deg)` : "",
</> transition: ani.startFlag
) ? `all ${ani.option.timeFunction} ${ani.option.duration}ms`
} : ""
export default RotateWheel }}
\ No newline at end of file // animation={myAnimation}
>
{show &&
prizelist.length &&
prizelist.map((ele, i) => {
return (
<View
className={styles["item"]}
style={{
// backgroundColor:`${ele?.color}`,
width: `${nodeInfo.width / 100}rem`,
height: `${nodeInfo.height / 100}rem`,
transform: `rotate(${ele?.rotate}deg)`,
top: `${ele.centerY / 100}rem`,
left: `${ele.centerX / 100}rem`,
position: "absolute"
}}
key={"item" + i}
>
{isShowPrizeName && (
<View
className={styles["prize_name"]}
style={{
width: `${prizeNameWidthRatio * 100}%`,
height: `${30 / 100}rem`
}}
>
{ele.name}
</View>
)}
<View
className={styles["prize_img"]}
style={{
backgroundImage: `url(${ele.image})`,
width: `${imgInfo.width / 100}rem`,
height: `${imgInfo.height / 100}rem`
}}
></View>
</View>
);
})}
</View>
<View className={styles["circle"]} onTap={drawPrize}>
draw
</View>
</View>
);
};
export default RotateWheel;
.rotate{
margin: 0 auto;
}
.rotate_container{ .rotate_container{
width: 100%; width: 100%;
height: 100%; height: 100%;
......
...@@ -215,17 +215,7 @@ function Index() { ...@@ -215,17 +215,7 @@ function Index() {
{/* 大转盘 */} {/* 大转盘 */}
<View className={styles['rotate']} <RotateWheel {...rotateConfig} callback={()=>{}} />
style={{
width:`${600/100}rem`,
height:`${600/100}rem`,
margin:`${100/100}rem auto`,
display:'flex',
justifyContent:'center',
alignItems:'center'
}} >
<RotateWheel {...rotateConfig} callback={()=>{}} />
</View>
<View className='view' onTap={playCurrentAudio}>play audio</View> <View className='view' onTap={playCurrentAudio}>play audio</View>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment