mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-28 05:59:46 +08:00
💄 深境螺旋UI迭代
This commit is contained in:
@@ -1,25 +1,38 @@
|
||||
<!-- 战斗组件 -->
|
||||
<template>
|
||||
<div class="tud-db-box">
|
||||
<div class="tud-db-time">{{ props.title }} {{ props.modelValue.time }}</div>
|
||||
<div class="tud-db-icons-grid">
|
||||
<div class="tua-db-box">
|
||||
<div class="tua-db-time">{{ props.title }} {{ props.battle.time }}</div>
|
||||
<div v-if="props.battle.monsters && props.battle.monsters.length > 0" class="tua-db-monsters">
|
||||
<div v-for="(monster, idx) in props.battle.monsters" :key="idx" class="tua-db-monster">
|
||||
<div class="icon">
|
||||
<TMiImg :ori="true" :src="monster.icon" alt="icon" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<span>{{ monster.name }}</span>
|
||||
<span>Lv.{{ monster.level }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tua-db-grid">
|
||||
<TItemBox
|
||||
v-for="avatar in props.modelValue.characters"
|
||||
v-for="avatar in props.battle.characters"
|
||||
:key="avatar.id"
|
||||
:model-value="getBoxData(avatar)"
|
||||
:model-value="getAvatarBox(avatar)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
import { AppCharacterData } from "@/data/index.js";
|
||||
|
||||
type TuaDetailBattleProps = { title: string; modelValue: TGApp.Sqlite.Abyss.Battle };
|
||||
type TuaDetailBattleProps = { title: string; battle: TGApp.Sqlite.Abyss.Battle };
|
||||
|
||||
const props = defineProps<TuaDetailBattleProps>();
|
||||
|
||||
function getBoxData(avatar: TGApp.Sqlite.Abyss.CharacterInfo): TItemBoxData {
|
||||
function getAvatarBox(avatar: TGApp.Sqlite.Abyss.CharacterInfo): TItemBoxData {
|
||||
const res = AppCharacterData.find((i) => i.id === avatar.id);
|
||||
if (avatar.id === 10000005 || avatar.id === 10000007) {
|
||||
return {
|
||||
@@ -49,18 +62,80 @@ function getBoxData(avatar: TGApp.Sqlite.Abyss.CharacterInfo): TItemBoxData {
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tud-db-icons-grid {
|
||||
<style lang="scss" scoped>
|
||||
.tua-db-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.tua-db-time {
|
||||
color: var(--box-text-2);
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tua-db-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tud-db-time {
|
||||
color: var(--box-text-1);
|
||||
font-size: 12px;
|
||||
opacity: 0.6;
|
||||
text-align: left;
|
||||
.tua-db-monsters {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-wrap: wrap-reverse;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tua-db-monster {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px 12px 4px 4px;
|
||||
border-radius: 40px;
|
||||
background: var(--box-bg-3);
|
||||
color: var(--box-text-4);
|
||||
column-gap: 4px;
|
||||
|
||||
.icon {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
background: var(--box-bg-4);
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
|
||||
span {
|
||||
line-height: 14px;
|
||||
|
||||
&:first-child {
|
||||
font-family: var(--font-title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,40 +1,78 @@
|
||||
<!-- 关卡组件 -->
|
||||
<template>
|
||||
<div class="tua-dl-box">
|
||||
<TuaDetailTitle
|
||||
:val="props.modelValue.winStar"
|
||||
:name="`第${props.modelValue.id}间`"
|
||||
mode="level"
|
||||
/>
|
||||
<TuaDetailBattle
|
||||
v-if="props.modelValue.upBattle"
|
||||
title="上半"
|
||||
:model-value="props.modelValue.upBattle"
|
||||
/>
|
||||
<TuaDetailBattle
|
||||
v-if="props.modelValue.downBattle"
|
||||
title="下半"
|
||||
:model-value="props.modelValue.downBattle"
|
||||
/>
|
||||
<div class="tua-dl-title">
|
||||
<div class="title">第{{ props.level.id }}间</div>
|
||||
<div class="star">
|
||||
<img
|
||||
v-for="(i, idx) in genStarList()"
|
||||
:key="idx"
|
||||
:src="`/icon/star/abyss${i}.webp`"
|
||||
alt="icon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<TuaDetailBattle v-if="props.level.upBattle" :battle="props.level.upBattle" title="上半" />
|
||||
<TuaDetailBattle v-if="props.level.downBattle" :battle="props.level.downBattle" title="下半" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TuaDetailBattle from "./tua-detail-battle.vue";
|
||||
import TuaDetailTitle from "./tua-detail-title.vue";
|
||||
|
||||
type TuaDetailLevelProps = { modelValue: TGApp.Sqlite.Abyss.Level };
|
||||
type TuaDetailLevelProps = { level: TGApp.Sqlite.Abyss.Level };
|
||||
|
||||
const props = defineProps<TuaDetailLevelProps>();
|
||||
|
||||
function genStarList(): Array<number> {
|
||||
const arr: Array<number> = [];
|
||||
for (let i = 0; i < props.level.maxStar; i++) {
|
||||
if (i < props.level.winStar) arr.push(1);
|
||||
else arr.push(0);
|
||||
}
|
||||
return arr.reverse();
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tua-dl-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--common-shadow-1);
|
||||
border-radius: 4px;
|
||||
margin-top: 8px;
|
||||
background: var(--box-bg-2);
|
||||
gap: 8px;
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.tua-dl-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
column-gap: 12px;
|
||||
|
||||
.title {
|
||||
color: var(--box-text-4);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.star {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
column-gap: 4px;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 2px;
|
||||
border-radius: 50%;
|
||||
background: #2c313c;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<div class="tud-t-box">
|
||||
<div class="tud-t-title">
|
||||
<slot name="title">{{ props.name }}</slot>
|
||||
</div>
|
||||
<div class="tud-t-val">
|
||||
<img src="/icon/star/Abyss.webp" alt="Abyss" />
|
||||
<slot name="val">{{ props.val }}</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
type TuaDetailTitleProps = { name: string; val: number; mode: "floor" | "level" };
|
||||
|
||||
const props = defineProps<TuaDetailTitleProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tud-t-box {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--common-shadow-4);
|
||||
font-family: v-bind("props.mode === 'level' ? 'var(--font-text)' : 'var(--font-title)'");
|
||||
}
|
||||
|
||||
.tud-t-title {
|
||||
color: var(--box-text-4);
|
||||
font-size: v-bind("props.mode === 'level' ? '18px' : '20px'");
|
||||
}
|
||||
|
||||
.tud-t-val {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--tgc-yellow-1);
|
||||
font-family: var(--font-title);
|
||||
font-size: v-bind("props.mode === 'level' ? '18px' : '20px'");
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.tud-t-val img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 1px;
|
||||
filter: invert(22%) sepia(7%) saturate(1241%) hue-rotate(182deg) brightness(95%) contrast(99%);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.dark .tud-t-val img {
|
||||
filter: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,38 +1,89 @@
|
||||
<!-- 楼层组件 -->
|
||||
<template>
|
||||
<div class="tuad-box">
|
||||
<TuaDetailTitle
|
||||
:val="props.modelValue.winStar"
|
||||
:name="`第${props.modelValue.id}层`"
|
||||
mode="floor"
|
||||
/>
|
||||
<div class="tuad-title">
|
||||
<div class="title">第{{ props.floor.id }}层</div>
|
||||
<div class="append">
|
||||
<span>{{ props.floor.winStar }}</span>
|
||||
<span>/{{ props.floor.maxStar }}</span>
|
||||
<img alt="Abyss" src="/icon/star/Abyss.webp" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="props.floor.buff && props.floor.buff.length > 0" class="tuad-buff">
|
||||
<span>地脉异常:</span>
|
||||
<span v-for="(b, i) in props.floor.buff" :key="i">{{ b }}</span>
|
||||
</div>
|
||||
<div class="tuad-index-box">
|
||||
<TuaDetailLevel
|
||||
v-for="level in props.modelValue.levels"
|
||||
:key="level.id"
|
||||
:model-value="level"
|
||||
/>
|
||||
<TuaDetailLevel v-for="level in props.floor.levels" :key="level.id" :level />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TuaDetailLevel from "./tua-detail-level.vue";
|
||||
import TuaDetailTitle from "./tua-detail-title.vue";
|
||||
|
||||
type TuaDetailProps = { modelValue: TGApp.Sqlite.Abyss.Floor };
|
||||
type TuaDetailProps = { floor: TGApp.Sqlite.Abyss.Floor };
|
||||
|
||||
const props = defineProps<TuaDetailProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tuad-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--box-bg-1);
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.tuad-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid var(--common-shadow-4);
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
|
||||
.append {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
column-gap: 4px;
|
||||
|
||||
span:first-child {
|
||||
color: var(--tgc-od-orange);
|
||||
font-family: var(--font-title);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 2px;
|
||||
border-radius: 50%;
|
||||
background: #2c313c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tuad-buff {
|
||||
position: relative;
|
||||
margin-left: auto;
|
||||
color: var(--box-text-1);
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.tuad-index-box {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-gap: 8px;
|
||||
gap: 8px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- 概览 -->
|
||||
<template>
|
||||
<div class="tuao-box">
|
||||
<div class="tuao-title">
|
||||
@@ -23,15 +24,19 @@ import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
|
||||
import { AppCharacterData } from "@/data/index.js";
|
||||
|
||||
type TAOProps = {
|
||||
/** 标题 */
|
||||
title: string;
|
||||
/**值文本 */
|
||||
valText?: string | number;
|
||||
valIcons?: Array<TGApp.Sqlite.Abyss.Character>;
|
||||
/** 值图标 */
|
||||
valIcons?: Array<TGApp.Sqlite.Abyss.CharacterData>;
|
||||
/* 是否多个 */
|
||||
multi4?: boolean;
|
||||
};
|
||||
|
||||
const props = defineProps<TAOProps>();
|
||||
|
||||
function getBoxData(avatar: TGApp.Sqlite.Abyss.Character): TItemBoxData {
|
||||
function getBoxData(avatar: TGApp.Sqlite.Abyss.CharacterData): TItemBoxData {
|
||||
const res = AppCharacterData.find((a) => a.id === avatar.id);
|
||||
return {
|
||||
height: "80px",
|
||||
@@ -42,6 +47,7 @@ function getBoxData(avatar: TGApp.Sqlite.Abyss.Character): TItemBoxData {
|
||||
lt: `/icon/element/${res?.element ?? "风"}元素.webp`,
|
||||
innerText: avatar.value.toString(),
|
||||
display: "inner",
|
||||
innerBlur: "5px",
|
||||
size: "80px",
|
||||
innerHeight: 20,
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="tuc-ae-flex">
|
||||
<div v-for="(enemy, idx) in props.enemies" :key="idx" class="tuc-enemy">
|
||||
<div class="tuc-enemy-icon">
|
||||
<img :src="enemy.icon" alt="icon" />
|
||||
<TMiImg :ori="true" :src="enemy.icon" alt="icon" />
|
||||
</div>
|
||||
<div class="tuc-enemy-info">
|
||||
<span>{{ enemy.name }}</span>
|
||||
@@ -29,6 +29,7 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TItembox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import { getWikiBrief, getZhElement } from "@utils/toolFunc.js";
|
||||
|
||||
type TucAeBoxProps = {
|
||||
|
||||
Reference in New Issue
Block a user