🌱 角色详情页 overlay 草创

This commit is contained in:
BTMuli
2023-06-16 23:31:53 +08:00
parent 0d7ed8d239
commit 0a34f4e483
7 changed files with 532 additions and 13 deletions

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -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 {