223 lines
5.9 KiB
Vue
223 lines
5.9 KiB
Vue
<template>
|
|
<page-container title="Canvas抽奖特效演示" :showBack="true">
|
|
<view class="demo-container">
|
|
<view class="prize-wheel-wrapper">
|
|
<canvas-prize-wheel
|
|
ref="canvasPrizeWheel"
|
|
:prizes="prizes"
|
|
:duration="4"
|
|
:itemWidth="itemWidth"
|
|
:itemHeight="itemHeight"
|
|
:backgroundColor="'rgba(255, 255, 255, 0.9)'"
|
|
:highlightColor="'rgba(255, 215, 0, 0.5)'"
|
|
:highlightShadow="'rgba(255, 215, 0, 0.8)'"
|
|
:borderRadius="8"
|
|
@spin-start="onSpinStart"
|
|
@spin-end="onSpinEnd">
|
|
</canvas-prize-wheel>
|
|
</view>
|
|
|
|
<view class="control-panel">
|
|
<button class="start-btn" @click="startLottery" :disabled="isSpinning">开始抽奖</button>
|
|
|
|
<view class="result-display" v-if="prizeResult">
|
|
<text class="result-label">抽奖结果:</text>
|
|
<text class="result-value" :style="{ color: prizeResult.color }">{{prizeResult.value}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</page-container>
|
|
</template>
|
|
|
|
<script>
|
|
import CanvasPrizeWheel from '@/components/canvas-prize-wheel/canvas-prize-wheel.vue'
|
|
|
|
export default {
|
|
components: {
|
|
CanvasPrizeWheel
|
|
},
|
|
data() {
|
|
return {
|
|
// 奖品列表 - 使用简短名称更好显示
|
|
prizes: [
|
|
{ id: 1, value: '一等奖', color: '#ff0000', bgColor: 'rgba(255,0,0,0.1)' },
|
|
{ id: 2, value: '二等奖', color: '#00ff00', bgColor: 'rgba(0,255,0,0.1)' },
|
|
{ id: 3, value: '三等奖', color: '#0000ff', bgColor: 'rgba(0,0,255,0.1)' },
|
|
{ id: 4, value: '四等奖', color: '#ffff00', bgColor: 'rgba(255,255,0,0.1)' },
|
|
{ id: 5, value: '五等奖', color: '#ff00ff', bgColor: 'rgba(255,0,255,0.1)' },
|
|
{ id: 6, value: '六等奖', color: '#00ffff', bgColor: 'rgba(0,255,255,0.1)' },
|
|
{ id: 7, value: '谢谢', color: '#ff8800', bgColor: 'rgba(255,136,0,0.1)' }
|
|
],
|
|
isSpinning: false,
|
|
prizeResult: null,
|
|
itemWidth: uni.upx2px(150),
|
|
itemHeight: uni.upx2px(120)
|
|
}
|
|
},
|
|
mounted() {
|
|
// 确保界面加载后Canvas正确初始化
|
|
this.$nextTick(() => {
|
|
setTimeout(() => {
|
|
if (this.$refs.canvasPrizeWheel) {
|
|
this.$refs.canvasPrizeWheel.render()
|
|
}
|
|
}, 500)
|
|
})
|
|
},
|
|
methods: {
|
|
// 开始抽奖
|
|
startLottery() {
|
|
if (this.isSpinning) return
|
|
|
|
this.isSpinning = true
|
|
this.prizeResult = null
|
|
|
|
// 启动抽奖动画
|
|
this.$refs.canvasPrizeWheel.startSpin()
|
|
|
|
// 模拟异步获取抽奖结果
|
|
// 实际应用中应该调用后端API获取结果
|
|
setTimeout(() => {
|
|
// 随机选择一个奖品
|
|
const randomIndex = Math.floor(Math.random() * this.prizes.length)
|
|
const result = this.prizes[randomIndex]
|
|
|
|
// 设置最终奖品并开始减速
|
|
this.$refs.canvasPrizeWheel.setPrize(result)
|
|
}, 2000) // 2秒后获取结果
|
|
},
|
|
|
|
// 抽奖开始回调
|
|
onSpinStart() {
|
|
console.log('抽奖开始')
|
|
// 播放背景音乐或其他操作
|
|
uni.showToast({
|
|
title: '抽奖开始',
|
|
icon: 'none'
|
|
})
|
|
},
|
|
|
|
// 抽奖结束回调
|
|
onSpinEnd(prize) {
|
|
console.log('抽奖结束', prize)
|
|
this.isSpinning = false
|
|
this.prizeResult = prize
|
|
|
|
// 显示结果
|
|
uni.showToast({
|
|
title: `恭喜获得: ${prize.value}`,
|
|
icon: 'success',
|
|
duration: 2000
|
|
})
|
|
|
|
// 可以在这里添加截图分享功能
|
|
// this.saveAndShareResult()
|
|
},
|
|
|
|
// 保存并分享抽奖结果
|
|
async saveAndShareResult() {
|
|
try {
|
|
// 导出Canvas为图片
|
|
const imagePath = await this.$refs.canvasPrizeWheel.exportImage()
|
|
|
|
// 保存图片到相册
|
|
uni.saveImageToPhotosAlbum({
|
|
filePath: imagePath,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: '已保存到相册',
|
|
icon: 'success'
|
|
})
|
|
},
|
|
fail: (err) => {
|
|
console.error('保存图片失败', err)
|
|
}
|
|
})
|
|
} catch (error) {
|
|
console.error('导出图片失败', error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.demo-container {
|
|
width: 100%;
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
box-sizing: border-box;
|
|
background-image: url($imgurl + 'common/slot_bg.webp');
|
|
background-size: cover;
|
|
background-position: center;
|
|
|
|
.prize-wheel-wrapper {
|
|
width: 100%;
|
|
padding: 0;
|
|
height: 120rpx;
|
|
background-image: url($imgurl + 'common/slot1.png');
|
|
background-size: cover;
|
|
background-position: center;
|
|
position: relative;
|
|
margin: 40rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.control-panel {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 20rpx;
|
|
|
|
.start-btn {
|
|
width: 300rpx;
|
|
height: 90rpx;
|
|
background: linear-gradient(to right, #ff5a5f, #ff8a5f);
|
|
color: white;
|
|
border-radius: 45rpx;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
font-size: 32rpx;
|
|
margin-bottom: 30rpx;
|
|
box-shadow: 0 4rpx 10rpx rgba(255, 90, 95, 0.3);
|
|
|
|
&:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
&[disabled] {
|
|
background: #cccccc;
|
|
color: #888888;
|
|
}
|
|
}
|
|
|
|
.result-display {
|
|
margin-top: 20rpx;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
padding: 20rpx 40rpx;
|
|
border-radius: 10rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
.result-label {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.result-value {
|
|
font-size: 40rpx;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |