mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-04-11 08:23:22 +08:00
♻️ 重构留影叙佳期页面,处理部分文本加载异常
This commit is contained in:
139
src/components/pageArchive/pac-birth-card.vue
Normal file
139
src/components/pageArchive/pac-birth-card.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<!-- 留影叙佳期页面卡片 -->
|
||||
<template>
|
||||
<div class="pac-bc-box">
|
||||
<div class="pac-bc-cover" @click="handleClick()">
|
||||
<div class="pac-bc-img">
|
||||
<TMiImg
|
||||
v-if="!props.isAether"
|
||||
:alt="item.word_text"
|
||||
:ori="true"
|
||||
:src="item.unread_picture[0]"
|
||||
/>
|
||||
<TMiImg v-else :alt="item.word_text" :ori="true" :src="item.unread_picture[1]" />
|
||||
</div>
|
||||
<div class="pac-bc-hide" />
|
||||
<v-icon class="pac-bc-icon">mdi-magnify</v-icon>
|
||||
</div>
|
||||
<div class="pac-bc-info">
|
||||
<div class="pac-bc-title">
|
||||
<span>{{ item.year }}/{{ item.birthday }}</span>
|
||||
<span>{{ item.role_name }}</span>
|
||||
</div>
|
||||
<div :title="item.word_text" class="pac-bc-desc">{{ item.word_text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
type PacBirthCardProps = {
|
||||
/** 元数据 */
|
||||
item: TGApp.Archive.Birth.DrawItem;
|
||||
/**是否为空 */
|
||||
isAether: boolean;
|
||||
};
|
||||
type PacBirthCardEmits = (e: "open") => void;
|
||||
const props = defineProps<PacBirthCardProps>();
|
||||
const emits = defineEmits<PacBirthCardEmits>();
|
||||
|
||||
function handleClick(): void {
|
||||
emits("open");
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pac-bc-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: fit-content;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
row-gap: 4px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.pac-bc-cover {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
border-radius: 4px;
|
||||
aspect-ratio: 125 / 54;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pac-bc-img {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pac-bc-hide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
background: var(--common-shadow-t-2);
|
||||
}
|
||||
|
||||
.pac-bc-cover img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.pac-bc-cover:hover {
|
||||
img {
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transform: scale(1.2);
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.pac-bc-hide {
|
||||
background: var(--common-shadow-2);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.pac-bc-info {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pac-bc-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--common-text-title);
|
||||
column-gap: 8px;
|
||||
font-family: var(--font-title);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.pac-bc-desc {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
color: var(--tgc-od-white);
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,38 +1,35 @@
|
||||
<!-- 留影叙佳期浮窗 TODO 左右SLOT -->
|
||||
<template>
|
||||
<TOverlay v-model="visible" blur-val="5px">
|
||||
<div class="toab-container" v-if="props.data">
|
||||
<div class="toab-img">
|
||||
<TMiImg :ori="true" :src="props.data.take_picture[Number(props.choice)]" alt="顶部图像" />
|
||||
<div class="toab-dialog" v-show="showText">
|
||||
<div v-for="(item, index) in textParse" :key="index" class="toab-dialog-item">
|
||||
<div class="toab-dialog-item-icon" v-if="item.icon" :title="item.name">
|
||||
<TMiImg :src="item.icon" alt="对白头像" :ori="true" />
|
||||
</div>
|
||||
<div v-else-if="item.name !== '未知'" class="toab-dialog-item-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div
|
||||
:class="{
|
||||
'toab-dialog-item-text': item.icon !== undefined,
|
||||
'toab-dialog-item-text-mini': item.icon === undefined,
|
||||
}"
|
||||
>
|
||||
{{ item.text }}
|
||||
</div>
|
||||
<div class="pao-bc-container">
|
||||
<div v-if="props.data" class="pao-bc-cover">
|
||||
<TMiImg v-if="props.choice" :ori="true" :src="props.data.take_picture[1]" alt="顶部图像" />
|
||||
<TMiImg v-else :ori="true" :src="props.data.take_picture[0]" alt="顶部图像" />
|
||||
</div>
|
||||
<div v-show="showText" class="pao-bc-comments">
|
||||
<div v-for="(item, index) in textParse" :key="index" class="pao-bc-comment">
|
||||
<div v-if="item.icon" :title="item.name" class="pao-bcc-icon">
|
||||
<TMiImg :ori="true" :src="item.icon" alt="对白头像" />
|
||||
</div>
|
||||
<div v-else-if="item.name !== '未知'" class="pao-bcc-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div :class="item.icon ? 'pao-bcc-text' : 'pao-bcc-quote'">
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toab-top-tools">
|
||||
<v-icon @click="onCopy" title="复制到剪贴板">mdi-content-copy</v-icon>
|
||||
<v-icon @click="onDownload" title="下载到本地">mdi-download</v-icon>
|
||||
<v-icon @click="loadText" :title="showText ? '隐藏对白' : '显示对白'">
|
||||
<div class="pao-bc-top-tools">
|
||||
<v-icon title="复制到剪贴板" @click="onCopy">mdi-content-copy</v-icon>
|
||||
<v-icon title="下载到本地" @click="onDownload">mdi-download</v-icon>
|
||||
<v-icon :title="showText ? '隐藏对白' : '显示对白'" @click="showComments()">
|
||||
{{ showText ? "mdi-eye-off" : "mdi-eye" }}
|
||||
</v-icon>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import TOverlay from "@comp/app/t-overlay.vue";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
@@ -54,14 +51,25 @@ const showText = ref<boolean>(false);
|
||||
const buffer = shallowRef<ArrayBuffer | null>(null);
|
||||
const textParse = shallowRef<Array<XmlTextParse>>([]);
|
||||
|
||||
onMounted(() => clearData());
|
||||
watch(() => props.data, clearData);
|
||||
watch(() => props.choice, clearData);
|
||||
onMounted(async () => await clearData());
|
||||
watch(
|
||||
() => [props.data, props.choice],
|
||||
async () => await clearData(),
|
||||
);
|
||||
watch(
|
||||
() => showText.value,
|
||||
async () => {
|
||||
if (showText.value) await loadText();
|
||||
else textParse.value = [];
|
||||
},
|
||||
);
|
||||
|
||||
function clearData(): void {
|
||||
async function clearData(): Promise<void> {
|
||||
buffer.value = null;
|
||||
textParse.value = [];
|
||||
showText.value = false;
|
||||
if (showText.value) {
|
||||
textParse.value = [];
|
||||
await loadText();
|
||||
}
|
||||
}
|
||||
|
||||
async function onCopy(): Promise<void> {
|
||||
@@ -82,6 +90,10 @@ async function onDownload(): Promise<void> {
|
||||
showSnackbar.success(`图片已下载到本地,大小:${size}`);
|
||||
}
|
||||
|
||||
function showComments(): void {
|
||||
showText.value = !showText.value;
|
||||
}
|
||||
|
||||
async function loadText(): Promise<void> {
|
||||
if (!props.data) return;
|
||||
if (textParse.value.length > 0) {
|
||||
@@ -95,13 +107,14 @@ async function loadText(): Promise<void> {
|
||||
}
|
||||
const keyMap = getKeyMap(resSource);
|
||||
const resXml: unknown = await parseXml(props.data.gal_xml);
|
||||
console.log(resXml);
|
||||
const textList = getTextList(resXml);
|
||||
console.log(textList);
|
||||
textParse.value = textList.map((item) => {
|
||||
const key = keyMap.find((keyItem) => keyItem.id === item.img);
|
||||
if (!key) return { name: "未知", text: item.text };
|
||||
return { name: key.group ?? key.id, text: item.text, icon: key.icon };
|
||||
});
|
||||
showText.value = true;
|
||||
}
|
||||
|
||||
function getKeyMap(resSource: unknown): Array<XmlKeyMap> {
|
||||
@@ -124,6 +137,7 @@ function getKeyMap(resSource: unknown): Array<XmlKeyMap> {
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: 重构文本解析||调整渲染方式
|
||||
function getTextList(resXml: unknown): Array<XmlTextList> {
|
||||
const res: Array<XmlTextList> = [];
|
||||
if (!resXml || typeof resXml !== "object") return res;
|
||||
@@ -143,7 +157,11 @@ function getTextList(resXml: unknown): Array<XmlTextList> {
|
||||
if (!("chara" in attr) || !("img" in attr)) continue;
|
||||
if (item.name !== "simple_dialog") continue;
|
||||
const img = props.choice ? attr.img : attr.img.replace("aether", "lumine");
|
||||
res.push({ chara: attr.chara, img: img, text: item.elements[0].text });
|
||||
let findText = "";
|
||||
const arr5 = item.elements[0].elements;
|
||||
if (arr5 && arr5.length > 0 && arr5[0].text !== "") findText = arr5[0].text;
|
||||
else findText = item.elements[0].text;
|
||||
res.push({ chara: attr.chara, img: img, text: findText });
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -164,90 +182,105 @@ async function parseXml(link: string): Promise<false | unknown> {
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.toab-container {
|
||||
.pao-bc-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 50vw;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
aspect-ratio: 125 / 54;
|
||||
background: var(--app-page-bg);
|
||||
}
|
||||
|
||||
.toab-img {
|
||||
.pao-bc-cover {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.toab-img img {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.toab-top-tools {
|
||||
.pao-bc-comments {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
-webkit-backdrop-filter: blur(2px);
|
||||
backdrop-filter: blur(2px);
|
||||
background: var(--common-shadow-t-2);
|
||||
color: var(--box-text-1);
|
||||
overflow-y: auto;
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.pao-bc-comment {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
column-gap: 4px;
|
||||
}
|
||||
|
||||
.pao-bcc-icon {
|
||||
position: relative;
|
||||
width: 40px;
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.pao-bcc-name {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pao-bcc-text {
|
||||
font-size: 16px;
|
||||
text-shadow: 0 0 2px var(--common-shadow-t-8);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pao-bcc-quote {
|
||||
margin-left: 3rem;
|
||||
font-size: 1rem;
|
||||
opacity: 0.8;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pao-bc-top-tools {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(2px);
|
||||
backdrop-filter: blur(2px);
|
||||
background-color: var(--common-shadow-t-2);
|
||||
border-bottom-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
.toab-dialog {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 40vh;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
border-radius: 10px;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
backdrop-filter: blur(5px);
|
||||
background: var(--common-shadow-t-2);
|
||||
color: var(--box-text-1);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.toab-dialog-item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.toab-dialog-item-icon {
|
||||
width: 50px;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.toab-dialog-item-name {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toab-dialog-item-text {
|
||||
font-size: 1.2rem;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.toab-dialog-item-text-mini {
|
||||
margin-left: 3rem;
|
||||
font-size: 1rem;
|
||||
opacity: 0.8;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
@@ -1,42 +1,60 @@
|
||||
<!-- 留影叙佳期 -->
|
||||
<template>
|
||||
<div class="ab-container">
|
||||
<div class="ab-draw-top">
|
||||
<div @click="toAct" class="ab-draw-act" title="前往网页活动">
|
||||
<img src="/source/UI/act_birthday.webp" alt="archive_birthday_icon" class="side-icon" />
|
||||
<v-app-bar>
|
||||
<div class="ab-top">
|
||||
<div class="ab-title">
|
||||
<img alt="archive_birthday_icon" src="/source/UI/act_birthday.webp" @click="toAct()" />
|
||||
<span>留影叙佳期</span>
|
||||
</div>
|
||||
<div class="ab-switch">
|
||||
<span>{{ isAether ? "空" : "荧" }}</span>
|
||||
<v-switch
|
||||
v-model="isAether"
|
||||
class="ab-switch-btn"
|
||||
color="var(--tgc-od-orange)"
|
||||
density="compact"
|
||||
/>
|
||||
</div>
|
||||
<v-switch class="ab-draw-switch" v-model="isAether" />
|
||||
<span>{{ isAether ? "空" : "荧" }}</span>
|
||||
<v-select
|
||||
v-model="curSelect"
|
||||
class="ab-select"
|
||||
:items="ArcBirRole"
|
||||
clearable
|
||||
variant="outlined"
|
||||
label="角色"
|
||||
:item-value="(item: TGApp.Archive.Birth.RoleItem) => item"
|
||||
:hide-details="true"
|
||||
:item-props="(item: TGApp.Archive.Birth.RoleItem) => getItemProps(item)"
|
||||
:item-value="(item: TGApp.Archive.Birth.RoleItem) => item"
|
||||
:items="ArcBirRole"
|
||||
class="ab-select"
|
||||
clearable
|
||||
density="compact"
|
||||
label="角色"
|
||||
variant="outlined"
|
||||
/>
|
||||
</div>
|
||||
<div class="ab-draw-grid">
|
||||
<div v-for="item in selectedItem" :key="item.op_id" class="ab-draw">
|
||||
<div class="ab-draw-cover" @click="showImg(item)">
|
||||
<div class="ab-draw-img">
|
||||
<TMiImg :src="item.unread_picture[Number(isAether)]" :alt="item.word_text" />
|
||||
</div>
|
||||
<div class="ab-draw-hide" />
|
||||
<v-icon class="ab-draw-icon">mdi-magnify</v-icon>
|
||||
</div>
|
||||
<div class="ab-di-info">{{ item.year }} {{ item.birthday }} {{ item.role_name }}</div>
|
||||
<div class="ab-di-text" :title="item.word_text">{{ item.word_text }}</div>
|
||||
<template #append>
|
||||
<div class="ab-top-append">
|
||||
<v-pagination
|
||||
v-model="page"
|
||||
:length="length"
|
||||
:total-visible="visible"
|
||||
density="compact"
|
||||
variant="elevated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<v-pagination v-model="page" :length="length" :total-visible="visible" />
|
||||
</template>
|
||||
</v-app-bar>
|
||||
<div class="ab-grid-container">
|
||||
<PacBirthCard
|
||||
v-for="item in selectedItem"
|
||||
:key="item.op_id"
|
||||
:isAether
|
||||
:item
|
||||
@open="showImg(item)"
|
||||
/>
|
||||
</div>
|
||||
<ToArcBrith v-model="showOverlay" :data="current" :choice="isAether" />
|
||||
<!-- TODO: 左右SLOT -->
|
||||
<ToArcBrith v-model="showOverlay" :choice="isAether" :data="current" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import ToArcBrith from "@comp/pageArchive/to-arcBrith.vue";
|
||||
import PacBirthCard from "@comp/pageArchive/pac-birth-card.vue";
|
||||
import ToArcBrith from "@comp/pageArchive/pao-birth-card.vue";
|
||||
import TGClient from "@utils/TGClient.js";
|
||||
import { computed, onMounted, ref, shallowRef, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
@@ -94,152 +112,73 @@ async function toAct(): Promise<void> {
|
||||
function getItemProps(item: TGApp.Archive.Birth.RoleItem) {
|
||||
return {
|
||||
title: `${item.name} ${item.role_birthday}`,
|
||||
subtitle: new DOMParser().parseFromString(item.text, "text/html").body.textContent,
|
||||
prependAvatar: item.head_icon,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.ab-container {
|
||||
<style lang="scss" scoped>
|
||||
.ab-top {
|
||||
position: relative;
|
||||
display: flex;
|
||||
margin-left: 16px;
|
||||
column-gap: 24px;
|
||||
}
|
||||
|
||||
.ab-title {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.ab-draw-top {
|
||||
.ab-switch {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
column-gap: 10px;
|
||||
justify-content: center;
|
||||
column-gap: 12px;
|
||||
|
||||
span {
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.ab-switch-btn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.ab-draw-act {
|
||||
cursor: pointer;
|
||||
.ab-select {
|
||||
position: relative;
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.ab-draw-act img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
transition: all 0.3s ease-in-out;
|
||||
.ab-top-append {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.ab-draw-switch {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ab-draw-grid {
|
||||
.ab-grid-container {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.ab-draw {
|
||||
display: flex;
|
||||
height: fit-content;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw-cover {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
border-radius: 5px;
|
||||
aspect-ratio: 125 / 54;
|
||||
}
|
||||
|
||||
.ab-draw-img {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ab-draw-hide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
backdrop-filter: blur(5px);
|
||||
background: var(--common-shadow-t-2);
|
||||
}
|
||||
|
||||
.ab-draw-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
color: var(--common-shadow-8);
|
||||
font-size: 30px;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw-cover img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw-act img:hover {
|
||||
transform: scale(1.1);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw:hover img {
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transform: scale(1.1);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw:hover .ab-draw-hide {
|
||||
-webkit-backdrop-filter: blur(0);
|
||||
backdrop-filter: blur(0);
|
||||
background: var(--common-shadow-2);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-draw:hover .ab-draw-icon {
|
||||
color: var(--common-shadow-t-4);
|
||||
cursor: pointer;
|
||||
scale: 2;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.ab-di-info {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ab-di-text {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
opacity: 0.8;
|
||||
grid-template-rows: repeat(3, 1fr);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user