spinz777/src/pages/redeposit/ReDeposit.vue

964 lines
34 KiB
Vue
Raw Normal View History

2025-03-10 15:44:49 +08:00
<script setup>
import { ref, computed, onMounted, nextTick } from 'vue';
import { onLoad, onUnload } from '@dcloudio/uni-app';
import { useThemeStore } from '@/store/useThemeStore';
import { useAppStore } from '@/store/useAppStore';
import Boardcast from './components/Boardcast.vue';
import config from '@/config/global.config';
import { checkRedepositApi, getRepositLotteryApi } from '@/api/promo';
import Congratulation from '@/components/popup/Congratulation.vue';
import { useUserStore } from '@/store/useUserStore';
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const appStore = useAppStore();
const themeStore = useThemeStore();
const userStore = useUserStore();
const dw = computed(() => themeStore.theme.depositWheel);
const active = ref(0);
const imgBgs = [dw.value.wheelBg0, dw.value.wheelBg1, dw.value.wheelBg2, dw.value.wheelBg3];
const statusBarHeight = ref(20)
// import sliverRing from '@/static/deposit_wheel/image_zpwk_silver.png'
// import goldRing from '@/static/deposit_wheel/image_zpwk_gold.png'
// import diamondRing from '@/static/deposit_wheel/image_zpwk_diamond.png'
// import supremeRing from '@/static/deposit_wheel/image_zpwk_supreme.png'
// import sliverPoint from '@/static/deposit_wheel/image_zhizhen_silver.png'
// import goldPoint from '@/static/deposit_wheel/image_zhizhen_gold.png'
// import diamondPoint from '@/static/deposit_wheel/image_zhizhen_diamond.png'
// import supremePoint from '@/static/deposit_wheel/image_zhizhen_supreme.png'
// import spinBg from '@/static/deposit_wheel/image_zpdk.png'
// import jinbi from '@/static/deposit_wheel/image_jinbi.png'
// import zhibi from '@/static/deposit_wheel/image_zhibi.png'
const imgPaths = [
config.canvasImage + '/deposit_wheel/image_zpwk_silver.png',
config.canvasImage + '/deposit_wheel/image_zpwk_gold.png',
config.canvasImage + '/deposit_wheel/image_zpwk_diamond.png',
config.canvasImage + '/deposit_wheel/image_zpwk_supreme.png',
];
const pointImgs = [
config.canvasImage + '/deposit_wheel/image_zhizhen_silver.png',
config.canvasImage + '/deposit_wheel/image_zhizhen_gold.png',
config.canvasImage + '/deposit_wheel/image_zhizhen_diamond.png',
config.canvasImage + '/deposit_wheel/image_zhizhen_supreme.png',
]
const spinBg = config.canvasImage + '/deposit_wheel/image_zpdk.png';
const jinbi = config.canvasImage + '/spins/image_jinbi.png';
const zhibi = config.canvasImage + '/spins/image_zhibi.png';
const typeEnum = ['Amount', 'Sliver Spin', 'Gold Spin', 'Diamond Spin', 'Supreme Spin'];
const isSpinning = ref(false);
const size = 260;
const innerSize = 228;
const duration = 5000
let targetIndex = 0
const activityContent = ref([])
const lottery = ref([])
const prizes = computed(() => activityContent.value[active.value]?.prizes ?? [])
const rechargeAmount = ref(0)
const disabledIndex = ref(3)
const spinCounts = ref([0, 0, 0, 0])
const uptoAmount = [377, 777, 1777, 3777]
const spinCount = computed(() => {
if (lottery.value.length > 0) {
return lottery.value[active.value].curCount
}
return 0
})
const rotationResult = ref(0)
const awardAmount = ref('')
const awardPopup = ref(null)
const currency = computed(() => import.meta.env.VITE_CURRENCY_SYMBOL)
const currency2 = ref('')
const percent = ref(0)
const autoRotation = ref(0);
const isAutoRotating = ref(true);
const autoRotateSpeed = 0.003;
const sliceWidth = ref(0);
const totalW = ref(0);
const canvasSpace = ref(0);
const startPoint = ref([0, 0]);
const moveWidth = ref(0);
const scale = ref(1);
const scaleMin = 0.8;
const scaleSpeed = 0.001;
// claude gen
const currentIndex = ref(0);
const wheelRefs = ref([]);
const isDragging = ref(false);
const startX = ref(0);
const translateX = ref(0);
const initialTranslateX = ref(0);
const animating = ref(false);
const wheelCanvasIds = ['depositWheel0', 'depositWheel1', 'depositWheel2', 'depositWheel3'];
const wheelContexts = ref([null, null, null, null]);
const wheelRotations = ref([0, 0, 0, 0]);
let autoTimer = null
const wheelsDrawnComplete = ref(false);
const wheelDrawnStatus = ref([false, false, false, false]);
// 计算缩放比例的方法
const calculateScale = (index) => {
if (index === currentIndex.value) {
return 1;
} else {
const distance = Math.abs(index - currentIndex.value);
return Math.max(1 - distance * 0.2, scaleMin);
}
};
// 处理触摸开始事件
const onTouchStart = (e) => {
if (animating.value || isSpinning.value) return;
const touch = e.touches[0];
startX.value = touch.clientX;
initialTranslateX.value = translateX.value;
isDragging.value = true;
};
// 处理触摸移动事件
const onTouchMove = (e) => {
if (!isDragging.value || animating.value || isSpinning.value) return;
const touch = e.touches[0];
const deltaX = touch.clientX - startX.value;
translateX.value = initialTranslateX.value + deltaX;
};
// 处理触摸结束事件
const onTouchEnd = () => {
if (!isDragging.value || animating.value || isSpinning.value) return;
isDragging.value = false;
animating.value = true;
// 计算应该滑动到哪个索引
const moveDistance = translateX.value - initialTranslateX.value;
let targetIndex = currentIndex.value;
if (Math.abs(moveDistance) > sliceWidth.value * 0.2) {
if (moveDistance > 0 && currentIndex.value > 0) {
targetIndex = currentIndex.value - 1;
} else if (moveDistance < 0 && currentIndex.value < activityContent.value.length - 1) {
targetIndex = currentIndex.value + 1;
} else if (moveDistance < 0 && currentIndex.value < activityContent.value.length - 1) {
// 检查是否可以滑动到最后一个转盘
if (currentIndex.value === activityContent.value.length - 2 && rechargeAmount.value <= 1777) {
// 如果是倒数第二个转盘且充值金额不足,不允许滑动到最后一个
targetIndex = currentIndex.value;
} else {
targetIndex = currentIndex.value + 1;
}
}
}
// 滑动到目标索引
slideToIndex(targetIndex);
};
// 滑动到指定索引
const slideToIndex = (index) => {
if (index === activityContent.value.length - 1 && rechargeAmount.value <= 1777) {
// 如果是最后一个转盘且充值金额不足,不允许滑动
index = activityContent.value.length - 2;
uni.showToast({
title: t('redeposit.supreme'),
icon: 'none',
duration: 3500
})
}
if (index === currentIndex.value) {
// 如果是当前索引,回弹到原位
const windowInfo = uni.getWindowInfo();
const w = windowInfo.windowWidth;
const initialOffset = (w - sliceWidth.value) / 2;
translateX.value = initialOffset - currentIndex.value * sliceWidth.value;
animating.value = false;
return;
}
// 设置动画
const startTranslateX = translateX.value;
const windowInfo = uni.getWindowInfo();
const w = windowInfo.windowWidth;
const initialOffset = (w - sliceWidth.value) / 2;
const targetTranslateX = initialOffset - index * sliceWidth.value;
const startTime = Date.now();
const duration = 600; // 动画持续时间
const animate = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeInOutQuad(progress);
translateX.value = startTranslateX + (targetTranslateX - startTranslateX) * easedProgress;
if (progress < 1) {
// #ifdef H5
requestAnimationFrame(animate);
// #endif
// #ifndef H5
setTimeout(animate, 16.6);
// #endif
} else {
translateX.value = targetTranslateX;
currentIndex.value = index;
animating.value = false;
active.value = index;
calPercent();
}
};
animate();
};
// 缓动函数
const easeInOutQuad = (t) => {
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
};
function drawWheel(rotation = 0, wheelIndex = active.value) {
const actualRotation = isAutoRotating.value && !isSpinning.value ? autoRotation.value : rotation;
wheelRotations.value[wheelIndex] = actualRotation;
const context = uni.createCanvasContext(wheelCanvasIds[wheelIndex]);
wheelContexts.value[wheelIndex] = context;
const center = size / 2;
const innerCenter = innerSize / 2;
const radius = center - 10;
// const sliceAngle = (2 * Math.PI) / prizes.value.length;
const sliceAngle = (2 * Math.PI) / activityContent.value[wheelIndex].prizes.length;
context.clearRect(0, 0, size, size);
context.save();
context.translate(center, center);
context.rotate(actualRotation);
context.translate(-center, -center);
context.drawImage(spinBg, center - innerCenter, center - innerCenter, innerSize, innerSize);
for (let index = 0, len = prizes.value.length; index < len; index++) {
// const prize = prizes.value[index];
const prize = activityContent.value[wheelIndex].prizes[index];
context.save();
context.translate(center, center);
// Rotate to the middle of the slice
context.rotate(index * sliceAngle);
// Rotate 90 degrees to make text perpendicular
context.rotate(Math.PI / 2);
// 0: sliver,1:gold,2:diamond,3:supreme
// Text settings
context.setTextAlign('center');
context.setTextBaseline('bottom');
context.setFillStyle('#fff');
context.font = '11px sans-serif';
let startY = -radius * 0.73;
if (prize.type === 0) {
context.fillText(`${currency.value}${prize.amount}`, 0, startY)
} else {
context.fillText(`${typeEnum[prize.type]}`, 0, startY)
startY = -radius * 0.63
context.fillText(`x ${prize.amount}`, 0, startY)
}
// const img2 = index % 2 === 0 ? jinbi : zhibi
const img2 = config.canvasImage + '/deposit_wheel/' + prizes.value[index]['icon']
// const img2 = await loadImg(config.canvasImage + currentImg)
// const img2 = config.canvasImage + currentImg
let _radius = center * 0.44;
let iconSize = 30;
if (prizes.value[index].type === 0) {
iconSize = 38
_radius = center * 0.46;
}
context.drawImage(
img2,
-19, // Center horizontally
-_radius - 17, // Position at sector center,
iconSize,
iconSize);
// Rotate to the middle of the slice
// context.rotate(index * sliceAngle);
context.restore();
}
context.restore();
context.translate(center, center)
context.rotate(0);
context.translate(-center, -center)
context.drawImage(imgPaths[wheelIndex], 0, 0, size, size);
context.save();
context.restore();
context.translate(center, center)
context.rotate(0)
// Draw fixed pointer in center (after rotation restore)
// const img = await loadImg(config.canvasImage + pointImgs[wheelIndex])
const img = pointImgs[wheelIndex]
context.drawImage(img, -32.5, -53.75, 65, 87.5);
context.save();
// Draw spin count
context.restore();
// context.translate(center, center);
context.rotate(0);
context.setTextAlign('center');
context.setTextBaseline('middle');
context.setFillStyle('#C14F21');
context.font = 'bold 16px sans-serif';
context.fillText('GO', 0, -6);
context.font = 'bold 11px sans-serif';
context.fillText(`Spin*${spinCount.value}`, 0, 12);
context.draw(false, () => {
// 标记当前转盘已绘制完成
wheelDrawnStatus.value[wheelIndex] = true;
// 检查所有需要显示的转盘是否都已绘制完成
const visibleWheelsCount = rechargeAmount.value > 1777 ? 4 : 3;
const allDrawn = wheelDrawnStatus.value.slice(0, visibleWheelsCount).every(status => status);
if (allDrawn && !wheelsDrawnComplete.value) {
wheelsDrawnComplete.value = true;
// 所有转盘绘制完成后,开始自动旋转
setTimeout(() => {
isAutoRotating.value = true;
startAutoRotate();
}, 1000); // 添加短暂延迟确保UI更新
}
});
}
const calculateTargetRotation = (targetIndex) => {
// Calculate base rotation needed to align the target index
const sliceAngle = (2 * Math.PI) / prizes.value.length;
// Calculate the angle needed to rotate the target index to 12 o'clock
// We add Math.PI/2 to start from 12 o'clock (instead of 3 o'clock)
// We subtract the target index angle to rotate counterclockwise
// We add sliceAngle/2 to center the slice
const baseAngle = Math.PI - ((targetIndex - 2) * sliceAngle);
// Add extra rotations (5-8 full spins)
const extraRotations = Math.PI * 2 * (5 + Math.floor(Math.random() * 3));
// Return total rotation (extra rotations + base angle)
return extraRotations + baseAngle;
};
const startAutoRotate = () => {
if (!isAutoRotating.value || isSpinning.value) return;
const animate = () => {
if (!isAutoRotating.value || isSpinning.value) return;
// 增加旋转角度
autoRotation.value += autoRotateSpeed;
// 确保角度在0-2π之间循环
if (autoRotation.value >= Math.PI * 2) {
autoRotation.value -= Math.PI * 2;
}
// drawWheel(rotationResult.value);
for (let i = 0; i < wheelCanvasIds.length; i++) {
if (activityContent.value[i]) {
drawWheel(autoRotation.value, i);
}
}
// 继续下一帧动画
// #ifdef H5
requestAnimationFrame(animate);
// #endif
// #ifndef H5
autoTimer = setTimeout(animate, 16.6);
// #endif
};
animate();
};
const startSpin = async () => {
if (isSpinning.value) return;
isSpinning.value = true;
isAutoRotating.value = false;
wheelsDrawnComplete.value = true;
// If targetIndex is provided and valid, use it; otherwise random
let finalIndex;
if (targetIndex >= 0 && targetIndex < prizes.value.length) {
finalIndex = targetIndex;
} else {
finalIndex = Math.floor(Math.random() * prizes.value.length);
}
const targetRotation = calculateTargetRotation(finalIndex);
rotationResult.value = targetRotation
autoRotation.value = targetRotation
const startTime = Date.now();
const animate = () => {
const currentTime = Date.now();
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOut(progress);
const rotation = targetRotation * easedProgress;
drawWheel(rotation);
if (progress < 1) {
// #ifdef H5
requestAnimationFrame(animate);
// #endif
// #ifndef H5
setTimeout(animate, 16.6);
// #endif
} else {
// isSpinning.value = false;
console.log('Final Index:', finalIndex, 'Prize:', prizes.value[finalIndex]);
const prize = prizes.value[finalIndex]
if (prize.type === 0) {
currency2.value = currency.value
awardAmount.value = prizes.value[finalIndex].amount
} else {
currency2.value = ''
awardAmount.value = typeEnum[prize.type] + ' x ' + prizes.value[finalIndex].amount
}
awardPopup.value?.open()
// TODO emit('spin-end', prizes.value[finalIndex]);
}
};
animate();
};
const easeOut = (t) => {
return 1 - Math.pow(1 - t, 5);
};
async function loadImg(src) {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src,
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
},
});
})
}
const calPercent = () => {
const stepItem = activityContent.value[active.value]
const val = Math.ceil((rechargeAmount.value / stepItem.amounts[stepItem.amounts.length - 1]) * 100)
percent.value = val >= 100 ? 100 : val
}
const handleTabClick = (idx) => {
// if (idx >= disabledIndex.value) return
// active.value = idx
// calPercent()
// drawWheel()
// console.log("handleTabClick", idx, disabledIndex.value);
if (idx === 3 && rechargeAmount.value < 1777) {
uni.showToast({
title: t('redeposit.supreme'),
icon: 'none',
duration: 3500
})
return
}
if (idx >= disabledIndex.value || animating.value || isSpinning.value) return;
active.value = idx;
slideToIndex(idx);
}
const getRedepositAct = async () => {
const { code, data } = await checkRedepositApi();
if (code == 200) {
console.log('checkRedepositApi:', JSON.parse(data.activity.content));
if (data?.activity?.content) {
const _content = JSON.parse(data.activity.content)
activityContent.value = _content.map((item, index) => {
return {
...item,
bgImg: imgBgs[index]
}
})
}
if (data?.lottery) {
rechargeAmount.value = data?.lottery?.rechargeAmount
lottery.value = JSON.parse(data?.lottery?.lottery)
// const last = activityContent.value[2]
if (rechargeAmount.value >= 1777) {
disabledIndex.value = 4
}
console.log('disabledIndex:', disabledIndex.value);
// spinCount.value = lottery.value[active.value].curCount
spinCounts.value = lottery.value.reduce((acc, cur) => {
acc.push(cur.curCount)
return acc
}, [])
calPercent()
}
}
}
const requestLottery = async () => {
const { data } = await getRepositLotteryApi({ id: activityContent.value[active.value].level })
console.log("getRepositLotteryApi:", data);
targetIndex = data
}
const handleStart = async () => {
const count = spinCounts.value[active.value]
if (count === 0) {
uni.showToast({
title: t('redeposit.noCount'),
icon: 'none',
duration: 3500
})
return
}
await requestLottery()
setTimeout(() => {
// drawWheel()
startSpin()
}, 200);
}
const onClose = async () => {
// isSpinning.value = false;
await getRedepositAct()
// drawWheel()
setTimeout(() => {
isSpinning.value = false;
isAutoRotating.value = true;
wheelsDrawnComplete.value = false;
startAutoRotate();
}, 1000);
}
const toRules = () => {
uni.navigateTo({ url: '/pages/redeposit/WheelRules' })
}
const toHistory = () => {
uni.navigateTo({ url: '/pages/redeposit/WheelHistory' })
}
const depositNow = () => {
uni.navigateTo({ url: '/pages/wallet/Deposit' })
}
onLoad(async () => {
await getRedepositAct()
// await drawWheel();
const windowInfo = uni.getWindowInfo();
statusBarHeight.value = windowInfo.statusBarHeight;
const w = windowInfo.windowWidth;
const space = (w - size) / 2;
const _sliceWidth = space + size;
// const _totalW = _sliceWidth * (rechargeAmount.value > 1777 ? 4 : 3);
sliceWidth.value = sliceWidth.value = w * 0.8;;
canvasSpace.value = space / 2;
const visibleWheels = rechargeAmount.value > 1777 ? 4 : 3;
sliceWidth.value = w * 0.68;
totalW.value = sliceWidth.value * visibleWheels;
const initialOffset = (w - sliceWidth.value) / 2;
translateX.value = initialOffset;
nextTick(() => {
// reset status
wheelDrawnStatus.value = [false, false, false, false];
wheelsDrawnComplete.value = false;
isAutoRotating.value = false; // 先禁用自动旋转
for (let i = 0; i < wheelCanvasIds.length; i++) {
if (activityContent.value[i]) {
drawWheel(0, i);
}
}
// startAutoRotate();
})
});
onUnload(() => {
isAutoRotating.value = false;
clearTimeout(autoTimer);
});
</script>
<template>
<mobile-custom-layout :bgColor="dw.bgColor">
<template #head-right>
<view class="count-box flex items-center" :style="{ background: dw.dark2, borderColor: dw.pentary }">
<theme-image class="icon-coin" src="@/static/deposit_wheel/icon_coin.png" />
<text class="coin-amount" :style="{ color: dw.quaternary }">
{{ userStore.userInfo?.totalAssets ?? 0 }}
</text>
</view>
</template>
<view style="position: fixed;top: -11111px;left: -11111px;">
<theme-image src="@/static/deposit_wheel/bg_silver.png" />
<theme-image src="@/static/deposit_wheel/bg_gold.png" />
<theme-image src="@/static/deposit_wheel/bg_diamond.png" />
<theme-image src="@/static/deposit_wheel/bg_supreme.png" />
<theme-image v-for="(item, index) in imgPaths" :key="index" :src="item" />
<theme-image v-for="(item, index) in pointImgs" :key="index" :src="item" />
<image :src="spinBg" mode="scaleToFill" />
<image :src="jinbi" mode="scaleToFill" />
<image :src="zhibi" mode="scaleToFill" />
<!-- <theme-image src="@/static/deposit_wheel/image_zpwk_gold.png" />
<theme-image src="@/static/deposit_wheel/image_zpwk_diamond.png" />
<theme-image src="@/static/deposit_wheel/image_zpwk_supreme.png" />
<theme-image src="@/static/deposit_wheel/image_zhizhen_silver.png" />
<theme-image src="@/static/deposit_wheel/image_zhizhen_gold" />
<theme-image src="@/static/deposit_wheel/image_zhizhen_supreme.png" />
<theme-image src="@/static/deposit_wheel/image_zhizhen_diamond.png" /> -->
<!-- <theme-image src="@/static/deposit_wheel/image_zpdk.png" />
<theme-image src="@/static/spins/image_jinbi.png" />
<theme-image src="@/static/spins/image_jinbi.png" /> -->
</view>
<view class="content w-full" :style="{ background: dw.bgImg, paddingTop: (statusBarHeight + 50) + 'px' }">
<view class="slogan w-full flex flex-column items-center">
<theme-image class="slogan-img" src="@/static/deposit_wheel/bt.png" />
<view class="desc" :style="{ color: dw.text }">
{{ $t('redeposit.slogan1') }}
</view>
<view class="desc" :style="{ color: dw.text }">{{ $t('redeposit.slogan2') }}</view>
<view class="deposit-btn flex-center" @click="depositNow"
:style="{ background: dw.btnBg, color: dw.secondary }">
{{ $t('redeposit.depositNow') }}
</view>
<view class="notice">
<Boardcast />
</view>
</view>
<view class="wheel-content w-full" :style="{ background: imgBgs[active] }">
<view class="wheel-tab w-full grid-col-4">
<view v-for="(item, index) in activityContent" :key="index" @click.stop="handleTabClick(index)"
class="wheel-item flex-1 flex flex-column items-center justify-end relative"
:style="{ color: dw.light }">
<template v-if="index === 3">
<template v-if="disabledIndex == 3">
<view class="upto">Supreme</view>
<view class="amount">Wheel</view>
</template>
<template v-else>
<view class="upto">upto</view>
<view class="amount">3777</view>
</template>
<theme-image v-if="disabledIndex <= 3" class="icon-lock"
src="@/static/deposit_wheel/image_lock.png" />
<view v-if="disabledIndex >= 3" class="lot-count flex-center"
:style="{ color: item.bgImg }">
{{ spinCounts[index] }}
</view>
</template>
<template v-else>
<view class="upto">{{ $t('redeposit.upto') }}</view>
<view class="amount">{{ uptoAmount[index] }}</view>
<theme-image v-if="index >= disabledIndex" class="icon-lock"
src="@/static/deposit_wheel/image_lock.png" />
<view class="lot-count flex-center" :style="{ color: item.bgImg }">
{{ spinCounts[index] }}
</view>
</template>
</view>
</view>
<view class="wheel-box">
<view class="progress-box relative">
<view class="progress-wrapper">
<view class="progress-inner" :style="{ width: percent + '%' }"></view>
</view>
<view class="float-step flex justify-between pos-absolute">
<view class="step-item">
<view class="flex flex-column items-center" :style="{ color: dw.light }">
<view class="step-img"></view>
<view class="step-currency"></view>
<view class="step-count"></view>
</view>
</view>
<view class="step-item" v-for="(item, index) in activityContent[active]?.amounts"
:key="index">
<view class="flex flex-column items-center" :style="{ color: dw.light }">
<view class="step-img">
<theme-image src="@/static/deposit_wheel/wheel_image.png" class="icon-step" />
</view>
<view class="step-currency">{{ currency }} {{ item }}</view>
<view class="step-count" :style="{ color: dw.tertiary }"> +1 Spin</view>
</view>
</view>
</view>
</view>
<!-- <view class="canvas-content flex items-center"
:style="{ width: totalW + 'px', height: size + 'px', 'padding-left': canvasSpace + 'px' }">
<view class="canvas-wrapper relative"
:style="{ width: size + 'px', height: size + 'px', 'margin-left': canvasSpace + 'px', 'margin-right': canvasSpace + 'px' }">
<canvas canvas-id="depositWheel" id="depositWheel"
:style="{ width: size + 'px', height: size + 'px' }"></canvas>
<view class="click-area pos-absolute" @click.stop="handleStart"></view>
</view>
</view> -->
<view class="wheel-carousel" @touchstart="onTouchStart" @touchmove="onTouchMove"
@touchend="onTouchEnd">
<view class="wheel-carousel-inner"
:style="{ transform: `translateX(${translateX}px)`, transition: animating ? 'transform 0.2s ease' : 'none' }">
<view v-for="(item, index) in activityContent" :key="index" class="wheel-carousel-item"
:style="{
transform: `scale(${calculateScale(index)})`,
opacity: currentIndex === index ? 1 : 0.8,
transition: animating ? 'transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease' : 'transform 0.3s ease',
width: sliceWidth + 'px',
display: (index === activityContent.length - 1 && rechargeAmount <= 1777) ? 'none' : 'flex'
}">
<view class="canvas-wrapper relative"
:style="{ width: size + 'px', height: size + 'px', margin: '0 auto' }"
:ref="el => { if (el) wheelRefs[index] = el }">
<canvas :canvas-id="wheelCanvasIds[index]" :id="wheelCanvasIds[index]"
:style="{ width: size + 'px', height: size + 'px' }"></canvas>
<view class="click-area pos-absolute" @click.stop="handleStart"></view>
</view>
</view>
</view>
</view>
</view>
</view>
<theme-image src="@/static/deposit_wheel/bg_lasheng.png" class="w-full bottom-img"
mode="aspectFill"></theme-image>
</view>
<view @click="toRules" class="rules flex-center" :style="{ background: dw.awardBg, color: dw.light }">Rules
</view>
<view @click="toHistory" class="rules history flex-center" :style="{ background: dw.awardBg, color: dw.light }">
History
</view>
<Congratulation ref="awardPopup" :prize-amount="awardAmount" :currency="currency" @close="onClose" />
</mobile-custom-layout>
</template>
<style lang="scss" scoped>
.content {
min-height: 100vh;
overflow-x: hidden;
.slogan-img {
width: 458rpx;
height: 114rpx;
}
.desc {
font-family: Roboto;
font-weight: 400;
font-size: 23rpx;
color: #F797A1;
}
.deposit-btn {
width: 350rpx;
height: 78rpx;
margin-top: 15rpx;
font-family: Roboto;
font-weight: 600;
font-size: 31rpx;
color: #7B0810;
}
.notice {
width: 575rpx;
margin-top: 34rpx;
}
.bottom-img {
height: 300rpx;
}
.wheel-content {
height: 854rpx;
margin-top: 27rpx;
// overflow-x: hidden;
.wheel-tab {
height: 146rpx;
.wheel-item {
font-family: Roboto;
font-weight: 400;
font-size: 23rpx;
color: #FFFFFF;
line-height: 25rpx;
.amount {
margin-bottom: 4rpx;
margin-top: 4rpx;
}
.icon-lock {
width: 28rpx;
height: 36rpx;
position: absolute;
top: 47rpx;
left: 50%;
transform: translate(-50%, -50%);
}
.lot-count {
width: 36rpx;
height: 36rpx;
background: linear-gradient(0deg, #C62D2C, #ED6556);
border-radius: 50%;
font-family: Roboto;
font-weight: 400;
font-size: 23rpx;
color: #FFFFFF;
line-height: 25rpx;
position: absolute;
top: -8rpx;
right: -2rpx;
}
}
}
.grid-col-4 {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
column-gap: 20rpx;
}
.wheel-box {
width: 100%;
margin-top: 20rpx;
overflow-x: hidden;
.progress-box {
width: 688rpx;
height: 94rpx;
padding: 0 16rpx;
padding-top: 14rpx;
margin: 0 auto;
.progress-wrapper {
width: 100%;
height: 27rpx;
background: linear-gradient(0deg, #670003, #88000E);
border-radius: 14rpx;
border: 1px solid #F3B459;
.progress-inner {
height: 100%;
background: linear-gradient(0deg, #EDC148, #EAAB32, #FFF237, #FFFCA0, #FFF137);
border-radius: 13rpx;
}
}
.float-step {
top: 0;
left: 0;
width: 100%;
height: 100%;
.step-item {
position: relative;
right: -14rpx;
}
.step-img {
width: 48rpx;
height: 48rpx;
}
.icon-step {
width: 48rpx;
height: 48rpx;
display: block;
}
.step-currency {
font-size: 25rpx;
line-height: 24rpx;
}
.step-count {
font-size: 22rpx;
}
}
}
.canvas-content {
margin-top: 24rpx;
}
.canvas-wrapper {
.click-area {
width: 160rpx;
height: 160rpx;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
}
}
}
}
}
.count-box {
min-width: 164rpx;
height: 42rpx;
background: #050202;
border-radius: 21rpx;
border: 2px solid #301A1A;
.icon-coin {
width: 34rpx;
height: 32rpx;
margin-left: 4rpx;
flex-shrink: 0;
}
.coin-amount {
font-family: Roboto;
font-weight: 400;
font-size: 21rpx;
color: #FFD45B;
margin-left: 16rpx;
}
}
.wheel-carousel {
width: 100%;
overflow: hidden;
position: relative;
margin-top: 24rpx;
}
.wheel-carousel-inner {
display: flex;
width: 100%;
will-change: transform;
}
.wheel-carousel-item {
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
transform-origin: center center;
}
.rules {
position: fixed;
left: 0;
top: 220rpx;
width: 96rpx;
height: 52rpx;
z-index: 999;
font-family: Roboto;
font-weight: 400;
font-size: 23rpx;
color: #FFFFFF;
}
.history {
top: 300rpx;
}
</style>