Files
super_video/src/views/home/components/StudyProgressPopup/CertificateDetailPopup.vue
T
2026-09-21 10:30:13 +08:00

134 lines
3.0 KiB
Vue

<script lang="ts" setup>
import { onMounted } from 'vue'
import { getStaticImage } from '@/utils'
import { ImgButton } from '@/components'
defineOptions({
name: 'CertificateDetailPopup',
})
defineProps<{
date: string // '2026-06-18' 颁发日期
certificateNumber: string // '001' 证书编号
studentNumber: string // '001' 学员数量
}>()
const visible = defineModel<boolean>({ default: false })
const emit = defineEmits<{
close: []
}>()
const certificateDetailSrc = getStaticImage('components/medal/证书详情')
onMounted(() => {
const img = new Image()
img.src = certificateDetailSrc
})
const handleClose = () => {
visible.value = false
emit('close')
}
</script>
<template>
<Transition name="certificate-fade">
<div
v-if="visible"
class="absolute inset-0 z-[120] flex items-center justify-center bg-black/45"
@click.stop
>
<div class="certificate-detail relative text-2xl">
<img
draggable="false"
:src="certificateDetailSrc"
class="certificate-detail-img object-contain"
alt=""
/>
<ImgButton
class="absolute right-0 top-0 z-10"
:image="'components/close'"
@click="handleClose"
/>
<!-- 证书编号 -->
<span class="absolute bottom-[154px] left-[390px]">
{{ certificateNumber }}
</span>
<!-- 颁发日期 -->
<span class="absolute bottom-[122px] left-[390px]">{{ date }}</span>
<!-- 多少位学员 -->
<!-- <span class="absolute bottom-[468px] left-[948px] text-3xl">
{{ studentNumber }}
</span>
<span class="absolute bottom-[380px] left-[1070px]">
{{ studentNumber }}
</span> -->
</div>
</div>
</Transition>
</template>
<style scoped>
.certificate-fade-enter-active {
transition: opacity 220ms ease-out;
}
.certificate-fade-leave-active {
transition: opacity 160ms ease-in;
}
.certificate-fade-enter-from,
.certificate-fade-leave-to {
opacity: 0;
}
.certificate-fade-enter-active .certificate-detail,
.certificate-fade-leave-active .certificate-detail {
transition:
opacity 220ms ease,
transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.certificate-fade-enter-from .certificate-detail {
opacity: 0;
transform: translate3d(0, 36px, 0) scale(0.96);
}
.certificate-fade-enter-to .certificate-detail,
.certificate-fade-leave-from .certificate-detail {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
.certificate-fade-leave-to .certificate-detail {
opacity: 0;
transform: translate3d(0, 24px, 0) scale(0.98);
}
.certificate-detail {
transform: translateZ(0);
will-change: transform, opacity;
}
.certificate-detail::before {
content: '';
position: absolute;
inset: 8% 12%;
z-index: -1;
border-radius: 48px;
background: radial-gradient(
circle,
rgba(255, 255, 255, 0.35) 0%,
rgba(117, 235, 255, 0.2) 38%,
rgba(117, 235, 255, 0) 72%
);
}
.certificate-detail-img {
width: 100%;
height: 100%;
}
</style>