topfans/frontend/pages/castlove/laser/laser-result.vue

231 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="laser-result-page">
<image class="background-image" src="/static/background/exhibitionSuccess.png" mode="aspectFill" />
<!-- 金字塔选卡5 张静态候选礼盒打开后才出现 -->
<view class="cards-container" :class="{ 'cards-visible': isGiftOpened }">
<LaserVariantPyramid
:paths="generatedImages"
:selectedIndex="selectedIndex"
@select="handleSelect"
/>
</view>
<!-- 礼盒 -->
<view class="gift-box" :class="{ 'gift-opened': isGiftOpened }">
<image v-if="!isGiftOpened" class="gift-image" src="/static/nft/lihe.png" mode="aspectFit" />
<image
v-else
class="gift-image gift-image-opened"
src="/static/nft/lihe_kaiqi.png"
mode="aspectFit"
/>
</view>
<!-- 底部操作 -->
<view class="bottom-action">
<view class="action-button action-button--secondary" @tap="handleBack">
<text class="button-text">重新选择</text>
</view>
<view class="action-button" @tap="selectAsset">
<text class="button-text">开始铸造</text>
</view>
</view>
<!-- 铸造确认弹窗 -->
<ConfirmModal
v-if="showConfirmModal"
:visible="showConfirmModal"
:cost-crystal="confirmCostInfo.costCrystal"
:current-balance="confirmCostInfo.currentBalance"
:mint-count="confirmCostInfo.mintCount"
:next-tier-cost="confirmCostInfo.nextTierCost"
@confirm="handleConfirmMint"
@cancel="handleCancelMint"
/>
</view>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue'
import ConfirmModal from '@/components/ConfirmModal.vue'
import LaserVariantPyramid from '@/components/laser/LaserVariantPyramid.vue'
import { useLaserMint } from '@/composables/useLaserMint.js'
import { CASTLOVE_FORM_KEY, GENERATED_IMAGES_KEY } from '@/utils/castloveGenerationFlow.js'
const generatedImages = ref([])
const selectedIndex = ref(0)
const craftFormData = ref(null)
const isGiftOpened = ref(false)
const getSelectedImagePath = () => {
return generatedImages.value?.[selectedIndex.value] || ''
}
const {
showConfirmModal,
confirmCostInfo,
selectAsset,
handleConfirmMint,
handleCancelMint,
} = useLaserMint({
getSelectedImagePath,
getSelectedPresetIndex: () => selectedIndex.value,
formDataRef: craftFormData,
})
const handleSelect = (idx) => {
selectedIndex.value = idx
}
const handleBack = () => {
uni.navigateBack({ delta: 1 })
}
onMounted(() => {
try {
const formStr = uni.getStorageSync(CASTLOVE_FORM_KEY)
if (formStr) craftFormData.value = JSON.parse(formStr)
const imagesStr = uni.getStorageSync(GENERATED_IMAGES_KEY)
if (imagesStr) {
generatedImages.value = JSON.parse(imagesStr)
}
} catch (e) {
console.error('[laser-result] init failed', e)
uni.showToast({ title: '数据错误', icon: 'none' })
setTimeout(() => uni.navigateBack(), 1200)
}
// 模拟 generation-result延迟打开礼盒并展示选卡
setTimeout(() => {
isGiftOpened.value = true
}, 800)
})
</script>
<style scoped>
.laser-result-page {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
background: #000;
}
.background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.cards-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s ease-in-out;
}
.cards-container.cards-visible {
opacity: 1;
pointer-events: auto;
}
.gift-box {
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
width: 480rpx;
height: 480rpx;
z-index: 3;
animation: giftFloat 3s ease-in-out infinite;
transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.gift-box.gift-opened {
width: 17rem;
bottom: 15%;
animation: none;
}
@keyframes giftFloat {
0%,
100% {
transform: translateX(-50%) translateY(0);
}
50% {
transform: translateX(-50%) translateY(-20rpx);
}
}
.gift-image {
width: 100%;
height: 100%;
transition: opacity 0.5s ease-in-out;
}
.gift-image-opened {
width: 17rem;
animation: giftOpenPop 0.5s ease-out;
}
@keyframes giftOpenPop {
0% {
transform: scale(0.8);
opacity: 0;
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
opacity: 1;
}
}
.bottom-action {
position: absolute;
left: 0;
right: 0;
bottom: 70rpx;
z-index: 30;
display: flex;
justify-content: center;
gap: 24rpx;
padding: 0 40rpx;
}
.action-button {
min-width: 260rpx;
height: 92rpx;
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
background-image: url('/static/icon/confirmbj.png');
background-size: cover;
color: #fff;
font-weight: 700;
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.35);
}
.action-button--secondary {
background-image: none;
background: rgba(255, 255, 255, 0.12);
border: 2rpx solid rgba(255, 255, 255, 0.45);
}
.button-text {
font-size: 34rpx;
}
</style>