mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
🌱 角色详情页 overlay 草创
This commit is contained in:
55
src/components/userCharacter/tuc-detail-constellation.vue
Normal file
55
src/components/userCharacter/tuc-detail-constellation.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="tuc-dc-box">
|
||||
<div v-if="!modelValue.active" class="tuc-dc-lock">
|
||||
<v-icon color="white">
|
||||
mdi-lock
|
||||
</v-icon>
|
||||
</div>
|
||||
<div class="tuc-dc-icon">
|
||||
<img :src="modelValue.icon" alt="constellation">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface TucDetailConstellationProps {
|
||||
modelValue: TGApp.Sqlite.Character.RoleConstellation
|
||||
}
|
||||
|
||||
defineProps<TucDetailConstellationProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-dc-box {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tuc-dc-lock {
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tuc-dc-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
padding: 5px;
|
||||
background: rgb(0 0 0/ 20%);
|
||||
}
|
||||
|
||||
.tuc-dc-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<TucDetailDesc>
|
||||
<template #title>
|
||||
<span>命之座</span>
|
||||
</template>
|
||||
<template #content>
|
||||
<TucDetailConstellation v-model="props.modelValue" />
|
||||
<div class="tuc-ddc-content">
|
||||
<div class="tuc-ddc-top">
|
||||
{{ props.modelValue.name }}
|
||||
</div>
|
||||
<div class="tuc-ddc-bottom">
|
||||
<span>命之座</span>
|
||||
<span>第</span>
|
||||
<span>{{ props.modelValue.pos }}</span>
|
||||
<span>层</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #desc>
|
||||
<span>{{ props.modelValue.description }}</span>
|
||||
</template>
|
||||
</TucDetailDesc>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import TucDetailDesc from "./tuc-detail-desc.vue";
|
||||
import TucDetailConstellation from "./tuc-detail-constellation.vue";
|
||||
|
||||
interface TucDetailDescConstellationProps {
|
||||
modelValue: TGApp.Sqlite.Character.RoleConstellation;
|
||||
}
|
||||
|
||||
const props = defineProps<TucDetailDescConstellationProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-ddc-top {
|
||||
margin-left: 15px;
|
||||
color: var(--common-color-blue-2);
|
||||
}
|
||||
|
||||
.tuc-ddc-bottom {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.tuc-ddc-bottom :nth-child(1) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.tuc-ddc-bottom :nth-child(3) {
|
||||
color: var(--common-color-yellow);
|
||||
}
|
||||
</style>
|
||||
74
src/components/userCharacter/tuc-detail-desc-weapon.vue
Normal file
74
src/components/userCharacter/tuc-detail-desc-weapon.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<TucDetailDesc>
|
||||
<template #title>
|
||||
<span>武器</span>
|
||||
</template>
|
||||
<template #content>
|
||||
<TucDetailItemBox v-model="box" />
|
||||
<div class="tuc-ddw-content">
|
||||
<div class="tuc-ddwc-top">
|
||||
<span>{{ props.modelValue.name }}</span>
|
||||
<span>Lv.{{ props.modelValue.level }}</span>
|
||||
<span>精炼</span>
|
||||
<span>{{ props.modelValue.affix }}</span>
|
||||
<span>阶</span>
|
||||
</div>
|
||||
<div class="tuc-ddwc-bottom">
|
||||
<img :src="`/icon/star/${props.modelValue.star}.webp`" alt="star">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #desc>
|
||||
<span>{{ props.modelValue.description }}</span>
|
||||
</template>
|
||||
</TucDetailDesc>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { computed } from "vue";
|
||||
import TucDetailDesc from "./tuc-detail-desc.vue";
|
||||
import TucDetailItemBox from "./tuc-detail-itembox.vue";
|
||||
|
||||
interface TucDetailDescWeaponProps {
|
||||
modelValue: TGApp.Sqlite.Character.RoleWeapon;
|
||||
}
|
||||
|
||||
const props = defineProps<TucDetailDescWeaponProps>();
|
||||
const box = computed(() => {
|
||||
return {
|
||||
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
|
||||
icon: `/WIKI/weapon/icon/${props.modelValue.id}.webp`,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-ddw-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tuc-ddwc-top {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.tuc-ddwc-top span {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.tuc-ddwc-top :nth-child(2),
|
||||
.tuc-ddwc-top :nth-child(4) {
|
||||
color: var(--common-color-yellow);
|
||||
}
|
||||
|
||||
.tuc-ddwc-bottom {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.tuc-ddwc-bottom img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
63
src/components/userCharacter/tuc-detail-desc.vue
Normal file
63
src/components/userCharacter/tuc-detail-desc.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="tuc-dd-box">
|
||||
<div class="tuc-dd-title">
|
||||
<slot name="title" />
|
||||
</div>
|
||||
<div class="tuc-dd-divider" />
|
||||
<div class="tuc-dd-content">
|
||||
<slot name="content" />
|
||||
</div>
|
||||
<div class="tuc-dd-desc">
|
||||
<slot name="desc" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="css" scoped>
|
||||
.tuc-dd-box {
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
border: 2px solid var(--common-color-grey-2);
|
||||
background: rgb(255 255 255 / 40%);
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.tuc-dd-title {
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
color: var(--common-color-blue);
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tuc-dd-divider {
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: var(--common-color-grey);
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.tuc-dd-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.tuc-dd-desc {
|
||||
font-family: var(--font-text);
|
||||
font-size: 14px;
|
||||
margin-top: 5px;
|
||||
color: var(--common-color-black);
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
word-break: break-all;
|
||||
max-height: 50px;
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
53
src/components/userCharacter/tuc-detail-itembox.vue
Normal file
53
src/components/userCharacter/tuc-detail-itembox.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="tuc-dib-box">
|
||||
<div v-if="modelValue.bg" class="tuc-dib-bg">
|
||||
<img :src="modelValue.bg" alt="bg">
|
||||
</div>
|
||||
<div v-if="modelValue.icon" class="tuc-dib-icon">
|
||||
<img :src="modelValue.icon" alt="icon">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
interface TucDetailItemBoxProps {
|
||||
modelValue: {
|
||||
icon?: string,
|
||||
bg?: string,
|
||||
};
|
||||
}
|
||||
|
||||
defineProps<TucDetailItemBoxProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-dib-box {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tuc-dib-bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tuc-dib-bg img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.tuc-dib-icon {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tuc-dib-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
226
src/components/userCharacter/tuc-detail-overlay.vue
Normal file
226
src/components/userCharacter/tuc-detail-overlay.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<TOverlay v-model="visible" hide :to-click="onCancel">
|
||||
<div class="tuc-do-box">
|
||||
<div class="tuc-do-bg">
|
||||
<img :src="props.dataVal.img" alt="role">
|
||||
</div>
|
||||
<div class="tuc-do-quote">
|
||||
*所有数据以游戏内为准,此处仅供参考
|
||||
</div>
|
||||
<div v-if="data" class="tuc-do-show">
|
||||
<!-- 左侧武器跟圣遗物 -->
|
||||
<div class="tuc-do-left">
|
||||
<div class="tuc-dol-item" @click="showDetail(data.weapon,'武器')">
|
||||
<TucDetailItemBox v-model="weaponBox" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧环状排列6个命座 -->
|
||||
<div class="tuc-do-right">
|
||||
<div class="tuc-dor-box">
|
||||
<TucDetailConstellation
|
||||
v-for="item in data.constellation"
|
||||
class="tuc-dor-item"
|
||||
:model-value="item"
|
||||
@click="showDetail(item, '命座')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 底部说明 -->
|
||||
<div class="tuc-do-bottom">
|
||||
<TucDetailDescWeapon v-if="selected.type === '武器'" v-model="selected.data" />
|
||||
<TucDetailDescConstellation v-else-if="selected.type === '命座'" v-model="selected.data" />
|
||||
<!-- <TucDetailDescRelic v-else-if="selected.type === '圣遗物'" v-model="selected.data" />-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// vue
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import TOverlay from "../main/t-overlay.vue";
|
||||
import TucDetailDescWeapon from "./tuc-detail-desc-weapon.vue";
|
||||
import TucDetailDescConstellation from "./tuc-detail-desc-constellation.vue";
|
||||
// import TucDetailDescRelic from "./tuc-detail-desc-relic.vue";
|
||||
import TucDetailItemBox from "./tuc-detail-itembox.vue";
|
||||
import TucDetailConstellation from "./tuc-detail-constellation.vue";
|
||||
|
||||
interface ToUcDetailProps {
|
||||
modelValue: boolean;
|
||||
dataVal: TGApp.Sqlite.Character.UserRole;
|
||||
}
|
||||
|
||||
interface ToUcDetailEmits {
|
||||
(e: "update:modelValue", value: TGApp.Sqlite.Character.UserRole): void;
|
||||
|
||||
(e: "cancel"): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<ToUcDetailEmits>();
|
||||
const props = withDefaults(defineProps<ToUcDetailProps>(), {
|
||||
modelValue: false,
|
||||
dataVal: {} as TGApp.Sqlite.Character.UserRole,
|
||||
});
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emits("update:modelValue", value),
|
||||
});
|
||||
|
||||
// data
|
||||
const data = ref({
|
||||
weapon: {} as TGApp.Sqlite.Character.RoleWeapon,
|
||||
constellation: [] as TGApp.Sqlite.Character.RoleConstellation[],
|
||||
reliquary: [] as TGApp.Sqlite.Character.RoleReliquary[],
|
||||
});
|
||||
const selected = ref({
|
||||
data: {} as TGApp.Sqlite.Character.RoleConstellation
|
||||
| TGApp.Sqlite.Character.RoleWeapon
|
||||
| TGApp.Sqlite.Character.RoleReliquary,
|
||||
type: "武器" || "命之座" || "圣遗物",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
data.value = {
|
||||
weapon: JSON.parse(props.dataVal.weapon) as TGApp.Sqlite.Character.RoleWeapon,
|
||||
constellation: JSON.parse(props.dataVal.constellation) as TGApp.Sqlite.Character.RoleConstellation[],
|
||||
reliquary: [],
|
||||
};
|
||||
if (props.dataVal.reliquary) {
|
||||
data.value.reliquary = JSON.parse(props.dataVal.reliquary) as TGApp.Sqlite.Character.RoleReliquary[];
|
||||
}
|
||||
selected.value = {
|
||||
data: data.value.weapon,
|
||||
type: "武器",
|
||||
};
|
||||
});
|
||||
|
||||
const weaponBox = computed(() => {
|
||||
const weapon = data.value.weapon;
|
||||
return {
|
||||
icon: `/WIKI/weapon/icon/${weapon.id}.webp`,
|
||||
bg: `/icon/bg/${weapon.star}-Star.webp`,
|
||||
};
|
||||
});
|
||||
|
||||
const onCancel = () => {
|
||||
visible.value = false;
|
||||
emits("cancel");
|
||||
};
|
||||
|
||||
function showDetail (item: TGApp.Sqlite.Character.RoleConstellation | TGApp.Sqlite.Character.RoleWeapon | TGApp.Sqlite.Character.RoleReliquary, type: string) {
|
||||
selected.value = {
|
||||
data: item,
|
||||
type,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-do-box {
|
||||
position: relative;
|
||||
width: 500px;
|
||||
height: 620px;
|
||||
background: rgb(255 255 255 / 30%);
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tuc-do-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tuc-do-bg img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tuc-do-quote {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
right: 5px;
|
||||
font-family: var(--font-text);
|
||||
font-size: 12px;
|
||||
color: var(--common-color-yellow);
|
||||
}
|
||||
|
||||
.tuc-do-show {
|
||||
position: absolute;
|
||||
width: calc(100% - 20px);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.tuc-do-left {
|
||||
width: 50%;
|
||||
height: 400px;
|
||||
//background: rgb(255 255 255 / 30%);
|
||||
}
|
||||
|
||||
.tuc-do-right {
|
||||
width: 50%;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.tuc-do-bottom {
|
||||
width: 480px;
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
/* 左侧显示区域 */
|
||||
.tuc-dol-item {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tuc-dol-item:nth-child(1) {
|
||||
top: 30px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.tuc-dor-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tuc-dor-item {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* 环状排列6个命座 */
|
||||
.tuc-dor-item:nth-child(1) {
|
||||
top: 0;
|
||||
right: 100px;
|
||||
}
|
||||
|
||||
.tuc-dor-item:nth-child(2) {
|
||||
top: 50px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
.tuc-dor-item:nth-child(3) {
|
||||
top: 130px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.tuc-dor-item:nth-child(4) {
|
||||
bottom: 130px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.tuc-dor-item:nth-child(5) {
|
||||
bottom: 50px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
.tuc-dor-item:nth-child(6) {
|
||||
bottom: 0;
|
||||
right: 100px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,19 +1,23 @@
|
||||
<template>
|
||||
<div class="tuc-rb-box">
|
||||
<div class="tuc-rb-box" @click="visible = true">
|
||||
<div class="tuc-rb-top">
|
||||
<TItemBox v-model="avatarBox" @click="showAvatarData" />
|
||||
<TItemBox v-model="weaponBox" @click="showWeaponData" />
|
||||
<TItemBox v-model="avatarBox" />
|
||||
<TItemBox v-model="weaponBox" />
|
||||
</div>
|
||||
</div>
|
||||
<ToUcDetail v-model="visible" :data-val="props.modelValue" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
// vue
|
||||
import { computed, ref } from "vue";
|
||||
import TItemBox from "../main/t-itembox.vue";
|
||||
import ToUcDetail from "./tuc-detail-overlay.vue";
|
||||
|
||||
interface TucRoleBoxProps {
|
||||
modelValue: TGApp.Sqlite.Character.UserRole;
|
||||
}
|
||||
|
||||
const visible = ref(false);
|
||||
const props = defineProps<TucRoleBoxProps>();
|
||||
const avatarBox = computed(() => {
|
||||
return {
|
||||
@@ -56,15 +60,6 @@ function getAvatarName () {
|
||||
: props.modelValue.name
|
||||
);
|
||||
}
|
||||
|
||||
function showAvatarData () {
|
||||
console.log(avatarBox.value);
|
||||
}
|
||||
|
||||
function showWeaponData () {
|
||||
const weapon = JSON.parse(props.modelValue.weapon) as TGApp.Sqlite.Character.RoleWeapon;
|
||||
console.log(weapon);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuc-rb-box {
|
||||
|
||||
Reference in New Issue
Block a user