Authored by 李奇

抽奖转盘效果实现

... ... @@ -22,59 +22,157 @@ export default class wheelSurf extends PureComponent {
document.title ='大转盘';
super(props);
this.state = {
initial: true,
canStart: true, // 可以抽奖
pending: false, // 抽奖中
startEnd: false,
isEnding: false, // 即将停止
slowEnding: false, // 减速结束
startEnded: false, // 已结束
isLogin: false,
conf: {
loading: ''
}
},
totalParts: '',
remainCount: '',
angle: 0, // 当前旋转角度
speed: 0, // 旋转速度
stopAngle: 0, // 停止的角度
startSlowAngle: 0 // 起始减速的角度
};
this.init();
}
init = async () => {
// 登录状态
yaSDK.getUid().then(uid => {
this.setState({
uid,
isLogin: !!uid
});
});
let result = await conf({
act_id: +actId
});
if (result.code === 200) {
this.setState({
conf: result.data.conf
conf: result.data.conf,
totalParts: result.data.prize,
remainCount: result.data.residueCount,
})
}
};
componentDidMount = () => {
window.addEventListener('scroll', this.handleScroll);
begin = async () => {
// let result = await start({
// actId,
// uid: uid,
// sessionKey: cookie.load('app_session_key') || getQueryObj().session_key || '',
// sessionType: cookie.load('app_client_type') || '',
// appVersion: cookie.load('app_version') || ''
// });
await new Promise(resolve => {
let timer1 = setTimeout(() => {
clearTimeout(timer1);
resolve({idx: 3, message: '中奖了'});
}, 500)
});
let timer2 = setTimeout(() => {
clearTimeout(timer2);
console.log('中奖了');
this.state.stopAngle = this.calcStopAngle(1);
this.setState({
slowEnding: true
});
}, 2000)
};
componentWillUnmount = () => {
window.removeEventListener('scroll', this.handleScroll);
calcStopAngle = idx => {
return parseInt(360 / this.state.totalParts) * (this.state.totalParts - idx + 1) || 359;
};
start = async () => {
console.log('抽奖开始');
let uid = cookie.load('app_uid') || getQueryObj().uid || 0;
if(!uid || !parseInt(uid)){
const {isLogin, canStart} = this.state;
if (!isLogin) {
return yaSDK.goLogin();
}
if (!canStart) {
return;
}
// 开始抽奖
console.log('开始抽奖');
let result = await start({
actId,
uid: uid,
sessionKey: cookie.load('app_session_key') || getQueryObj().session_key || '',
sessionType: cookie.load('app_client_type') || '',
appVersion: cookie.load('app_version') || ''
});
this.state.canStart = false;
this.rotate();
this.begin();
};
if (result.code === 200) {
rotate = () => {
let {slowEnding, startEnded} = this.state;
if (startEnded) {
return;
}
if (!slowEnding) {
this.setState({
conf: result.data.conf
})
pending: true
});
if (this.state.speed < 20) {
this.state.speed += 0.2;
}
this.state.angle += this.state.speed;
if (this.state.angle >= 360) {
this.state.angle -= 360;
}
} else {
this.state.angle = parseInt(this.state.angle);
if (this.state.angle >= 360 ) {
this.state.angle -= 360;
}
if (!this.state.setStopAngle) {
this.state.angle += 3;
if (this.state.angle >= 359) {
this.state.angle = 0;
this.state.setStopAngle = true;
}
}
if (this.state.setStopAngle) {
let diff = this.state.stopAngle - this.state.angle;
switch (true) {
case (diff > 200):
this.state.angle += 4;
break;
case (diff > 100):
this.state.angle += 2;
break;
default:
this.state.angle += 1;
}
if (this.state.angle >= this.state.stopAngle) {
this.state.setStopAngle = false;
this.state.startEnded = true;
}
}
}
if (!this.state.startEnded) {
document.getElementById('rotateWheel').style.webkitTransform = 'rotateZ(' + this.state.angle + 'deg)';
requestAnimationFrame(this.rotate)
}
};
... ... @@ -101,12 +199,20 @@ export default class wheelSurf extends PureComponent {
bg: conf.jump_btn_right_bg
});
}
return links;
};
setCanStart = () => {
this.setState({
canStart: true,
slowEnding: false,
startEnded: false,
speed: 0
});
};
render() {
const {conf, isEnding, isLogin} = this.state;
const {conf, slowEnding, isLogin, totalParts, remainCount, pending} = this.state;
if (!conf.id) {
return (
... ... @@ -123,15 +229,22 @@ export default class wheelSurf extends PureComponent {
<img className="main-bg" src={conf.main_bg}/>
{conf.rule_btn_bg ? (<Link to={`${config.routerPath}/rule.html`}><img className="rule-btn" src={conf.rule_btn_bg}/></Link>) : ''}
{conf.share_btn_bg ? (<img className="share-btn" src={conf.share_btn_bg}/>): ''}
<img className="wheel-bg" src={conf.wheel_bg}/>
<img className="wheel-bg-surf-layer" src={conf.wheel_bg}/>
<img className="wheel-bg" id="rotateWheel" src={conf.wheel_bg}/>
<img onClick={()=>{this.start()}} className="start-btn-bg" src={conf.prize_btn_bg}/>
{
isLogin ?
(<div className="tips">
<p className="tip-1">今日剩余次数:{remainCount}</p>
<p className="tip-2">分享至朋友圈可以多1次抽奖机会</p>
</div>) : ''
}
<BottomButton links={links}/>
<Resource code={conf.code || '11421760f4ea8b231c5b8269f4ff65bb'}/>
<Resource code={conf.bottomContentCode}/>
{isEnding ? (<img className="prize-hit-bg" src={conf.win_prize_bg}/>) : ''}
{isEnding ? (<img className="prize-hit-start-bg" src={conf.prize_btn_bg}/>) : ''}
{slowEnding ? (<img onClick={this.setCanStart} className="prize-hit-bg transition" src={conf.win_prize_bg}/>) : ''}
{slowEnding ? (<span onClick={this.setCanStart} className="close-prize-hit-bg">关闭</span>) : ''}
{slowEnding ? (<img className="prize-hit-start-bg" src={conf.prize_btn_bg}/>) : ''}
</div>
)
}
... ...
... ... @@ -18,11 +18,30 @@
height: 630px;
margin-left: -315px;
}
@keyframes showHitBg
{
from {opacity: 0.1;}
to {opacity: 1;}
}
.prize-hit-bg {
position: absolute;
top: 0;
width: 750px;
width: 100%;
animation: showHitBg 2s 1;
}
.close-prize-hit-bg {
position: absolute;
top: 44px;
right: 60px;
font-family: PingFang-SC-Regular;
font-size: 28px;
color: #FFFFFF;
letter-spacing: 0;
margin: 20px;
}
.start-btn-bg, .prize-hit-start-bg {
... ... @@ -50,6 +69,28 @@
height: 62px;
}
.tips {
position: absolute;
top: 970px;
left: 0;
right: 0;
text-align: center;
.tip-1 {
font-family: PingFang-SC-Semibold;
font-size: 40px;
color: #FFFFFF;
letter-spacing: 0;
}
.tip-2 {
font-family: PingFang-SC-Regular;
font-size: 24px;
color: #FFFFFF;
letter-spacing: 0;
}
}
.bottom-btns {
position: absolute;
top: 1100px;
... ...
... ... @@ -45,12 +45,12 @@
"compression-webpack-plugin": "^1.1.11",
"copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.11",
"mini-css-extract-plugin":"^0.4.3",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"html-withimg-loader": "^0.1.16",
"json-loader": "^0.5.7",
"jsx-loader": "^0.13.2",
"mini-css-extract-plugin": "^0.4.3",
"node-sass": "^4.9.3",
"optimize-css-assets-webpack-plugin": "^4.0.0",
"postcss": "^7.0.2",
... ... @@ -65,7 +65,7 @@
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.3",
"webpack-merge": "^4.1.4",
"yoho-activity-sdk": "^1.0.2"
"yoho-activity-sdk": "^1.0.3"
},
"author": "陈峰 <feng.chen@yoho.cn>",
"license": "ISC",
... ...
... ... @@ -6510,6 +6510,6 @@ yargs@^7.0.0:
y18n "^3.2.1"
yargs-parser "^5.0.0"
yoho-activity-sdk@^1.0.2:
version "1.0.2"
resolved "http://npm.yohops.com/yoho-activity-sdk/-/yoho-activity-sdk-1.0.2.tgz#82f2e00c2bc11514b9243c9940273e2990d0c27c"
yoho-activity-sdk@^1.0.3:
version "1.0.3"
resolved "http://npm.yohops.com/yoho-activity-sdk/-/yoho-activity-sdk-1.0.3.tgz#2e012779bfc91cbafe9bf80f93018a432cde66b1"
... ...