一段时间没更新,是因为公司下面的子公司移动端开发需要人员去支援,好了,鄙人被派去了,主要完成四个小游戏的H5开发。接着挨个介绍这四个小游戏我是怎么完成的,以下只贴上核心代码文件,想要直接cv运行的话,可能不行嗷,看懂逻辑,自己去改也是一种学习过程!有问题私信我
红包雨
这里的需求:大小红包,点击大红包10分,小红包5分,点击之后还有打开效果,大红包:小红包比例,二比五。我这里采用的是100以内的随机数,2的整除数和5的整除数。
CountdownTimer.vue 倒计数组件,时间到,跳出游戏结束弹框
<template>
<div class="countdown_box">
<p class="countdown">{{ formattedTime }}s</p>
</div>
</template>
<script>
import { Bus } from '@/util/bus'
export default {
data() {
return {
timeLeft: 15000, // 总时间(毫秒)
countdownInterval: null,
microsecondIncrement: 0, // 用于模拟微秒增加
Count: 0
}
},
computed: {
formattedTime() {
const seconds = Math.floor(this.timeLeft / 1000)
const milliseconds = Math.floor((this.timeLeft % 1000) / 10)
const microseconds = this.microsecondIncrement % 100
return `${seconds.toString().padStart(2, '0')}:${milliseconds
.toString()
.padStart(2, '0')}:${microseconds.toString().padStart(2, '0')}`
}
},
mounted() {
this.startCountdown()
Bus.$on('Total', Total => {
this.Count = Total
})
},
beforeDestroy() {
this.stopCountdown()
},
methods: {
startCountdown() {
this.countdownInterval = setInterval(() => {
if (this.timeLeft > 0) {
this.timeLeft -= 10 // 每10毫秒减少10毫秒
this.microsecondIncrement++ // 模拟微秒增加
if (this.microsecondIncrement >= 1000) {
this.microsecondIncrement = 0 // 重置微秒模拟
}
} else {
this.stopCountdown()
Bus.$emit('countdownEnd', this.Count)
}
}, 10) // 每10毫秒更新一次时间
},
stopCountdown() {
clearInterval(this.countdownInterval)
}
}
}
</script>
<style lang="less" scoped>
.countdown_box {
text-align: center;
color: red;
.countdown {
font-size: 9vw;
}
}
</style>
index.vue 核心代码
<template>
<div class="rain-wrapper">
<CountdownTimer style="margin-top: 7.0667vw" ref="cutdown"></CountdownTimer>
<div ref="rainBox" id="rainBox" class="rainBox">
<rain-point
v-for="(item, idx) in rains"
:key="`rain-point-${idx}`"
:ref="`rain-point-${idx}`"
@rainPoinclick="rainPoinclick"
></rain-point>
</div>
</div>
</template>
<script>
import rainPoint from './tpl.vue'
import countdown from './countdown'
import CountdownTimer from '../CountdownTimer.vue'
import { Bus } from '@/util/bus.js'
export default {
name: 'rain',
props: {
density: {
// 雨点创建速度
type: Number,
default: 600
},
delay: {
// 雨点时长
type: Number,
default: 5
},
time: {
// 动画时长(秒)
type: Number,
default: 10
}
},
data() {
return {
count: 0, // 点击统计
rains: [], // 组件列表
rainsCount: 0, // 组件下标
createTimer: null, // 创建雨点计时器
flag: true, // 是否结束
isFiveCount: 0,
isTenCount: 0,
event: ''
}
},
components: {
rainPoint,
CountdownTimer
},
methods: {
// 结束后回调
timeoutCallback() {
this.$emit('timeoutCallback', this.count, this.isFiveCount, this.isTenCount)
},
// 点击雨点
rainPoinclick(e) {
if (!this.flag) return
this.count += 1
if (e.target._prevClass == 'rain-point_small') this.isFiveCount += 1
if (e.target._prevClass == 'rain-point_big') this.isTenCount += 1
Bus.$emit('Total', this.Total)
},
// 生成随机起始与落点坐标
grid() {
let [startX, startY, endX, endY] = [0, 0, 0, 0]
let rects = document.documentElement.getBoundingClientRect()
startX = Math.random() * (rects.width - 20)
startY = -20
endX = Math.random() * (rects.width - 20)
endY = rects.height
return {
startX,
startY,
endX,
endY
}
},
// 随机速度曲线值
newCubicBezier() {
let arr = ['0,.49,1,.3', '.04,.2,.93,.49', '.99,.36,.54,.46'] // 快 中 慢
// let idx = parseInt(Math.random() * 10) > 2 ? 0 : 1
let idx = parseInt(Math.random() * 3)
return arr[idx]
},
// 创建雨点
async create(rainscount) {
// 生成Dom
this.rains.push(`rain-point-${rainscount}`)
// 生成坐标
let rects = await this.grid()
// 渲染完成后执行
await this.$nextTick(async function () {
// Dom节点
let el = this.$refs[`rain-point-${rainscount}`][0]
let initStyleText = {
transform: `translate(${rects.startX}px, ${rects.startY}px)`
}
let actionStyleText = {
transition: `transform ${this.delay}s cubic-bezier(${this.newCubicBezier()})`,
transform: `translate(${rects.endX}px, ${rects.endY}px)`
}
// 设置初始坐标
await el.setStyle(initStyleText)
// 设置结束坐标
await setTimeout(() => {
el.setStyle(actionStyleText)
}, 50)
// 动画结束
el.$el.addEventListener('transitionend', el.destory, false)
})
},
// 执行
start() {
// this.$nextTick(() => {
// this.$refs.cutdown.startCountdown()
// })
this.clear()
// 开启雨点点击
this.flag = true
// 重置点击数
this.count = 0
// 清除动画定时器
countdown.clearAssignTimer('rain')
// 动画定时器
countdown.creatTimer({
remainTime: parseInt(this.time) * 1000,
label: 'rain',
timeoutFn: () => {
this.clear()
this.timeoutCallback()
}
})
// 创建节点
this.createTimer = setInterval(async () => {
await this.create(this.rainsCount)
this.rainsCount += 1
}, this.density)
},
// 停止
stop() {
this.flag = false
clearInterval(this.createTimer)
},
// 清空
clear() {
this.stop()
countdown.clearAssignTimer('rain')
this.rains = []
this.rainsCount = 0
}
},
computed: {
Total() {
return this.isFiveCount * 5 + this.isTenCount * 10
}
},
mounted() {
// window.start = this.start
// window.stop = this.stop
// window.clear = this.clear
// this.start()
}
}
</script>
<style>
.rain-wrapper {
width: 100%;
height: 250vw;
/* height: 100%; */
overflow: hidden;
position: relative;
}
.rainBox {
width: 100%;
}
</style>
tpl.vue
<template>
<div class="tyh">
<div
v-if="this.isShow"
@click="rainPoinclick"
:class="[
isClick ? 'action' : '',
this.isEven ? 'rain-point_small' : this.MultiFive ? 'rain-point_small' : 'rain-point_big'
]"
:style="styleText"
>
<transition name="number-fade">
<div class="addNum" v-if="showNumber">
<span>+</span>
<span>{{ this.isEven ? 5 : this.MultiFive ? 5 : 10 }}</span>
</div>
</transition>
</div>
</div>
</template>
<script>
export default {
name: 'rain-point',
props: {},
data() {
return {
styleText: {},
isShow: true,
isClick: false,
// 红包
total: 0,
showNumber: false,
event: ''
}
},
methods: {
rainPoinclick(e) {
this.event = e
if (this.isClick) return
this.isClick = true
this.showNumber = true
// 在动画完成后隐藏数字
this.$nextTick(() => {
setTimeout(() => {
this.showNumber = false
}, 500) // 动画持续时间,与CSS中的transition-duration保持一致
})
this.$emit('rainPoinclick', e)
},
setStyle(params) {
this.styleText = params
},
destory() {
this.isShow = false
},
created() {}
},
computed: {
isEven() {
return Math.floor(Math.random() * 100 + 1) % 2 === 0
},
MultiFive() {
return Math.floor(Math.random() * 100 + 1) % 10 === 0
}
},
watch: {}
}
</script>
<style lang="less" scoped>
.tyh {
.rain-point_small {
position: absolute;
width: 51px;
height: 65px;
background-image: url('~@/assets/image/draw/red-envelope-rain/envelope_small.png');
border-radius: 2.5vw;
}
.rain-point_big {
position: absolute;
width: 75px;
height: 95px;
background-image: url('~@/assets/image/draw/red-envelope-rain/envelope_big.png');
border-radius: 2.5vw;
}
.action {
width: 90px;
height: 120px;
background-image: url('~@/assets/image/draw/red-envelope-rain/envelope_open.png');
}
.number-fade-enter-active,
.number-fade-leave-active {
transition: opacity 0.5s;
}
.number-fade-enter,
.number-fade-leave-to {
opacity: 0;
}
.addNum {
font-size: 9vw;
color: red;
position: absolute;
}
}
</style>
打地鼠
倒计时组件和上述红包雨的一样,需要的话自行改造
<template>
<div class="draw-box">
<div v-if="centerDialogVisible" class="cover">
<div class="dialog">
<div class="el-dialog__header">
<div class="title">
{{ isTrue ? '挑战成功!' : '挑战失败!' }}
</div>
<img
:style="isTrue ? 'top:-31vw' : 'top:-22vw'"
:src="
isTrue
? require('@/assets/image/draw/red-envelope-rain/success.png')
: require('@/assets/image/draw/red-envelope-rain/fail.png')
"
/>
</div>
<div class="el-dialog__body">
<div class="content">
<h1 style="margin-top: 7.7333vw">
您的成绩为:
<span style="color: #fa3e56">{{ RankCount }}分</span>
</h1>
<span
class="tip"
v-if="!isTrue"
:style="isTrue ? 'margin-bottom: 4vw,margin-top:1.333vw' : ''"
>
成绩必须达到80分才能抽奖
</span>
<div class="divider1"></div>
<div class="the_Best">
<div class="BestGrade" style="margin-right: 6vw">
<span class="text">最佳成绩</span>
<span class="count">{{ rankBestgrade.bestPoint || RankCount }} 分</span>
</div>
<div class="vertical-divider"></div>
<div class="BestGrade" style="margin-left: 6vw">
<span class="text">最佳排名</span>
<span class="count">NO.{{ rankBestgrade.ranking || 1 }}</span>
</div>
</div>
<div class="divider2"></div>
<span v-show="isTrue" style="margin-top: 4vw">
今天还有
<span style="color: #fa3e56">{{ drawCount }}</span>
次抽奖机会
</span>
<button :style="isTrue ? 'margin-top: 4vw' : 'margin-top: 5vw'" @click="btnClick">
{{ isTrue ? '去抽奖' : '再玩一次' }}
</button>
</div>
</div>
<div class="dialog-footer">
<button class="return" @click="homepage">返回首页</button>
<button class="charts" @click="toCharts">排行榜</button>
</div>
</div>
</div>
<div class="content">
<header>
<CountdownTimer ref="CutDown"></CountdownTimer>
</header>
<div class="row_box">
<div class="row" v-for="y in size[1]" :key="y">
<!--在老鼠被击中时 不能触发点击事件-->
<div
class="box"
v-for="x in size[0]"
:key="x"
@click.stop.prevent="imgSrc !== imgList[1] && hitGround(x, y)"
>
<div class="img_box">
<img v-show="isShow(x, y)" :src="imgSrc" />
<!-- <img v-show="true" :src="imgSrc" /> -->
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<img v-if="showImg" class="round" src="@/assets/image/draw/strike-hamster/round.png" alt="" />
<img
v-if="showImg"
class="hammer_dec"
src="@/assets/image/draw/strike-hamster/hammer_dec.png"
alt=""
/>
<img class="bgc1" src="@/assets/image/draw/strike-hamster/game_bg1.png" alt="" />
</div>
<fillIn-address
:visible.sync="fillInVisible"
:lotteryId="lotteryId"
:prizeId="activePrizeId"
:prizeName="activePrizeName"
:orderId="activeOrderId"
:loginPhone="loginPhone"
:isRefresh="true"
></fillIn-address>
<prize-winning
:visible.sync="winningVisible"
:activePrizeName="activePrizeName"
:activePrizeIcon="activePrizeIcon"
:activePrizeType="activePrizeType"
:activePrizeTip="activePrizeTip"
@open-fillIn="openFillIn"
></prize-winning>
<prize-winning-error
:visible.sync="winningErrorVisible"
:winningErrorMsg="winningErrorMsg"
></prize-winning-error>
</div>
</template>
<script>
import strikeHamsterIndex from './mixin/index'
import { Bus } from '@/util/bus'
import CountdownTimer from './component/CountdownTimer.vue'
const fillInAddress = () => import('@/components/Address/fillIn.vue')
const prizeWinning = () => import('../component/winning.vue')
const prizeWinningError = () => import('../component/winning-error.vue')
export default {
name: 'strike-hamster',
mixins: [strikeHamsterIndex],
components: {
CountdownTimer,
'fillIn-address': fillInAddress,
'prize-winning': prizeWinning,
'prize-winning-error': prizeWinningError
},
data() {
return {
size: [5, 4],
mouseId: null, // 地鼠随机出现定时器的值
site: [], // 地鼠出现的位置
Counts: 0, // 分数
time: 15, // 游戏倒计时 s
timerId: null, // 倒计时定时器的值
// isClick: false, // 是否能点击开始游戏按钮
level: null, // 难度等级
speed: 800, // 地鼠出现的速度
// 地鼠图片
imgList: [
require('@/assets/image/draw/strike-hamster/strike_before.png'),
require('@/assets/image/draw/strike-hamster/strike_after.png')
],
// 当前地鼠的图片
imgSrc: null,
showImg: false // 是否显示图片
}
},
mounted() {
// 适配移动端界面
this.startGame()
const ua = navigator.userAgent
const ipad = ua.match(/(iPad).*OS\s([\d_]+)/)
const isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/)
const isAndroid = ua.match(/(Android)\s+([\d.]+)/)
const isMobile = isIphone || isAndroid
if (isMobile) {
this.size = [3, 3]
}
Bus.$on('countdownEnd', Total => {
this.countdownEndHandle(Total)
})
setTimeout(() => {
this.showImg = true
}, 20000)
},
methods: {
toCharts() {
this.$router.push({
path: '/StrikeHamster/RankingList',
query: {
id: this.lotteryId,
commonSign: this.commonSign,
miniprogramParam: this.miniProgramParam
}
})
},
homepage() {
this.$router.push({
path: '/StrikeHamster1',
query: {
id: this.lotteryId,
commonSign: this.commonSign,
miniprogramParam: this.miniProgramParam
}
})
},
// 初始化
ready() {
// 倒计时结束 不能调用函数
if (this.time > 0) {
this.imgSrc = this.imgList[0]
this.randomSite()
this.mouseId = setInterval(this.randomSite, this.speed)
}
},
// 渲染地鼠图片
isShow(x, y) {
return this.site[0] === x && this.site[1] === y
},
// 地鼠位置随机产生
randomSite() {
const x = Math.floor(Math.random() * this.size[0] + 1)
const y = Math.floor(Math.random() * this.size[1] + 1)
this.site = [x, y]
},
// 游戏倒计时
spendTime() {
this.timerId = setInterval(() => {
this.time--
if (this.time === 0) {
// 地鼠位置设为空
this.site = []
clearInterval(this.mouseId)
clearInterval(this.timerId)
// this.isClick = false
// 弹出游戏结束提示
// this.$message({
// message: '游戏结束',
// type: 'success',
// center: true,
// duration: 1000
// })
}
}, 1000)
},
// 打击地鼠
hitGround(x, y) {
// 打中地鼠 并且地鼠要出来
if (this.site[0] === x && this.site[1] === y && this.time > 0) {
// 增加分数
this.Counts += 10
// 切换为打中地鼠的图片
this.imgSrc = this.imgList[1]
// 暂停循环
clearInterval(this.mouseId)
// 地鼠位置置为空 延迟为了展示被击中的动画
setTimeout(() => {
this.site = []
}, 500)
// 延迟下 使音效和动作能衔接好 随机时间出现下次地鼠
setTimeout(() => {
// 重置地鼠位置和地鼠刷新时间
this.ready()
}, 1000)
}
Bus.$emit('Counts', this.Counts)
},
// 开始游戏
startGame() {
// 弹出游戏开始提示
// this.$message({
// message: '游戏开始',
// type: 'success',
// center: true,
// duration: 1000
// })
// 初始化时间和分数
this.time = 20
this.Counts = 0
this.ready()
this.spendTime()
// this.isClick = true
}
}
}
</script>
<style scope lang="scss">
.draw-box {
position: relative;
width: 100vw;
min-height: 100vh;
background-color: #f2cb79;
background-image: url(~@/assets/image/draw/strike-hamster/game_bg.png);
background-size: 100%;
background-repeat: no-repeat;
padding: 3.2vw 0 13.3333vw;
.cover {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 100;
background: rgba(0, 0, 0, 0.8);
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
// margin-top: 60.2667vw;
width: 80vw;
height: 116vw;
border-radius: 4vw;
background-color: #ffefbb;
.divider1 {
border-bottom: 1px solid #b3b3b3;
margin: 4.4vw 0;
width: 62.4vw;
}
.divider2 {
border-bottom: 1px solid #b3b3b3;
margin: 4.4vw 0;
width: 62.4vw;
}
.vertical-divider {
float: left;
width: 0.1333vw;
height: 100%;
background-color: #b3b3b3;
margin: 0 1vw;
}
.el-dialog__header {
width: 100vw;
padding: 3.7333vw 15.0667vw 0 38.9333vw;
.title {
color: #fa3e56;
font-size: 6.1333vw;
font-weight: 700;
}
img {
width: 51.7333vw;
height: 46.9333vw;
position: absolute;
top: -29.2vw;
left: -10vw;
}
}
.el-dialog__body {
padding: 9.4667vw 2.6667vw 0;
.content {
border-radius: 5vw;
height: 75vw;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
.tip {
margin-top: 3.3333vw;
color: #999999;
font-size: 3.4667vw;
}
.the_Best {
display: flex;
.BestGrade {
display: flex;
flex-direction: column;
align-items: center;
.text {
font-family: AlibabaPuHuiTi-Regular;
color: #333333;
font-size: 4vw;
margin-bottom: 4vw;
}
.count {
color: #e63814;
font-size: 4vw;
font-weight: 800;
}
}
}
button {
background-color: #e63814;
font-size: 4.2667vw;
color: #fff;
width: 53.3333vw;
height: 10.6667vw;
border-radius: 10vw;
border: 1vw solid #fa3e56;
}
.chance_box {
margin-top: 2vw;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.morechance {
font-size: 3.4667vw;
color: #999999;
}
.divider {
border-bottom: 1px solid #b3b3b3;
margin-top: 1vw;
}
}
}
}
.dialog-footer {
margin-top: 4.6667vw;
.return,
.charts {
margin-left: 8.8vw;
width: 28.5333vw;
height: 10.6667vw;
border-radius: 5vw;
font-size: 4.2667vw;
background-color: #ffefbb;
color: #e63814;
border: 0.5vw solid #e63814;
}
}
}
}
.footer {
position: absolute;
bottom: 0vw;
width: 100%;
.bgc1 {
width: 100%;
}
.round {
transition: transform 0.2s;
position: absolute;
left: 40vw;
}
.round:hover {
transform: scale(1.5);
}
.hammer_dec:hover {
transform: scale(1.5);
}
.hammer_dec {
transition: transform 0.2s;
position: absolute;
left: 46vw;
}
}
.content {
height: 100%;
width: 100%;
header {
// padding: 2.6667vw 6.6667vw 1.3333vw;
width: 100%;
top: 10vw;
position: absolute;
left: 6vw;
> div div {
display: flex;
justify-content: space-between;
align-items: center;
}
}
.row_box {
margin-top: 28vw;
.row {
display: flex;
.box {
top: 30vw;
display: flex;
justify-content: center;
width: 50vw;
height: 35vw;
cursor: url('~@/assets/image/draw/strike-hamster/hammer.png'), auto;
background-position: center;
background-image: url('~@/assets/image/draw/strike-hamster/field.png');
background-repeat: no-repeat;
.img_box {
width: 25vw;
height: 20vw;
text-align: center;
img {
// object-fit: cover;
width: 100%;
height: 100%;
}
}
}
}
}
}
}
</style>
拼图
倒计时组件和上述红包雨的一样,需要的话自行改造
<template>
<div class="draw-box">
<div v-if="centerDialogVisible" class="cover">
<div class="dialog">
<div class="el-dialog__header">
<div class="title">
{{ isTrue ? '挑战成功!' : '挑战失败!' }}
</div>
<img
@click="Cancel"
class="cancel"
src="../../../assets/image/draw/jigsaw-puzzle/cancel.png"
alt=""
/>
<img
class="icon"
:style="isTrue ? 'top:-31vw' : 'top:-22vw'"
:src="
isTrue
? require('@/assets/image/draw/red-envelope-rain/success.png')
: require('@/assets/image/draw/red-envelope-rain/fail.png')
"
/>
</div>
<div class="el-dialog__body">
<div class="content">
<h1 style="margin-top: 7.7333vw">
您的成绩为:
<span style="color: #5280c1">{{ this.completedTime }}s</span>
</h1>
<span
class="tip"
v-if="!isTrue"
:style="isTrue ? 'margin-bottom: 4vw,margin-top:1.333vw' : ''"
>
<!-- 成绩必须达到80分才能抽奖 -->
必须在120s内完成才能抽奖
</span>
<div class="divider1"></div>
<div class="the_Best">
<div class="BestGrade" style="margin-right: 6vw">
<span class="text">最佳成绩</span>
<span class="count">{{ rankBestgrade.bestSecond || 0 }} s</span>
</div>
<div class="vertical-divider"></div>
<div class="BestGrade" style="margin-left: 6vw">
<span class="text">最佳排名</span>
<span class="count">NO.{{ rankBestgrade.ranking || 1 }}</span>
</div>
</div>
<div class="divider2"></div>
<span v-show="isTrue" style="margin-top: 4vw">
今天还有
<span style="color: #fa3e56">{{ drawCount }}</span>
次抽奖机会
</span>
<button :style="isTrue ? 'margin-top: 4vw' : 'margin-top: 5vw'" @click="btnClick">
{{ isTrue ? '去抽奖' : '再玩一次' }}
</button>
</div>
</div>
<div class="dialog-footer">
<button class="return" @click="homepage">返回首页</button>
<button class="charts" @click="toCharts">排行榜</button>
</div>
</div>
</div>
<img class="time_bg" src="@/assets/image/draw/jigsaw-puzzle/time_bg.png" alt="" />
<div class="sample"
><img src="@/assets/image/draw/jigsaw-puzzle/topleft_corner.png" alt=""
/></div>
<div class="content">
<div class="time_text">用时:</div>
<header>
<CountdownTimer></CountdownTimer>
</header>
<div class="game_content">
<div class="puzzle_game">
<div class="wrap" ref="wrap">
<div class="play-page">
<div class="play-area" id="playArea">
<div
v-for="item in boxArr"
:index="item"
:key="item"
:class="['piece', 'piece-' + item, item == boxArractivelass ? 'active' : '']"
:style="{ backgroundImage: 'url(' + selectedImg + ')' }"
@click="changePositon($event, item)"
:ref="'piece' + item"
></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<img src="@/assets/image/draw/jigsaw-puzzle/game_bg_down.png" alt="" />
</div>
<fillIn-address
:visible.sync="fillInVisible"
:lotteryId="lotteryId"
:prizeId="activePrizeId"
:prizeName="activePrizeName"
:orderId="activeOrderId"
:loginPhone="loginPhone"
:isRefresh="true"
></fillIn-address>
<prize-winning
:visible.sync="winningVisible"
:activePrizeName="activePrizeName"
:activePrizeIcon="activePrizeIcon"
:activePrizeType="activePrizeType"
:activePrizeTip="activePrizeTip"
@open-fillIn="openFillIn"
></prize-winning>
<prize-winning-error
:visible.sync="winningErrorVisible"
:winningErrorMsg="winningErrorMsg"
></prize-winning-error>
</div>
</template>
<script>
import JigsawPuzzleIndex from './mixin/index'
import CountdownTimer from './component/CountdownTimer.vue'
const fillInAddress = () => import('@/components/Address/fillIn.vue')
const prizeWinning = () => import('../component/winning.vue')
const prizeWinningError = () => import('../component/winning-error.vue')
export default {
name: 'home',
mixins: [JigsawPuzzleIndex],
components: {
CountdownTimer,
'fillIn-address': fillInAddress,
'prize-winning': prizeWinning,
'prize-winning-error': prizeWinningError
},
data() {
return {
size: [5, 4],
mouseId: null, // 地鼠随机出现定时器的值
site: [], // 地鼠出现的位置
Counts: 0, // 分数
time: 15, // 游戏倒计时 s
timerId: null, // 倒计时定时器的值
level: null, // 难度等级
// 拼图
startDx: 0, // 初始位移,用于返回上一页
activeClass: -1,
boxArractivelass: -1,
prevIndex: null,
curIndex: 0,
curposArr: [],
clickStartBtn: false,
uploadimg: '',
selectedImg: '',
boxArr: new Array(9).fill(1).map((item, index) => {
return index
}),
pieces: document.querySelectorAll('.piece'),
pool: this.generateMatrix(3, 30.2667, 28),
// matrixArr: this.upsetArr(this.generateMatrix(3, 28, 20)),
matrixArr: this.upsetArr(this.generateMatrix(3, 30.2667, 28)),
// 30.2667
// matrixArr:this.shuffle(this.pieces, this.pool),
imgArr: [{ url: require('@/assets/image/draw/jigsaw-puzzle/topleft_corner1.png') }],
wall: 0,
prevEl: null, // 上一个元素,
dealtime: 600,
timer: null,
issuccess: false,
canvasUrl: '',
isVisible: false,
// isflag: false,
completedTime: 0
}
},
mounted() {
this.startGame()
},
methods: {
// start
getItem(index) {
this.activeClass = index
},
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files
if (!files.length) return
this.createImage(files[0])
},
createImage(file) {
// var image = new Image();
var reader = new FileReader()
var vm = this
reader.onload = e => {
vm.uploadimg = e.target.result
this.imgArr.push({
url: e.target.result
})
}
reader.readAsDataURL(file)
},
startGame(picIndex) {
// this.dealtime = 180;
this.timer = setInterval(this.timeStart, 1000)
// this.startDx = this.startDx - 100
// this.transformX(this.$refs.wrap, -100 + 'vw')
this.selectedImg = this.imgArr[0].url
this.shuffle(document.querySelectorAll('.piece'), this.pool)
},
// reOrder() {
// this.shuffle(document.querySelectorAll('.piece'), this.pool)
// },
// 点击高亮并且切换对应位置 (想办法交换对应索引位置的x,y值即可)
changePositon(e, item) {
//点击小图片切换位置方法
let reg = /active/g
this.boxArractivelass = item
let pieces = document.querySelectorAll('.piece')
if (!this.wall) {
this.wall = 1
this.prevEl = e.target
for (var i = 0, len = pieces.length; i < len; i++) {
// 使用replace为了避免元素后期加入其他类名
pieces[i].className = pieces[i].className.replace(' active', '')
}
!reg.test(this.className) && (this.className += ' active')
// this.className= this.className.replace(' active', '');
} else {
this.wall = 0
var prevIndex = +this.prevEl.getAttribute('index'),
curIndex = +e.target.getAttribute('index')
// 置换数组
this.swap(this.pool, prevIndex, curIndex)
this.prevEl.style.transform =
'translate(' + this.pool[prevIndex].x + 'vw,' + this.pool[prevIndex].y + 'vw' + ')'
e.target.style.transform =
'translate(' + this.pool[curIndex].x + 'vw,' + this.pool[curIndex].y + 'vw' + ')'
// 清除样式
// this.prevEl.className= this.prevEl.className.replace(' active', '');
this.boxArractivelass = -1
// 校验是否成功
if (this.isTestSuccess(this.pool)) {
this.completedTime = 600 - this.dealtime
if (this.completedTime < 120) {
this.centerDialogVisible = true
this.isTrue = true
this.countdownEndHandle(this.completedTime)
} else {
this.centerDialogVisible = true
this.isTrue = false
}
// 清除计时器
// this.clickStartBtn = true;
clearInterval(this.timer)
this.startDx -= 100
this.issuccess = true
// alert('成功')
// $('#playArea')[0].classList.add('active');
// $('#use_time').html(180-dealtime);
// setTimeout(function() {
// this.transformX(this.$refs.wrap, this.startDx + 'vw')
// }, 1200);
}
}
},
timeStart() {
this.dealtime--
if (this.dealtime < 1) {
this.centerDialogVisible = true
this.isTrue = false
this.isflag = false
clearInterval(this.timer)
// alert('挑战失败,请返回重新开始')
}
},
// overtime(num) {
// this.step = num;
// },
// 滑动元素
transformX(el, dx) {
el.style.transform = 'translateX(' + dx + ')'
},
// onceAgain() {
// this.shuffle(document.querySelectorAll('.piece'), this.pool)
// this.startDx = -100
// this.transformX(this.$refs.wrap, this.startDx + 'vw')
// this.resetTime()
// this.dealtime = 180
// this.timer = setInterval(this.timeStart, 1000)
// // this.$refs.child.initTime();
// },
// reStart() {
// this.startDx = this.startDx + 300
// this.transformX(this.$refs.wrap, this.startDx + 'vw')
// this.resetTime()
// // this.dealtime = 180;
// // this.timer = setInterval(this.timeStart, 1000);
// },
// 生成n维矩阵
generateMatrix(n, dx, dy) {
var arr = [],
index = 0
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
arr.push({ x: j * dx, y: i * dy, index: index })
index++
}
}
return arr
},
shuffle(els, arr) {
this.upsetArr(arr)
for (var i = 0, len = els.length; i < len; i++) {
var el = els[i]
el.setAttribute('index', i) // 将打乱后的数组索引缓存到元素中
el.style.transform = 'translate(' + arr[i].x + 'vw,' + arr[i].y + 'vw' + ')'
}
},
upsetArr(arr) {
// 方法1:
return arr.sort(function () {
return Math.random() > 0.5 ? -1 : 1
})
},
// 置换数组(对应索引的x,y值进行交换)
swap(arr, indexA, indexB) {
// let targetArr = [];
// arr.map(item => {
// if (item.index == indexA || item.index == indexB) {
// targetArr.push(item);
// }
// });
// [targetArr[0].x, targetArr[1].x] = [targetArr[1].x, targetArr[0].x];
// [targetArr[0].y, targetArr[1].y] = [targetArr[1].y, targetArr[0].y];
// return targetArr;
// var cache = arr[indexA];
// arr[indexA] = arr[indexB];
// arr[indexB] = cache;
// ES6的解耦交换方式: [arr[index], arr[n]] = [arr[n], arr[index]];
;[arr[indexA], arr[indexB]] = [arr[indexB], arr[indexA]]
},
// 校验是否成功方法
isTestSuccess(arr) {
return arr.every(function (item, i) {
return item.index === i
})
},
// 将canvas转化为图片
convertCanvasToImage(canvas, quality) {
var image = new Image()
image.src = canvas.toDataURL('image/png', quality)
return image
},
// end
toCharts() {
this.$router.push({
path: '/JigsawPuzzle/RankingList',
query: {
id: this.lotteryId
}
})
},
homepage() {
this.$router.push({
path: '/JigsawPuzzle1',
query: {
id: this.lotteryId
}
})
},
Cancel() {
this.centerDialogVisible = false
this.$router.push({
path: '/JigsawPuzzle1',
query: {
id: this.lotteryId
}
})
}
}
}
</script>
<style scope lang="scss">
.draw-box {
position: relative;
width: 100vw;
min-height: 100vh;
background-color: #178dc5;
background-image: url(~@/assets/image/draw/jigsaw-puzzle/game_bg_up.png);
background-size: 100%;
background-repeat: no-repeat;
padding: 3.2vw 0 13.3333vw;
// background-size: cover;
.footer {
width: 100%;
img {
width: 100%;
}
position: absolute;
bottom: 0vw;
.round {
transition: transform 0.2s;
position: absolute;
left: 40vw;
}
.round:hover {
transform: scale(1.5);
}
.hammer_dec:hover {
transform: scale(1.5);
}
.hammer_dec {
transition: transform 0.2s;
position: absolute;
left: 46vw;
}
}
.time_bg {
width: 54.4vw;
height: 15.7333vw;
position: absolute;
top: 11.4667vw;
right: 8vw;
}
.sample {
position: absolute;
width: 31.0667vw;
height: 29.0667vw;
left: 5.6vw;
top: 3.4667vw;
img {
width: 100%;
height: 100%;
}
}
.content {
height: 100%;
width: 100%;
.time_text {
font-size: 4vw;
color: #fff;
position: absolute;
top: 16.6667vw;
right: 37.0667vw;
}
header {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 15.5333vw;
right: 13.0667vw;
> div div {
display: flex;
justify-content: space-between;
align-items: center;
}
}
.game_content {
width: 100vw;
height: 118.2667vw;
position: absolute;
top: 43.3333vw;
background-image: url(~@/assets/image/draw/jigsaw-puzzle/game_bg_mid.png);
background-repeat: no-repeat;
background-position: center;
.puzzle_game {
.wrap {
// position: absolute;
display: flex;
// left: 28.3333vw;
// transition: transform 1s cubic-bezier(0.52, 0.37, 0.16, 1.32);
}
div {
box-sizing: border-box;
}
.btn {
display: inline-block;
padding: 10px 60px;
width: 300px;
background-color: #06c;
color: #fff;
cursor: pointer;
margin: 40px auto 10px;
z-index: 10;
}
#back {
margin-top: 10px;
}
.play-page,
.result-page,
.start-page,
.start-page .title {
text-align: center;
}
.play-page {
position: relative;
width: 100vw;
// height: 100vh;
}
.start-page .title {
line-height: 4em;
font-size: 24px;
}
.start-page .album-list {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.start-page .album-list .img-wrap {
margin-bottom: 0;
width: 33.33%;
height: 22vh;
overflow: hidden;
}
.start-page .album-list .img-wrap.active {
border: 4px solid #f00;
}
.start-page .album-list .img-wrap img {
width: 100%;
}
.start-page .album-list .img-wrap .file-wrap {
position: relative;
height: 100%;
background-position: center center;
background-size: 100%;
background-repeat: no-repeat;
}
.start-page .album-list .img-wrap .file-wrap::before {
content: '+';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 60px;
color: #ccc;
cursor: pointer;
}
.start-page .album-list .img-wrap .file-wrap input {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.start-page-ft {
position: absolute;
width: 100%;
bottom: 20px;
font-size: 12px;
text-align: center;
}
.start-page-ft a {
color: #06c;
}
.play-page {
// background-color: #4e2503;
}
.play-page .deloy {
padding: 10px 20px;
color: #fff;
}
.play-page .play-area {
position: relative;
// width: 84vw;
// height: 60vh;
width: 85.8vw;
height: 76vw;
display: flex;
flex-wrap: wrap;
margin: 22vw 5.8667vw;
z-index: 10;
// margin: 20px auto;
// background-color: pink;
}
.play-page .play-area.active {
outline-color: #1f8b40;
}
.play-page .play-area .piece {
position: absolute;
left: 0;
top: -1.6vw;
// width: 28vw;
// height: 20vh;
width: 30.2667vw;
height: 28vw;
border: 1px solid transparent;
background-repeat: no-repeat;
// background-size: 84vw 60vh;
background-size: 90.8vw 84vw;
transition: transform 0.6s ease-in-out;
}
.play-page .play-area .piece.active {
border: 3px solid red;
}
.play-page .play-area .piece-0 {
background-position: 0 0;
}
.play-page .play-area .piece-1 {
// background-position: -28vw 0;
background-position: -30.2667vw 0;
}
.play-page .play-area .piece-2 {
background-position: -60.5333vw 0;
}
.play-page .play-area .piece-3 {
// margin-top: -8.8vw;
background-position: 0 -28vw;
}
.play-page .play-area .piece-4 {
// margin-top: -8.8vw;
background-position: -30.2667vw -28vw;
}
.play-page .play-area .piece-5 {
// margin-top: -8.8vw;
background-position: -60.5333vw -28vw;
}
.play-page .play-area .piece-6 {
// margin-top: -17.6vw;
background-position: 0 -56vw;
}
.play-page .play-area .piece-7 {
// margin-top: -17.6vw;
background-position: -30.2667vw -56vw;
}
.play-page .play-area .piece-8 {
// margin-top: -17.6vw;
background-position: -60.5333vw -56vw;
// background-position: -56vw -40vh;
}
.result-page {
padding-left: 20px;
padding-right: 20px;
background-color: #2b2929;
}
.result-page .success-text {
padding-top: 160px;
padding-bottom: 20px;
font-size: 36px;
color: #e4d721;
font-weight: 700;
}
.result-page .total-time {
display: block;
margin-bottom: 30px;
color: #fff;
font-size: 24px;
}
.last-page {
position: relative;
}
.last-page img {
position: absolute;
left: 0;
top: 0;
}
.play-again {
position: absolute;
bottom: 10px;
left: 5px;
z-index: 10;
width: 48%;
}
.share-other {
position: absolute;
bottom: 10px;
right: 5px;
z-index: 10;
width: 48%;
}
.share-bg {
position: fixed;
top: 0;
width: 0;
width: 100%;
height: 100%;
// background: url('../assets/images/share.png') no-repeat rgba(0, 0, 0, 0.8);
background-position: top right;
z-index: 11;
/* background-size:75%; */
}
}
}
}
.cover {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 100;
background: rgba(0, 0, 0, 0.8);
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
// margin-top: 60.2667vw;
width: 80vw;
height: 116vw;
border-radius: 4vw;
background-color: #cee7fd;
.divider1 {
border-bottom: 1px solid #b3b3b3;
margin: 4.4vw 0;
width: 62.4vw;
}
.divider2 {
border-bottom: 1px solid #b3b3b3;
margin: 4.4vw 0;
width: 62.4vw;
}
.vertical-divider {
float: left;
width: 0.1333vw;
height: 100%;
background-color: #b3b3b3;
margin: 0 1vw;
}
.el-dialog__header {
width: 100vw;
padding: 3.7333vw 15.0667vw 0 38.9333vw;
.title {
color: #fa3e56;
font-size: 6.1333vw;
font-weight: 700;
}
.cancel {
width: 6.9333vw;
height: 6.9333vw;
position: absolute;
top: -14.6667vw;
right: -3.4667vw;
}
.icon {
width: 51.7333vw;
height: 46.9333vw;
position: absolute;
top: -29.2vw;
left: -10vw;
}
}
.el-dialog__body {
padding: 9.4667vw 2.6667vw 0;
.content {
border-radius: 5vw;
height: 75vw;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
.tip {
margin-top: 3.3333vw;
color: #999999;
font-size: 3.4667vw;
}
.the_Best {
display: flex;
.BestGrade {
display: flex;
flex-direction: column;
align-items: center;
.text {
font-family: AlibabaPuHuiTi-Regular;
color: #333333;
font-size: 4vw;
margin-bottom: 4vw;
}
.count {
color: #5280c1;
font-size: 4vw;
font-weight: 800;
}
}
}
button {
background-color: #5280c1;
font-size: 4.2667vw;
color: #fff;
width: 53.3333vw;
height: 10.6667vw;
border-radius: 10vw;
border: 1vw solid #5280c1;
}
.chance_box {
margin-top: 2vw;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.morechance {
font-size: 3.4667vw;
color: #999999;
}
.divider {
border-bottom: 1px solid #b3b3b3;
margin-top: 1vw;
}
}
}
}
.dialog-footer {
margin-top: 4.6667vw;
.return,
.charts {
margin-left: 8.8vw;
width: 28.5333vw;
height: 10.6667vw;
border-radius: 5vw;
font-size: 4.2667vw;
background-color: #cee7fd;
color: #5280c1;
border: 0.5vw solid #5280c1;
}
}
}
}
}
</style>
老虎机
官网
老虎机这个游戏用的是插件,这个没啥好说的,看官网文档
<template>
<div class="draw-box">
<div v-if="phone" class="login">
{{ phone }}
</div>
<div v-if="!miniProgramParam && phone" class="login_out" @click="phoneUnLogin">退出</div>
<div v-if="!miniProgramParam && !phone" class="login_out" @click="toLogin">登录</div>
<div class="title">
<img src="@/assets/image/draw/slot-machine/title.png" alt="" />
</div>
<div class="wheel">
<slot-machine
ref="SlotMachine"
class="slot-machine"
width="66.66vw"
height="34.66vw"
:prizes="prizes"
:defaultConfig="defaultConfig"
:blocks="blocks"
:slots="slots"
@end="endCallBack"
/>
<img class="wheel-point" src="@/assets/image/draw/slot-machine/machine_bg.png" />
</div>
<div class="prize_box" @click="toRecord">
<span class="myprize_text">我的奖品 ></span>
</div>
<div class="count_box">
<span class="count_text">剩余次数:{{ count }}</span>
</div>
<div class="lottery_box">
<span class="lottery_user">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(item, index) in winningSwiperList" :key="index">
<div class="text">{{ item.phone }}获得{{ item.activityPrizesName }}</div>
</div>
</div>
</div>
</span>
</div>
<div class="lottery_btn_box" @click="startCallBack">
<span class="lottery_btn">抽奖</span>
</div>
<div class="left-position-btn">
<div class="rule-btn" @click="openRule">
<span>规则</span>
</div>
<div class="customer-btn" @click="openCustomer">
<span>客服</span>
</div>
</div>
<div class="link-btn">
<div
v-if="phone && dataForm.isLink === '1' && count === 0"
class="link-name"
@click="jumpLink"
>
{{ dataForm.linkButtonName }}
</div>
</div>
<fillIn-address
:visible.sync="fillInVisible"
:lotteryId="lotteryId"
:prizeId="activePrizeId"
:prizeName="activePrizeName"
:orderId="activeOrderId"
:loginPhone="loginPhone"
:isRefresh="true"
></fillIn-address>
<prize-winning
:visible.sync="winningVisible"
:activePrizeName="activePrizeName"
:activePrizeIcon="activePrizeIcon"
:activePrizeType="activePrizeType"
:activePrizeTip="activePrizeTip"
@open-fillIn="openFillIn"
></prize-winning>
<prize-winning-error
:visible.sync="winningErrorVisible"
:winningErrorMsg="winningErrorMsg"
></prize-winning-error>
<customer-dialog
:visible.sync="customerVisible"
:servicePhone="dataForm.servicePhone"
:codeUrl="dataForm.qrCodeUrl"
></customer-dialog>
<rule-dialog :visible.sync="ruleVisible" :ruleContent="ruleContent"></rule-dialog>
</div>
</template>
<script>
import loginHandle from '@/mixin/loginHandle'
import LuckySlotMachineIndex from './mixin/index'
import Swiper from 'swiper'
import { listPrizeSample } from '@/api/draw/index.js'
import { SlotMachine } from '@lucky-canvas/vue'
const fillInAddress = () => import('@/components/Address/fillIn.vue')
const prizeWinning = () => import('./components/winning.vue')
const prizeWinningError = () => import('./components/winning-error.vue')
const customerDialog = () => import('@/components/activityCustomerDialog/index.vue')
const ruleDialog = () => import('@/components/activityRuleDialog/index.vue')
export default {
mixins: [loginHandle, LuckySlotMachineIndex],
components: {
'slot-machine': SlotMachine,
'fillIn-address': fillInAddress,
'prize-winning': prizeWinning,
'prize-winning-error': prizeWinningError,
'customer-dialog': customerDialog,
'rule-dialog': ruleDialog
},
data() {
return {
lotteryId: '', // 抽奖id
phone: '',
commonSign: '', // 如果在初始化有值代表测试链接
time: '',
blocks: [{ padding: '2.6667vw' }, { padding: '2.6667vw' }],
slots: [],
prizes: [],
defaultStyle: {
borderRadius: Infinity
},
defaultConfig: {
rowSpacing: '20px',
colSpacing: '20px'
},
winningSwiperList: []
}
},
created() {
this.listPrizeSample()
},
methods: {
toLogin() {
this.loginDetermineHandle(this.geLoginQuery())
},
geLoginQuery() {
return {
path: '/SlotMachine1',
id: this.lotteryId,
commonSign: this.commonSign,
time: this.time
}
},
luckySlotMachineHandle() {
let prizes = []
let arr = this.dataForm.prizes
let length = this.dataForm.prizes.length
let prizesList = Array.from({ length }, (_, index) => index)
let order1 = Array.from({ length }, (_, index) => index)
let order2 = Array.from({ length }, (_, index) => index)
order1.push(order1.shift())
order2.unshift(order2.pop())
if (arr.length <= 1) {
arr.forEach((item, index) => {
prizes.push(
{
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
},
{
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
},
{
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
}
)
})
} else if (arr.length === 2) {
arr.forEach((item, index) => {
prizes.push(
{
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
},
{
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
}
)
})
} else {
arr.forEach((item, index) => {
prizes.push({
imgs: [
{
src: this.$http + item.uri,
width: '95%',
height: '100%'
}
]
})
})
}
this.slots = [{ order: prizesList }, { order: order1 }, { order: order2 }]
this.prizes = prizes
},
async listPrizeSample() {
const res = await listPrizeSample({ id: this.lotteryId })
if (res.data.code == 200) {
this.winningSwiperList = res.data.data
this.getSwiper()
}
},
getSwiper() {
let swiperObj = {
direction: 'vertical',
loop: true,
autoplay: true,
observer: true,
observeParents: true,
pagination: {
el: '.swiper-pagination'
}
}
let timer = setTimeout(() => {
clearTimeout(timer)
new Swiper('.swiper-container', swiperObj)
}, 500)
}
}
}
</script>
<style lang="less" scoped>
.draw-box {
position: relative;
width: 100vw;
min-height: 100vh;
background-color: #d1f8a0;
background-image: url(~@/assets/image/draw/slot-machine/bg.png);
background-size: 100%;
background-repeat: no-repeat;
padding: 3.2vw 0 13.3333vw;
// background-size: cover;
.swiper-container {
position: relative;
z-index: 12;
width: 100%;
height: 6vw;
overflow: hidden;
.swiper-wrapper {
height: 100%;
.swiper-slide {
width: 61.0667vw !important;
margin: 0 2.6667vw;
.text {
height: 6vw;
line-height: 6vw;
padding: 0 1.6vw;
border-radius: 3.0667vw;
font-size: 3.2vw;
text-align: center;
font-weight: 500;
color: #ecf1ed;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
}
.link-btn {
display: flex;
justify-content: center;
align-items: center;
margin-top: 8vw;
.link-name {
font-size: 4vw;
color: #fff;
border: 1px solid #fff;
border-radius: 4vw;
padding: 1vw 2vw;
cursor: pointer;
}
}
.myprize {
position: absolute;
top: 15.5333vw;
right: 3vw;
z-index: 10;
width: 13vw;
height: 13vw;
background-color: rgb(255, 255, 255);
border-radius: 7vw;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
border: 0.5vw solid #ff071e;
img {
width: 10vw;
height: 10vw;
margin-top: 2vw;
}
}
.prize_box {
position: absolute;
top: 153.5vw;
z-index: 10;
left: 39vw;
.myprize_text {
z-index: 10;
font-size: 4vw;
color: #fff;
text-shadow: #ff3428 1px 0 0, #ff3428 0 1px 0, #ff3428 -1px 0 0, #ff3428 0 -1px 0;
}
}
.count_box {
position: absolute;
top: 120vw;
z-index: 10;
left: 37vw;
.count_text {
z-index: 10;
font-size: 4vw;
color: #fff;
// text-shadow: #ff3428 1px 0 0, #ff3428 0 1px 0, #ff3428 -1px 0 0, #ff3428 0 -1px 0;
}
}
.lottery_box {
position: absolute;
top: 52vw;
z-index: 10;
left: 16vw;
.lottery_user {
font-size: 4vw;
color: #fff;
// text-shadow: #ff3428 1px 0 0, #ff3428 0 1px 0, #ff3428 -1px 0 0, #ff3428 0 -1px 0;
}
}
.lottery_btn_box {
background-color: #fee532;
width: 47vw;
height: 19vw;
position: absolute;
top: 129vw;
z-index: 10;
left: 24vw;
border-radius: 4vw;
text-align: center;
line-height: 20vw;
.lottery_btn {
font-size: 8vw;
color: red;
font-weight: bold;
}
}
.login {
position: absolute;
top: 2vw;
left: 3vw;
color: #fff;
font-size: 4vw;
z-index: 10;
}
.draw-prize {
position: relative;
z-index: 12;
margin: 3.2vw auto 4.9333vw;
text-align: center;
font-size: 4.8vw;
font-weight: 800;
color: #6617f8;
}
.wheel {
position: relative;
margin-top: -6.6667vw;
z-index: 9;
width: 100vw;
height: 181.3333vw;
.slot-machine {
position: absolute;
top: 75.2667vw;
left: 14.2vw;
z-index: 10;
}
.more-chance {
position: absolute;
font-size: 6vw;
font-weight: 500;
bottom: -11vw;
right: 19vw;
.btn_bg {
width: 66vw;
height: 25vw;
}
a {
position: absolute;
top: 8vw;
right: 15vw;
color: #f7462e;
}
}
.wheel-point {
position: absolute;
top: 32vw;
left: -2vw;
z-index: 9;
width: 100%;
height: 80%;
}
.wheel-point1 {
position: absolute;
right: 9vw;
bottom: 13vw;
z-index: 9;
}
}
.title {
position: absolute;
top: 10vw;
right: 10vw;
}
.login_out {
width: 14vw;
height: 6vw;
position: absolute;
top: 2vw;
right: 3vw;
color: #36388c;
font-size: 4vw;
text-decoration: none;
border-radius: 2.9333vw;
background-color: #fff;
border: #fff;
text-align: center;
z-index: 10;
line-height: 6vw;
}
.left-position-btn {
position: absolute;
top: 32.5333vw;
right: 0;
z-index: 10;
.prize-btn,
.customer-btn,
.rule-btn {
margin-bottom: 2.5333vw;
width: 6.0667vw;
height: 12.8667vw;
padding: 1.2vw;
background-color: #fb692f;
border-radius: 0.9333vw 0 0 0.9333vw;
font-size: 3.4667vw;
font-weight: 400;
color: #fff;
text-align: center;
line-height: 4.8667vw;
}
}
}
</style>
介绍到这里了,有问题私聊鄙人