This commit is contained in:
yixu
2025-09-08 15:36:26 +08:00
commit 9a5cf53e3c
36 changed files with 7750 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
<script setup>
import { ref, onMounted } from "vue"
import { useRouter } from 'vue-router'
defineProps({
show: true
})
const menuData = ref([
{
title: '神仙',
imgSrc: 'src/assets/images/generate/shenxian.png',
activeImgSrc: 'src/assets/images/generate/shenxian-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_1.png' },
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_2.png' },
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_3.png' },
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_4.png' },
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_5.png' },
{ imageUrl: 'src/assets/images/generate/template/shenxian/shenxian_6.png' }
]
},
{
title: '仙侠',
imgSrc: 'src/assets/images/generate/xianxia.png',
activeImgSrc: 'src/assets/images/generate/xianxia-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_1.png' },
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_2.png' },
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_3.png' },
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_4.png' },
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_5.png' },
{ imageUrl: 'src/assets/images/generate/template/xianxia/xianxia_6.png' }
]
},
{
title: '复古',
imgSrc: 'src/assets/images/generate/fugu.png',
activeImgSrc: 'src/assets/images/generate/fugu-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_1.png' },
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_2.png' },
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_3.png' },
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_4.png' },
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_5.png' },
{ imageUrl: 'src/assets/images/generate/template/fugu/fugu_6.png' }
]
},
{
title: '新中式',
imgSrc: 'src/assets/images/generate/xinzhongshi.png',
activeImgSrc: 'src/assets/images/generate/xinzhongshi-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_1.png' },
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_2.png' },
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_3.png' },
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_4.png' },
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_5.png' },
{ imageUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_6.png' }
]
},
{
title: '露营',
imgSrc: 'src/assets/images/generate/luying.png',
activeImgSrc: 'src/assets/images/generate/luying-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/luying/luying_1.png' },
{ imageUrl: 'src/assets/images/generate/template/luying/luying_2.png' },
{ imageUrl: 'src/assets/images/generate/template/luying/luying_3.png' },
{ imageUrl: 'src/assets/images/generate/template/luying/luying_4.png' },
{ imageUrl: 'src/assets/images/generate/template/luying/luying_5.png' },
{ imageUrl: 'src/assets/images/generate/template/luying/luying_6.png' }
]
},
{
title: '派对',
imgSrc: 'src/assets/images/generate/paidui.png',
activeImgSrc: 'src/assets/images/generate/paidui-selected.png',
children: [
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_1.png' },
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_2.png' },
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_3.png' },
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_4.png' },
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_5.png' },
{ imageUrl: 'src/assets/images/generate/template/paidui/paidui_6.png' }
]
}
]);
onMounted(() => {
activeMenu.value = { ...activeMenu.value, level1: 0 };
updateDisplayedImages();
})
const router = useRouter();
const navigateTodoList = () => {
router.push({
name: 'home'
})
}
const activeMenu = ref({
level1: 0
});
const selectMenu = (level, index)=> {
if (level === 1) {
activeMenu.value = { ...activeMenu.value, level1: index };
updateDisplayedImages();
}
}
const updateDisplayedImages = ()=> {
if (activeMenu.value.level1 !== null && menuData.value[activeMenu.value.level1]) {
displayedImages.value = menuData.value[activeMenu.value.level1].children;
} else {
displayedImages.value = [];
}
}
const contentPanels = ref([{}]);
const getMenuLevelTitle = (level) => {
const index = activeMenu.value[`level${level}`];
if (index === null || index === undefined) return '-';
if (level === 1) {
return menuData.value[index]?.title || '-';
}
return '-';
};
const getImageStyle = (index, actived)=> {
console.log(actived)
return {
position: 'absolute',
width: actived? index === 3? '68px' : '54px' : index === 3 ? '66px' : '44px',
top: actived? '14.2%' : '15%',
left: calculateMenuLevel1Left(index, actived) + '%'
}
}
// 计算一级菜单位置
const calculateMenuLevel1Left = (index, actived) => {
const multiplier =
index === 1 ? actived? 12.5 : 13.5 :
index === 2 ? actived? 13 : 13.5 :
index === 3 ? 13.5 :
index === 4 ? actived? 14.6 : 14.8 :
index === 5 ? 14.6 :
13.8;
return (8.4 + index * multiplier).toFixed(1);
};
const displayedImages = ref([]);
const goToGenerateImgPage = (item) => {
const hasVisitedBefore = localStorage.getItem('hasVisitedGenerateImg');
if (!hasVisitedBefore) {
localStorage.setItem('hasVisitedGenerateImg', 'true');
router.push({
name: 'generateImgConfirm',
query: { imageUrl: item.imageUrl }
});
} else {
router.push({
name: 'generateImg',
query: { imageUrl: item.imageUrl }
});
}
}
</script>
<template>
<div :show="show">
<div class="home-wrapper" style="z-index: 9;">
<div class="scene-item item-1">
<img src="../assets/images/back-btn.png" @click="navigateTodoList" alt="后退">
</div>
<!-- 一级菜单 -->
<div class="menu-level-1">
<div
v-for="(item, index) in menuData"
:key="'level1-' + index"
class="menu-item"
:class="{ active: activeMenu.level1 === index }"
@click="selectMenu(1, index)"
>
<img
:src="activeMenu.level1 === index ? item.activeImgSrc : item.imgSrc"
:style="getImageStyle(index, activeMenu.level1 === index)"
/>
</div>
</div>
<div class="images-container">
<div
v-for="(item, index) in displayedImages"
:key="index"
@click="goToGenerateImgPage(item)"
class="mask-image mask-background"
:style="{ 'background-image': `url(${item.imageUrl})` }"
>
<img class="border-img" src="../assets/images/generate/border.png" alt="边框">
</div>
</div>
<div class="content-area">
<div
v-for="(item, index) in contentPanels"
:key="'panel-' + index"
class="content-panel"
:class="{ active: activeContent === index }"
>
<div class="content-header">
<div class="breadcrumb">
<span>{{ getMenuLevelTitle(1) }}</span>
<span>{{ getMenuLevelTitle(2) }}</span>
</div>
<h2>{{ item.title }}</h2>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.images-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 100%;
gap: 14px;
margin-top: 192px;
overflow: hidden;
overflow-y: auto;
}
.mask-background {
-webkit-mask-image: url("../assets/images/generate/mengban.png");
mask-image: url("../assets/images/generate/mengban.png");
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
.mask-image {
background-size: cover;
background-repeat: no-repeat;
position: relative;
width: 168px;
height: 224px;
}
.border-img {
width: 170px;
height: 231px;
position: absolute;
top: -2px;
left: 0px;
}
.home-wrapper {
width: 100%;
height: 92vh;
background-image: url('../assets/images/generate/select-template-bg.png');
background-size: cover;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
min-height: -webkit-fill-available;
}
.scene-item {
position: absolute;
z-index: 2;
cursor: pointer;
transition: all 0.4s ease;
border-radius: 8px;
overflow: hidden;
border: 3px solid transparent;
animation: float 4s ease-in-out infinite;
}
.scene-item:hover {
transform: scale(1.05);
z-index: 10;
}
.scene-item img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.item-1 {
width: 20px;
top: 6.7%;
left: 5%;
animation-delay: 0s;
}
</style>