|
@@ -0,0 +1,397 @@
|
|
|
+<template>
|
|
|
+ <uni-popup ref="turntablePopup" type="center" :is-mask-click="false">
|
|
|
+ <view class="turntable">
|
|
|
+ <image class="bg" src="https://cos.his.cdwjyyh.com/fs/20250910/9a6263291ec0429ea5828a15b2b490dc.png" mode="aspectFit"></image>
|
|
|
+ <view class="turntable-con">
|
|
|
+ <image class="text" src="https://cos.his.cdwjyyh.com/fs/20250910/fc08b64307a344b4948568fa0f81401e.png" mode="heightFix"></image>
|
|
|
+ <image class="base" src="https://cos.his.cdwjyyh.com/fs/20250910/9385e4a6d5e245dfb86f425f49235589.png" mode="aspectFit"></image>
|
|
|
+ <image class="decoration_img" src="https://cos.his.cdwjyyh.com/fs/20250910/86577ed4fc50420d99b1153e2dd6e1df.png" mode="aspectFit"></image>
|
|
|
+ <view class="ring">
|
|
|
+ <view class="canvas-content" :class="{'infinite-spin': spinning}">
|
|
|
+ <view :animation="animationData" class="canvas-content" id="zhuanpano" style="">
|
|
|
+ <view class="canvas-line">
|
|
|
+ <!-- <canvas canvas-id="sector" style="width:502rpx;height:502rpx" /> -->
|
|
|
+ <view class="canvas-litem" v-for="(item,index) in list" :key="index"
|
|
|
+ :style="{transform:'rotate('+(index * width + width / 2)+'deg)'}"></view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="canvas-list">
|
|
|
+ <view class="canvas-item"
|
|
|
+ :style="{transform: 'rotate('+((index) * width)+'deg)', zIndex:index}"
|
|
|
+ v-for="(iteml,index) in list" :key="index">
|
|
|
+ <view class="canvas-item-text" :style="'transform:rotate('+(index)+')'">
|
|
|
+ <view class="b">{{iteml.name}}</view>
|
|
|
+ <image class="icon-awrad iconfont" :src="iteml.iconUrl" mode="aspectFit">
|
|
|
+ </image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <image class="button" src="https://cos.his.cdwjyyh.com/fs/20250910/d05462c59e7f4ab98e5205b7f8172325.png" mode="aspectFit" @click="playReward">
|
|
|
+ </image>
|
|
|
+ </view>
|
|
|
+ <image class="ring_bg" src="https://cos.his.cdwjyyh.com/fs/20250910/41bea8eda62e484d94a19f18316e509b.png" mode="aspectFit"></image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <image class="close" src="https://cos.his.cdwjyyh.com/fs/20250910/93608bad8ad1479a854ec26e8eaaacea.png" @click="close"></image>
|
|
|
+ </uni-popup>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ getVideoRewardRules
|
|
|
+ } from "@/api/course.js"
|
|
|
+ export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ running: false,
|
|
|
+ spinning: false, // 是否处于无限旋转
|
|
|
+ list: [],
|
|
|
+ width: 0,
|
|
|
+ animationData: {},
|
|
|
+ btnDisabled: '',
|
|
|
+ runDeg: 0,
|
|
|
+ targetIdx: -1,
|
|
|
+ duration: 1000,
|
|
|
+ currentDeg: 0, // 实时角度
|
|
|
+ idleTimer: null,
|
|
|
+ animationRun: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getVideoRewardRules(urlOption) {
|
|
|
+ const param = {
|
|
|
+ type: 3,
|
|
|
+ ...urlOption
|
|
|
+ }
|
|
|
+ getVideoRewardRules(param).then(res => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.list = res.data || []
|
|
|
+ this.width = 360 / this.list.length;
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: res.msg,
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ open(urlOption) {
|
|
|
+ this.animationRun = uni.createAnimation({
|
|
|
+ duration: 0
|
|
|
+ });
|
|
|
+ this.animationRun.rotate(0).step();
|
|
|
+ this.animationData = this.animationRun.export();
|
|
|
+ this.running = false
|
|
|
+ this.spinning = false;
|
|
|
+ clearInterval(this.idleTimer);
|
|
|
+ this.runDeg = 0
|
|
|
+ this.targetIdx = -1
|
|
|
+ this.$refs.turntablePopup.open()
|
|
|
+ this.getVideoRewardRules(urlOption)
|
|
|
+ },
|
|
|
+ close(type) {
|
|
|
+ if (type == 'close') {
|
|
|
+ this.running = false
|
|
|
+ this.spinning = false;
|
|
|
+ clearInterval(this.idleTimer);
|
|
|
+ }
|
|
|
+ if (this.running) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '抽取中,请勿关闭',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$refs.turntablePopup.close()
|
|
|
+ },
|
|
|
+ drawFanWithAlternateColor(id, x, y, r, count) {
|
|
|
+ const ctx = uni.createCanvasContext(id, this);
|
|
|
+ const sweep = 360 / count; // 每份角度
|
|
|
+ let start = -90 - sweep / 2; // 第一个扇形起始角度(deg)
|
|
|
+
|
|
|
+ for (let i = 0; i < count; i++) {
|
|
|
+ const end = start + sweep; // 结束角度
|
|
|
+ let color;
|
|
|
+ color = i % 2 === 0 ? '#FFDFD3' : '#FFF';
|
|
|
+
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(x, y);
|
|
|
+ ctx.arc(
|
|
|
+ x, y, r,
|
|
|
+ (start * Math.PI) / 180,
|
|
|
+ (end * Math.PI) / 180
|
|
|
+ );
|
|
|
+ ctx.closePath();
|
|
|
+ ctx.setFillStyle(color);
|
|
|
+ ctx.fill();
|
|
|
+
|
|
|
+ start = end; // 下一个扇形接着画
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx.draw();
|
|
|
+ },
|
|
|
+ animation(index = null) {
|
|
|
+ //中奖index
|
|
|
+ let list = this.list;
|
|
|
+ let runNum = 1; //旋转8周
|
|
|
+
|
|
|
+ // 旋转角度
|
|
|
+ this.runDeg = this.runDeg || 0;
|
|
|
+ this.runDeg = this.runDeg + (360 - this.runDeg % 360) + (360 * runNum - index * (360 / list.length)) + 1
|
|
|
+
|
|
|
+ // const a = 360 / list.length;
|
|
|
+ // this.runDeg = this.currentDeg + 360 * 4 + (360 - this.currentDeg % 360) - index * a + 1;
|
|
|
+ //创建动画
|
|
|
+ this.animationRun = uni.createAnimation({
|
|
|
+ duration: this.duration,
|
|
|
+ timingFunction: 'ease'
|
|
|
+ })
|
|
|
+ console.log("=====animationRun=", this.animationRun)
|
|
|
+ this.animationRun.rotate(this.runDeg).step();
|
|
|
+ this.animationData = this.animationRun.export();
|
|
|
+ },
|
|
|
+ //发起抽奖
|
|
|
+ playReward() {
|
|
|
+ if (this.running) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '抽取中',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.running = true
|
|
|
+ this.startIdle();
|
|
|
+ this.$emit('sendRewardFun',3)
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this.endSuccess()
|
|
|
+ // }, 2000)
|
|
|
+ },
|
|
|
+ startIdle() {
|
|
|
+ this.spinning = true; // 打开 CSS 动画
|
|
|
+ // 同时用定时器记录角度,方便后面衔接
|
|
|
+ this.idleTimer = setInterval(() => {
|
|
|
+ this.runDeg = (this.runDeg + 36) % 360; // 每 100ms 走 6°
|
|
|
+ }, 100);
|
|
|
+ },
|
|
|
+ endSuccess(code) {
|
|
|
+ // this.targetIdx = this.list.findIndex(it=>it.code == code)
|
|
|
+ this.targetIdx = 4
|
|
|
+ const that = this
|
|
|
+ this.spinning = false;
|
|
|
+ clearInterval(this.idleTimer);
|
|
|
+ if (this.targetIdx == -1) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '抽奖失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ this.running = false;
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.animation(this.targetIdx)
|
|
|
+ setTimeout(() => {
|
|
|
+ this.running = false;
|
|
|
+ uni.showModal({
|
|
|
+ title: '恭喜,中奖',
|
|
|
+ content: this.list[this.targetIdx].name,
|
|
|
+ showCancel: false,
|
|
|
+ success: function(res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ that.$refs.turntablePopup.close()
|
|
|
+ that.$emit("openAppPop")
|
|
|
+ } else if (res.cancel) {
|
|
|
+ that.$refs.turntablePopup.close()
|
|
|
+ that.$emit("openAppPop")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, this.duration + 1000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+ @keyframes spin {
|
|
|
+ from {
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ to {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .infinite-spin {
|
|
|
+ animation: spin 1s linear infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close {
|
|
|
+ width: 64rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ margin: 24rpx auto 0 auto;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .turntable {
|
|
|
+ position: relative;
|
|
|
+ width: 660rpx;
|
|
|
+ height: 880rpx;
|
|
|
+
|
|
|
+ .bg {
|
|
|
+ width: 660rpx;
|
|
|
+ height: 880rpx;
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-con {
|
|
|
+ width: 660rpx;
|
|
|
+ height: 880rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ width: 520rpx;
|
|
|
+ height: 104rpx;
|
|
|
+ margin-top: 47rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .base {
|
|
|
+ width: 451rpx;
|
|
|
+ height: 177rpx;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 55rpx;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ z-index: 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ .decoration_img {
|
|
|
+ width: 637rpx;
|
|
|
+ height: 592rpx;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 85rpx;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ z-index: 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ring {
|
|
|
+ width: 502rpx;
|
|
|
+ height: 502rpx;
|
|
|
+ background: #FFFDFD;
|
|
|
+ border-radius: 50%;
|
|
|
+ position: relative;
|
|
|
+ margin-top: 79rpx;
|
|
|
+ z-index: 9;
|
|
|
+ }
|
|
|
+
|
|
|
+ .button {
|
|
|
+ width: 158rpx;
|
|
|
+ height: 200rpx;
|
|
|
+ position: absolute;
|
|
|
+ top: calc(50% - 21rpx);
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ring_bg {
|
|
|
+ width: 620rpx;
|
|
|
+ height: 620rpx;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 74rpx;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ z-index: 6;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-content {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ z-index: 1;
|
|
|
+ display: block;
|
|
|
+ width: 502rpx;
|
|
|
+ height: 502rpx;
|
|
|
+ border-radius: inherit;
|
|
|
+ /* background-clip: padding-box; */
|
|
|
+ /* background-color: #ffcb3f; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .icon-awrad {
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ margin-top: 10rpx;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-list {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: inherit;
|
|
|
+ height: inherit;
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-item {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ color: #e4370e;
|
|
|
+ /* text-shadow: 0 1rpx 1rpx rgba(255, 255, 255, 0.6); */
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-item-text {
|
|
|
+ position: relative;
|
|
|
+ display: block;
|
|
|
+ padding-top: 14rpx;
|
|
|
+ margin: 0 auto;
|
|
|
+ text-align: center;
|
|
|
+ -webkit-transform-origin: 50% 251rpx;
|
|
|
+ transform-origin: 50% 251rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ color: #F72F26;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 24rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-item-text text {
|
|
|
+ font-size: 30rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 分隔线 */
|
|
|
+ .canvas-line {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: inherit;
|
|
|
+ height: inherit;
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-litem {
|
|
|
+ position: absolute;
|
|
|
+ left: 251rpx;
|
|
|
+ top: 0;
|
|
|
+ width: 1rpx;
|
|
|
+ height: 251rpx;
|
|
|
+ background-color: #FF4D2C;
|
|
|
+ overflow: hidden;
|
|
|
+ -webkit-transform-origin: 50% 251rpx;
|
|
|
+ transform-origin: 50% 251rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|