增加新的抽奖页面

This commit is contained in:
YeMingfei666 2024-12-20 09:45:54 +08:00
parent 168665eebc
commit 908205200b
19 changed files with 728 additions and 0 deletions

View File

@ -0,0 +1,108 @@
<template>
<view class="content">
<u-navbar title="抽奖" back-icon-color="#fff" :background="{background:'transparent'}" immersive :border-bottom="false"
title-color="#fff"></u-navbar>
<view class="sm">
<HM-slotMachine ref="HMslotMachine"></HM-slotMachine>
</view>
<view class="start" @tap="start">
<text> </text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
prizeList:[
{name:'iPhone13',value:'iPhone',img:require('@/other/static/1.png')},
{name:'airPods3',value:'airPods',img:require('@/other/static/2.png')},
{name:'行李箱',value:'luggage',img:require('@/other/static/3.png')},
{name:'风筒',value:'dryer',img:require('@/other/static/4.png')},
{name:'平行车',value:'balanceCar',img:require('@/other/static/5.png')},
{name:'iPad5',value:'iPad',img:require('@/other/static/6.png')}
]
}
},
onLoad() {
},
onReady() {
// init(options)
// options
// prizeList
// defaultResults
// duration
// direction up|down
this.$refs.HMslotMachine.init({
prizeList:this.prizeList,
defaultResults:['iPhone','iPhone','iPhone'],
duration:4000,
direction:'up'
})
},
methods: {
start(){
// roll(options)
//
// results [value,value,value] valuevalue
// success e={results} results
this.$refs.HMslotMachine.roll({
results:this.getResults(),
success:(e)=>{
console.log("success e: ",e);
}
})
},
getResults(){
// ajax
let max = this.prizeList.length-1;
let arr = [Math.floor(Math.random() * (max - 1 + 1) + 1),Math.floor(Math.random() * (max - 1 + 1) + 1),Math.floor(Math.random() * (max - 1 + 1) + 1)];
return [
this.prizeList[arr[0]].value,
this.prizeList[arr[1]].value,
this.prizeList[arr[2]].value
]
}
}
}
</script>
<style lang="scss">
page{
background-image: linear-gradient(to top,#8F1E70, #51279A);
min-height: calc(100vh - var(--window-bottom) - var(--window-top));
}
.content {
display: flex;
flex-direction: column;
align-items: center;
.sm{
margin-top: 200rpx;
}
.start{
width: 70%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #f29c11;
border-radius: 40rpx;
margin-top: 30rpx;
box-shadow: 0 1px 2px rgba($color: #51279A, $alpha: 1);
border-bottom: solid 3px #8d5805;
box-sizing: border-box;
text{
font-size: 20px;
font-weight: bold;
color: #b51c06;
text-shadow: 1px 1px 1px #f2e811;
}
}
}
</style>

BIN
other/static/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
other/static/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
other/static/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
other/static/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
other/static/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
other/static/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -715,6 +715,15 @@
{
"navigationBarTitleText" : "发红包"
}
},
{
"path" : "slotMachine/slotMachine",
"style" :
{
"navigationBarTitleText" : "抽奖",
"navigationStyle": "custom"
}
}
]

View File

@ -0,0 +1,9 @@
## 1.0.32022-04-28
修复图片不显示,小灯切换的问题
## 1.0.22022-01-29
* 兼容微信小程序
* 新增初始话参数,可以设置初始化显示的奖品
## 1.0.12022-01-19
* 稍微兼容一下vue3和PC网页...?
## 1.0.02022-01-19
初次发布

View File

@ -0,0 +1,386 @@
<template>
<view class="shell">
<view class="l">
<!-- 小灯列表 -->
<view class="lamp" v-for="(item,index) in lamps" :key="item.color" :style="{'background-color': item.color,'box-shadow': '0 0 5px '+item.color}"></view>
</view>
<view class="c">
<view class="HMSM">
<!-- 背景 -->
<view class="HMSM-display-bg">
<view v-for="(shaft,index) in shaftList" :key="index" class="box"></view>
</view>
<!-- 奖品列表 -->
<view class="HMSM-display">
<view v-for="(shaft,index) in shaftList" :key="index" class="HMSM-shaft"
:style="{transform: 'translate3d(0, '+translateY[index]+'%, 0)','transition-duration':duration+'ms'}"
:class="{'roll_animation':(rollState=='start')}">
<view v-for="(item,shaftIndex) in shaft" :key="item.HMSM_id">
<image :src="item.img"></image>
</view>
</view>
</view>
</view>
</view>
<view class="r">
<!-- 小灯列表 -->
<view class="lamp" v-for="(item,index) in lamps" :key="item.color" :style="{'background-color': item.color,'box-shadow': '0 0 5px '+item.color}"></view>
</view>
</view>
</template>
<script>
//
// translateY
// 线
export default {
name: 'HM-slotMachine',
data() {
return {
// /
delay:0,
//
duration: 0,
// up down
direction: 'up',
//
rollState: 'stop',
//
prizeList: [],
//
translateY: [0, 0, 0],
//
shaftList: [],
//
lampTimer:false,
//
lamps:[
{color:'#97eefb'},
{color:'#fecc6a'},
{color:'#fb7c84'},
{color:'#a097ff'},
{color:'#fd0100'}
]
}
},
// #ifdef VUE3
emits: ['init','roll'],
// #endif
methods: {
//
init({
//
prizeList,
//
defaultResults=[],
// 500ms
delay = 500,
// 4000ms
duration = 4000,
//
direction = 'up'
}) {
//
if(typeof delay !=='number'){
console.warn('delay参数应该传入整型');
delay = parseInt(delay)
delay = isNaN(delay)?500:delay;
}
if(typeof duration !=='number'){
console.warn('duration参数应该传入整型');
duration = parseInt(duration)
duration = isNaN(duration)?4000:duration;
}
if(typeof prizeList !=='object'){
return console.error('prizeList参数应该传入数组对象');
}
if(typeof defaultResults !=='object'){
return console.error('defaultResults参数应该传入数组');
}
if(direction !='up' && direction !='down'){
return console.error('direction参数应该传入"up"或者"down"');
}
//
this.direction = direction;
// 4
if (duration < 4000) {
duration = 4000
};
//
duration = duration - (delay*2);
this.prizeList = prizeList;
let shaftList = [];
shaftList.length = 3;
for (let i = 0; i < 3; i++) {
//
shaftList[i] = this.shuffle(prizeList);
for (let j = 0, len = shaftList[i].length; j < len; j++) {
shaftList[i][j].HMSM_id = 'id_'+i+'_'+j;
}
}
this.shaftList = shaftList;
if(defaultResults.length==3){
this.setTranslateY(defaultResults);
setTimeout(()=>{
this.stop();
},50)
}{
if(this.direction == 'down'){
//
let topY = (this.shaftList[1].length-1)*-100;
this.translateY.splice(0,3,topY,topY,topY);
}
}
this.$nextTick(function(){
this.duration = duration;
this.delay = delay;
})
},
//
roll({
//
results = null,
//
success = null
}) {
if(this.rollState == 'start'){
return console.warn('正在抽奖哦!');
}
if (typeof results != 'object') {
return console.error('请传入正确的开奖结果参数results');
}
this.rollState = 'start';
//
let res = this.setTranslateY(results);
this.lampTimer&&clearInterval(this.lampTimer);
//
this.startSwitchLamp();
setTimeout(() => {
typeof success == "function" && success(res);
this.stop();
}, this.duration + 1000);
},
//
setTranslateY(results){
let res = {
results: []
}
console.log("results: ",results);
for (let i = 0, len = results.length; i < len; i++) {
if(this.direction == 'up'){
//
for (let k = this.shaftList[i].length - 1; k >= 0; k--) {
if (this.shaftList[i][k].value == results[i]) {
res.results.push(JSON.parse(JSON.stringify(this.shaftList[i][k])));
//
setTimeout(() => {
this.translateY.splice(i,1,k * -100)
}, i * this.delay)
break;
}
}
}else{
//
for (let k = 0,len = this.shaftList[i].length; k < len; k++) {
if (this.shaftList[i][k].value == results[i]) {
res.results.push(JSON.parse(JSON.stringify(this.shaftList[i][k])));
//
setTimeout(() => {
this.translateY.splice(i,1,k * -100);
}, i * this.delay)
break;
}
}
}
}
return res;
},
//
stop() {
this.rollState = 'stop';
this.lampTimer&&clearInterval(this.lampTimer);
this.$nextTick(function(){
let tolerance = (this.shaftList[0].length/this.prizeList.length-1)*this.prizeList.length*100; //
tolerance = this.direction == 'up'&&tolerance||-tolerance
// /
for(let i=0,len=this.translateY.length;i<len;i++){
let topY = this.translateY[i] + tolerance;
this.translateY.splice(i,1,topY)
}
})
},
//
startSwitchLamp(){
this.lampTimer = setInterval(()=>{
if(this.rollState != 'stop'){
// #ifndef APP-PLUS
if(this.direction == 'up'){
this.lamps.push(this.lamps.shift())
}else{
this.lamps.unshift(this.lamps.pop())
}
// #endif
// #ifdef APP-PLUS
if(this.direction == 'up'){
const tmp = this.lamps[0];
[this.lamps[0],this.lamps[1],this.lamps[2],this.lamps[3]] = [this.lamps[1],this.lamps[2],this.lamps[3],this.lamps[4]];
this.$nextTick(function(){
this.lamps[4] = tmp;
})
}else{
const tmp = this.lamps[4];
[this.lamps[1],this.lamps[2],this.lamps[3],this.lamps[4]] = [this.lamps[0],this.lamps[1],this.lamps[2],this.lamps[3]];
this.$nextTick(function(){
this.lamps[0] = tmp;
})
}
// #endif
}
},50)
},
//
shuffle(arr) {
let tmpArr = JSON.parse(JSON.stringify(arr))
for (let i = 1; i < tmpArr.length; i++) {
const random = Math.floor(Math.random() * (i + 1));
[tmpArr[i], tmpArr[random]] = [tmpArr[random], tmpArr[i]];
}
// 40
// 40
let len = Math.ceil(40/arr.length); //
let tmpShaft = [];
while (len>0){
tmpShaft.push(...tmpArr);
len--;
}
return JSON.parse(JSON.stringify(tmpShaft));
}
}
}
</script>
<style lang="scss" scoped>
.shell{
width: 630rpx;
height: 352rpx;
background-image: linear-gradient(to right,#6543BC, #754EAE);
border-radius: 50rpx;
display: flex;
align-items: center;
.l,.r{
width: 36rpx;
height: 260rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
.lamp{
width: 14rpx;
height: 14rpx;
// box-shadow: 0 0 2px rgba($color: #000000, $alpha: 0.5);
border-radius: 50%;
}
}
.l{
padding-left: 10rpx;
}
.r{
padding-right: 10rpx;
}
.c{
width: 540rpx;
height: 270rpx;
background-color: #8461E9;
border: solid 1rpx #6443B6;
// box-shadow: 0 0 2px rgba($color: #000000, $alpha: 0.2);
border-radius: 30rpx;
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
.HMSM {
width: 510rpx;
height: 240rpx;
position: relative;
.HMSM-display-bg{
width: 100%;
height: 240rpx;
position: absolute;
left: 0;
top: 0;
z-index: 2;
display: flex;
flex-direction: row;
justify-content: space-between;
.box{
width: 160rpx;
height: 240rpx;
// background-color: #fff;
background-image: linear-gradient(to top,#E4DEFC, rgba(255,255,255,0));
box-shadow: 0 0 2px rgba($color: #fff, $alpha: 1);
border: solid 1px #9d82ea;
box-sizing: border-box;
&:first-child{
border-radius: 20rpx 0 0 20rpx;
}
&:last-child{
border-radius: 0 20rpx 20rpx 0;
}
}
}
.HMSM-display {
position: absolute;
left: 0;
top: 0;
z-index: 3;
width: 100%;
height: 240rpx;
overflow: hidden;
display: flex;
flex-direction: row;
justify-content: space-between;
border-radius: 20rpx;
.HMSM-shaft {
width: 160rpx;
transition-property:none;
transition-duration:0s;
&.roll_animation {
transition-property: transform;
transition-timing-function: cubic-bezier(0.5, 0, 0.1, 1);
}
>view {
width: 160rpx;
height: 240rpx;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-color: #fff;
image{
width: 160rpx;
height: 240rpx;
}
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,82 @@
{
"id": "HM-slotMachine",
"displayName": "HM-slotMachine 老虎机抽奖模板",
"version": "1.0.3",
"description": "一个老虎机抽奖模板,实现了抽奖的动画交互",
"keywords": [
"抽奖",
"老虎机",
"滚动抽奖"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"uni-app前端模板",
"vue 页面模板"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "u",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "u",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@ -0,0 +1,105 @@
<template>
<view class="content">
<view class="sm">
<HM-slotMachine ref="HMslotMachine"></HM-slotMachine>
</view>
<view class="start" @tap="start">
<text> </text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
prizeList:[
{name:'iPhone13',value:'iPhone',img:'/uni_modules/HM-slotMachine/static/1.png'},
{name:'airPods3',value:'airPods',img:'/uni_modules/HM-slotMachine/static/2.png'},
{name:'行李箱',value:'luggage',img:'/uni_modules/HM-slotMachine/static/3.png'},
{name:'风筒',value:'dryer',img:'/uni_modules/HM-slotMachine/static/4.png'},
{name:'平行车',value:'balanceCar',img:'/uni_modules/HM-slotMachine/static/5.png'},
{name:'iPad5',value:'iPad',img:'/uni_modules/HM-slotMachine/static/6.png'}
]
}
},
onLoad() {
},
onReady() {
// init(options)
// options
// prizeList
// defaultResults
// duration
// direction up|down
this.$refs.HMslotMachine.init({
prizeList:this.prizeList,
defaultResults:['iPhone','iPhone','iPhone'],
duration:4000,
direction:'up'
})
},
methods: {
start(){
// roll(options)
//
// results [value,value,value] valuevalue
// success e={results} results
this.$refs.HMslotMachine.roll({
results:this.getResults(),
success:(e)=>{
console.log("success e: ",e);
}
})
},
getResults(){
// ajax
let max = this.prizeList.length-1;
let arr = [Math.floor(Math.random() * (max - 1 + 1) + 1),Math.floor(Math.random() * (max - 1 + 1) + 1),Math.floor(Math.random() * (max - 1 + 1) + 1)];
return [
this.prizeList[arr[0]].value,
this.prizeList[arr[1]].value,
this.prizeList[arr[2]].value
]
}
}
}
</script>
<style lang="scss">
page{
background-image: linear-gradient(to top,#8F1E70, #51279A);
min-height: calc(100vh - var(--window-bottom) - var(--window-top));
}
.content {
display: flex;
flex-direction: column;
align-items: center;
.sm{
margin-top: 200rpx;
}
.start{
width: 70%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #f29c11;
border-radius: 40rpx;
margin-top: 30rpx;
box-shadow: 0 1px 2px rgba($color: #51279A, $alpha: 1);
border-bottom: solid 3px #8d5805;
box-sizing: border-box;
text{
font-size: 20px;
font-weight: bold;
color: #b51c06;
text-shadow: 1px 1px 1px #f2e811;
}
}
}
</style>

View File

@ -0,0 +1,29 @@
> * 遇到问题或有建议可以[加入QQ群(147157269)](https://jq.qq.com/?_wv=1027&k=jpdVnqxw)反馈
> * 如果觉得组件不错,<a id="praise"><font color=#f00>点我给个五星鼓励鼓励</font></a>咯!
<img id="spring" src="https://hmsmscode.hmwh.me/SMqrcode.png" width="227" height="227" onload="td=document;td.getElementById('praise').addEventListener('click', function(e){rating()});td.getElementById('praise').removeAttribute('id');td.getElementById('spring').removeAttribute('onload');td.getElementById('spring').removeAttribute('id');" />
安卓扫码下载apk体验
iOS想体验就乖乖下载示例运行咯
##模板说明
> * 老虎机抽奖页面模板,里面有一个页面(lottery-draw.vue)和一个组件(HM-slotMachine.vue)
> * 前端只有抽奖的交互动画,没有做抽奖逻辑(应该没有人敢把抽奖逻辑放前端吧?),开奖结果需要后台给
> * <font color=#f00>详细的说明,都以注释方式写在了代码里面,请下载示例或者模板查看</font>
##使用方法
直接下载示例或者导入组件
> * 遇到问题或有建议可以[加入QQ群(147157269)](https://jq.qq.com/?_wv=1027&k=jpdVnqxw)反馈
> * 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯!
####偷偷的打广告
定制模板开发uniapp、H5+APP、wap2app、PHP付费咨询指导有需要加QQ。
<table><tr><td bgcolor=#8f9396 >
<center><font color=#8f9396>QQ:565766672</font> <font color=#fff>(刮刮卡)</font></center>
</td></tr></table>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB