🌱 角色详情页面初步改造 3/5

#20
This commit is contained in:
BTMuli
2023-11-25 00:05:45 +08:00
parent d6ae3765b6
commit 90242829a9
6 changed files with 320 additions and 40 deletions

View File

@@ -0,0 +1,2 @@
<template></template>
<script lang="ts" setup></script>

View File

@@ -0,0 +1,108 @@
<template>
<div class="ddo-lt-box">
<div class="ddo-ltb-icon" :title="getTitle">
<TItemBox :model-value="boxData" />
</div>
<div class="ddo-ltb-info">
<span>{{ props.data.name }}</span>
<span>Lv.{{ props.data.level }}</span>
<span>{{ info }}</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
type DucDetailOltProps =
| {
data: TGApp.Sqlite.Character.UserRole;
mode: "avatar";
}
| {
data: TGApp.Sqlite.Character.RoleWeapon;
mode: "weapon";
};
const props = defineProps<DucDetailOltProps>();
const getTitle = computed(() => {
if (props.mode === "avatar") {
return `${props.data.name}`;
} else {
// 按照长度折行,一行最多显示 10 个字
const descriptionList = props.data.description.split("");
return descriptionList.reduce((prev: string, cur: string, index: number) => {
if (index % 10 === 0) {
return `${prev}\n${cur}`;
} else {
return `${prev}${cur}`;
}
}, "");
}
});
const boxData = computed<TItemBoxData>(() => {
if (props.mode === "avatar") {
return {
bg: `/icon/bg/${props.data.star}-Star.webp`,
icon: `/WIKI/character/icon/${props.data.cid}.webp`,
size: "100px",
height: "100px",
display: "inner",
innerHeight: 0,
innerText: "",
lt: `/icon/element/${props.data.element}.webp`,
ltSize: "30px",
};
} else {
return {
bg: `/icon/bg/${props.data.star}-Star.webp`,
icon: `/WIKI/weapon/icon/${props.data.id}.webp`,
size: "100px",
height: "100px",
display: "inner",
innerHeight: 0,
innerText: "",
lt: `/icon/weapon/${props.data.type}.webp`,
ltSize: "30px",
};
}
});
const info = computed(() => {
if (props.mode === "avatar") {
return `好感 ${props.data.fetter}`;
} else {
return `精炼 ${props.data.affix}`;
}
});
</script>
<style lang="css" scoped>
.ddo-lt-box {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
column-gap: 10px;
}
.ddo-ltb-info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
color: var(--tgc-white-1);
text-align: left;
}
.ddo-ltb-info :nth-child(1) {
margin-bottom: 10px;
font-family: var(--font-title);
font-size: 20px;
}
.ddo-ltb-info :not(:nth-child(1)) {
font-family: var(--font-text);
font-size: 16px;
opacity: 0.8;
}
</style>

View File

@@ -0,0 +1,2 @@
<template></template>
<script lang="ts" setup></script>

View File

@@ -0,0 +1,179 @@
<template>
<TOverlay v-model="visible" hide :to-click="onOverlayCancel" blur-val="20px">
<div class="duc-do-box">
<!-- 左侧箭头 -->
<div class="duc-arrow-left" @click="handleClick('left')">
<img src="../../assets/icons/arrow-right.svg" alt="left" />
</div>
<!-- 中间内容 -->
<div class="duc-do-container">
<img :src="nameCard" class="duc-doc-bg" v-if="nameCard !== false" alt="bg" />
<div class="duc-doc-bgc" />
<!-- 左上角色跟武器 -->
<div class="duc-doc-lt">
<DucDetailOlt :data="props.dataVal" mode="avatar" />
<DucDetailOlt :data="JSON.parse(props.dataVal.weapon)" mode="weapon" />
</div>
<!-- 右下天赋 -->
<div class="duc-doc-rb">
<DucDetailOrt :data="JSON.parse(props.dataVal.talent)" />
</div>
<!-- 左下命座 -->
<div class="duc-doc-lb">
<DucDetailOlb :data="JSON.parse(props.dataVal.constellation)" />
</div>
</div>
<!-- 右侧箭头 -->
<div class="duc-arrow-right" @click="handleClick('right')">
<img src="../../assets/icons/arrow-right.svg" alt="right" />
</div>
</div>
</TOverlay>
</template>
<script lang="ts" setup>
import { computed, onMounted, onUpdated, ref } from "vue";
import DucDetailOlb from "./duc-detail-olb.vue";
import DucDetailOlt from "./duc-detail-olt.vue";
import DucDetailOrt from "./duc-detail-ort.vue";
import TGSqlite from "../../plugins/Sqlite";
import TOverlay from "../main/t-overlay.vue";
interface DucDetailOverlayProps {
modelValue: boolean;
dataVal: TGApp.Sqlite.Character.UserRole;
}
type DucDetailOverlayEmits = {
(e: "update:modelValue", value: boolean): void;
(e: "clickL"): void;
(e: "clickR"): void;
};
const props = defineProps<DucDetailOverlayProps>();
const emits = defineEmits<DucDetailOverlayEmits>();
const visible = computed({
get: () => props.modelValue,
set: (value) => {
emits("update:modelValue", value);
},
});
// 渲染数据
const nameCard = ref<string | false>(false);
function onOverlayCancel() {
visible.value = false;
emits("update:modelValue", false);
}
function handleClick(pos: "left" | "right") {
pos === "left" ? emits("clickL") : emits("clickR");
}
onMounted(async () => {
await loadData();
});
onUpdated(async () => {
await loadData();
});
async function loadData(): Promise<void> {
if (!props.modelValue) return;
if (props.dataVal.cid !== 10000005 && props.dataVal.cid !== 10000007) {
const role = await TGSqlite.getAppCharacter(props.dataVal.cid);
nameCard.value = `/source/nameCard/profile/${role.nameCard}.webp`;
}
// resetData();
}
</script>
<style lang="css" scoped>
.duc-do-box {
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 10px;
}
.duc-arrow-left,
.duc-arrow-right {
position: relative;
display: flex;
width: 30px;
height: 30px;
align-items: center;
justify-content: center;
cursor: pointer;
}
.dark .duc-arrow-left,
.dark .duc-arrow-right {
filter: invert(11%) sepia(73%) saturate(11%) hue-rotate(139deg) brightness(97%) contrast(81%);
}
.duc-arrow-left img {
width: 100%;
height: 100%;
transform: rotate(180deg);
}
.duc-arrow-right img {
width: 100%;
height: 100%;
}
.duc-do-container {
position: relative;
overflow: hidden;
width: 50vw;
border-radius: 5px;
aspect-ratio: 21 / 10;
background: var(--box-bg-1);
}
.duc-doc-bg {
position: absolute;
right: 0;
left: 0;
width: 100%;
height: 100%;
}
.duc-doc-bgc {
position: absolute;
right: 0;
left: 0;
width: 100%;
height: 100%;
background: rgb(0 0 0 / 20%);
}
.duc-doc-lt {
position: absolute;
top: 10px;
left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 5px;
row-gap: 10px;
}
.duc-doc-rb {
position: absolute;
right: 20px;
bottom: 20px;
width: 100px;
height: 300px;
background: var(--common-shadow-2);
}
.duc-doc-lb {
position: absolute;
bottom: 20px;
left: 20px;
width: 300px;
height: 80px;
background: var(--common-shadow-2);
}
</style>