321 lines
7.2 KiB
Vue
321 lines
7.2 KiB
Vue
|
|
<template>
|
||
|
|
<view
|
||
|
|
class="page"
|
||
|
|
>
|
||
|
|
<view v-show="isActivity" class="rain-wrap">
|
||
|
|
<view
|
||
|
|
class="r-content"
|
||
|
|
:style="{
|
||
|
|
top: `${rcTop}rpx`,
|
||
|
|
left: `${rcLeft}rpx`,
|
||
|
|
transition: `all ${activityData.totalTime}s linear`
|
||
|
|
}"
|
||
|
|
>
|
||
|
|
<img
|
||
|
|
v-for="(packet, index) in redPackets"
|
||
|
|
:key="packet.id"
|
||
|
|
src="@/static/packet.png"
|
||
|
|
class="r-packet"
|
||
|
|
:class="{ sPacket: packet.small }"
|
||
|
|
:style="{ left: `${packet.x}` + 'rpx', top: `${packet.y}` + 'rpx' }"
|
||
|
|
@tap="cClick(packet, index)"
|
||
|
|
/>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
<view v-show="!isActivity" class="s-wrap">
|
||
|
|
|
||
|
|
<view class="s-bt" @click="countdownStart">开始活动</view>
|
||
|
|
</view>
|
||
|
|
<view v-if="countdownFlag" class="countdown-wrap">
|
||
|
|
<view class="c-t-num">3</view>
|
||
|
|
<view class="c-t-num">2</view>
|
||
|
|
<view class="c-t-num">1</view>
|
||
|
|
<view class="c-t-num">GO</view>
|
||
|
|
</view>
|
||
|
|
|
||
|
|
<view class="popup" :class="{'hidden': !showHint}">
|
||
|
|
<view class="prize-wrap">
|
||
|
|
<view class="prize-card">
|
||
|
|
<view class="p-c-t-1">恭喜抢到</view>
|
||
|
|
<view class="p-c-t-2"
|
||
|
|
>{{ `${getRedPackets.length}` }}<text class="p-c-t-2_1">个红包</text></view
|
||
|
|
>
|
||
|
|
</view>
|
||
|
|
<image
|
||
|
|
class="alert-close"
|
||
|
|
src="@/static/alert_close.png"
|
||
|
|
mode="widthFix"
|
||
|
|
@click="showHint = false"
|
||
|
|
></image>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
</template>
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
name: 'Index',
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
showHint: false, // 红包雨结束弹窗展示
|
||
|
|
speed: 2, // 红包下落速度控制
|
||
|
|
countdownFlag: false,
|
||
|
|
isActivity: false,
|
||
|
|
redPackets: [], // 初始化红包雨
|
||
|
|
getRedPackets: [], // 抢到的红包
|
||
|
|
pId: 0,
|
||
|
|
rcTop: 0,
|
||
|
|
rcLeft: 0,
|
||
|
|
getPoint: 0,
|
||
|
|
activityData: {
|
||
|
|
totalTime: 10 // 活动持续时间 秒
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
onLoad() {
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
// 倒计时开始
|
||
|
|
async countdownStart() {
|
||
|
|
// 开启倒计时
|
||
|
|
this.countdownFlag = true
|
||
|
|
setTimeout(() => {
|
||
|
|
// 倒计时结束,开始红包雨
|
||
|
|
this.countdownFlag = false
|
||
|
|
this.start()
|
||
|
|
}, 4000)
|
||
|
|
},
|
||
|
|
// 活动开始
|
||
|
|
async start() {
|
||
|
|
this.isActivity = true
|
||
|
|
let sY = 0
|
||
|
|
for (let i = 0; i < this.activityData.totalTime * this.speed; i++) {
|
||
|
|
// 每个水平位置上放置两个红包
|
||
|
|
const rowNum = 2
|
||
|
|
for (let i = 0; i < rowNum; i++) {
|
||
|
|
const section = 750/rowNum
|
||
|
|
let base = i * section
|
||
|
|
this.redPackets.push({
|
||
|
|
x: base + Math.random() * section,
|
||
|
|
y: sY + Math.random() * 70, // 垂直距离上70的距离随机分布
|
||
|
|
small: Math.random() > 0.5, // 随机生成小型红包
|
||
|
|
id: this.pId++
|
||
|
|
})
|
||
|
|
}
|
||
|
|
// 每行红包垂直间距200
|
||
|
|
sY += 200
|
||
|
|
}
|
||
|
|
// 红包雨开始的位置
|
||
|
|
this.rcTop = 0 - sY
|
||
|
|
this.rcLeft = sY * 0.268 // sY * tan(15)
|
||
|
|
setTimeout(() => {
|
||
|
|
// 红包雨结束时的位置
|
||
|
|
this.rcTop = 0
|
||
|
|
this.rcLeft = 100
|
||
|
|
}, 100)
|
||
|
|
|
||
|
|
setTimeout(async () => {
|
||
|
|
// 红包雨结束
|
||
|
|
this.isActivity = false
|
||
|
|
this.showHint = true
|
||
|
|
}, this.activityData.totalTime * 1000)
|
||
|
|
},
|
||
|
|
cClick(packet, index) {
|
||
|
|
this.getRedPackets.push({ ...packet })
|
||
|
|
this.redPackets.splice(index, 1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<style scoped lang="scss">
|
||
|
|
.page {
|
||
|
|
width: 100%;
|
||
|
|
min-height: 100vh;
|
||
|
|
background-size: 100% 100%;
|
||
|
|
background-image: url('https://i.328888.xyz/2023/01/06/k485X.png');
|
||
|
|
|
||
|
|
.popup {
|
||
|
|
width: 100%;
|
||
|
|
height: 100vh;
|
||
|
|
background: rgba(0,0,0,0.6);
|
||
|
|
position: fixed;
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
z-index: 99;
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
transition: all 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.hidden {
|
||
|
|
opacity: 0;
|
||
|
|
visibility: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.s-wrap {
|
||
|
|
padding-top: 468rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.s-bt {
|
||
|
|
width: 530rpx;
|
||
|
|
height: 100rpx;
|
||
|
|
line-height: 100rpx;
|
||
|
|
background: linear-gradient(180deg, #fdf6d9 0%, #eda863 100%);
|
||
|
|
border-radius: 728rpx;
|
||
|
|
text-align: center;
|
||
|
|
font-size: 40rpx;
|
||
|
|
font-weight: 500;
|
||
|
|
color: #ee3320;
|
||
|
|
margin: 484rpx auto 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.rain-wrap {
|
||
|
|
width: 100%;
|
||
|
|
height: 100vh;
|
||
|
|
position: relative;
|
||
|
|
overflow: hidden;
|
||
|
|
background: rgba(0,0,0,0.6);
|
||
|
|
}
|
||
|
|
|
||
|
|
.r-content {
|
||
|
|
position: relative;
|
||
|
|
top: -400px;
|
||
|
|
// left: 200rpx;
|
||
|
|
transform: rotate(15deg);
|
||
|
|
// transition: all 8s linear;
|
||
|
|
}
|
||
|
|
|
||
|
|
.r-packet {
|
||
|
|
position: absolute;
|
||
|
|
width: 112rpx;
|
||
|
|
height: 224rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sPacket {
|
||
|
|
width: 72rpx;
|
||
|
|
height: 144rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.countdown-wrap {
|
||
|
|
position: fixed;
|
||
|
|
left: 0;
|
||
|
|
top: 0;
|
||
|
|
width: 100%;
|
||
|
|
height: 100vh;
|
||
|
|
background: rgba(0,0,0,0.6);
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.c-t-num {
|
||
|
|
position: absolute;
|
||
|
|
font-size: 288rpx;
|
||
|
|
font-family: 'D-DIN Exp', sans-serif;
|
||
|
|
font-weight: bold;
|
||
|
|
line-height: 338rpx;
|
||
|
|
background: linear-gradient(180deg, #faf6e8 0%, #eda863 100%);
|
||
|
|
background-clip: text;
|
||
|
|
-webkit-text-fill-color: transparent;
|
||
|
|
color: transparent;
|
||
|
|
transform: scale(0);
|
||
|
|
animation: ani 1s;
|
||
|
|
|
||
|
|
&:nth-child(2) {
|
||
|
|
animation-delay: 1s;
|
||
|
|
}
|
||
|
|
|
||
|
|
&:nth-child(3) {
|
||
|
|
animation-delay: 2s;
|
||
|
|
}
|
||
|
|
|
||
|
|
&:nth-child(4) {
|
||
|
|
animation-delay: 3s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@keyframes ani {
|
||
|
|
0% {
|
||
|
|
transform: scale(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
50% {
|
||
|
|
transform: scale(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
100% {
|
||
|
|
transform: scale(0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.prize-wrap {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.prize-card {
|
||
|
|
background-image: url('https://yswy-agent.yjdfytmall.com/20221230/e23c5a80-e4ab-4630-a4af-e34f533d88d3.png');
|
||
|
|
background-size: 100% 100%;
|
||
|
|
padding-top: 110rpx;
|
||
|
|
width: 492rpx;
|
||
|
|
height: 660rpx;
|
||
|
|
text-align: center;
|
||
|
|
box-sizing: border-box;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.p-c-t-1 {
|
||
|
|
font-size: 32rpx;
|
||
|
|
color: #f04d3c;
|
||
|
|
line-height: 38rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.p-c-t-2 {
|
||
|
|
font-size: 88rpx;
|
||
|
|
font-family: 'D-DIN Exp', sans-serif;
|
||
|
|
font-weight: bold;
|
||
|
|
color: #f1523f;
|
||
|
|
line-height: 103rpx;
|
||
|
|
margin-top: 16rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.p-c-t-2_1 {
|
||
|
|
font-family: normal;
|
||
|
|
font-weight: 400;
|
||
|
|
font-size: 32rpx;
|
||
|
|
color: #f04d3c;
|
||
|
|
line-height: 38rpx;
|
||
|
|
}
|
||
|
|
|
||
|
|
.p-c-t-3 {
|
||
|
|
font-size: 28rpx;
|
||
|
|
color: #fbecca;
|
||
|
|
line-height: 33rpx;
|
||
|
|
margin-top: 192rpx;
|
||
|
|
background-clip: text;
|
||
|
|
-webkit-text-fill-color: transparent;
|
||
|
|
}
|
||
|
|
|
||
|
|
.p-bt {
|
||
|
|
background-image: url('https://yswy-agent.yjdfytmall.com/20221230/37d7a076-15e6-4f2b-bc79-552f3a11b2fc.png');
|
||
|
|
background-size: 100% 100%;
|
||
|
|
width: 342rpx;
|
||
|
|
height: 88rpx;
|
||
|
|
text-align: center;
|
||
|
|
line-height: 70rpx;
|
||
|
|
font-size: 36rpx;
|
||
|
|
color: #ee331f;
|
||
|
|
text-shadow: 0 1rpx 0 #ffeeab;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.alert-close {
|
||
|
|
width: 64rpx;
|
||
|
|
margin-top: 32rpx;
|
||
|
|
width: 64rpx;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|