UI Iteration

This commit is contained in:
mubai
2026-04-07 22:26:41 +08:00
parent 81b43c0790
commit ee4d997066
11 changed files with 471 additions and 279 deletions

View File

@@ -4,7 +4,7 @@
效果展示: <a href="https://m.mubai.link/" target="_blank">点击访问演示站点</a>
新版本测试访问站点: [新版本站点](https://www.mubai.us.ci/)
新版本测试访问站点: [新版本站点](https://www.mubai.cn.mt/) [备用域名](https://m2.mubai.link/)
## 简介
@@ -68,6 +68,7 @@
>
>后续计划:
>
>- 有无前端UI大佬救一救啊, 界面改的没思绪了.
>- 新增功能测试 && buf修复
>- 优化UI组件
>- 针对播放器进行BUG测试优化以及功能完善

View File

@@ -2,40 +2,50 @@
<div class="c_content" v-if="d.list">
<template v-if="d.list.length > 0">
<div class="item film-card" v-for="item in d.list" :style="{width: `calc(${d.width-1}%)`}">
<div v-if="item.id != -99 && global.isMobile" class="hidden-md-and-up">
<a :href="`/filmDetail?link=${item.id}`" class="default_image link_content">
<!--v2测试-->
<!--Wrap-->
<template v-if="global.isMobile && item.id != -99">
<div class="card">
<img class="card-img" :src="item.picture" :alt="item.name?.split('[')[0]" @error="handleImg">
<div class="tag_group">
<span class="cus_tag " v-if="item.cName.replace(/\s/g, '')" >{{ item.cName }}</span>
<span class="cus_tag ">{{ item.year ? item.year.slice(0, 4) : '未知' }}</span>
<span class="cus_tag ">{{ item.cName }}</span>
<span class="cus_tag ">{{ item.area.split(',')[0] }}</span>
</div>
<span class="cus_remark hidden-md-and-up">{{ item.remarks }}</span>
<img :src="item.picture" :alt="item.name?.split('[')[0]" @error="handleImg">
</a>
<a :href="`/filmDetail?link=${item.id}`" class="content_text_tag">{{ item.name.split("[")[0] }}</a>
<span class="cus_remark hidden-md-and-down">{{ item.remarks }}</span>
</div>
<div v-if="!global.isMobile && item.id != -99" class="film-card-inner">
<div class="film-card-front">
<a :href="`/filmDetail?link=${item.id}`" class="link_content">
<div class="tag_group">
<span class="cus_tag ">{{ item.year ? item.year.slice(0, 4) : '未知' }}</span>
<span class="cus_tag ">{{ item.cName }}</span>
<span class="cus_tag ">{{ item.area.split(',')[0] }}</span>
</div>
<span class="cus_remark hidden-md-and-up">{{ item.remarks }}</span>
<img :src="item.picture" :alt="item.name?.split('[')[0]" @error="handleImg">
<a class="card-info" :href="`/filmDetail?link=${item.id}`">
<p class="text-title">{{ item.name }}</p>
<p v-if="item.blurb == '' || item.blurb == '...' " class="text-body"> 暂无简介 </p>
<p v-else class="text-body">{{ item.blurb }}</p>
<el-button class="card-button " :icon="Discount" color="#626aef" plain round @click="toDetail(item.id)">
详情
</el-button>
</a>
</div>
<div class="film-card-back" @click="toDetail(item.id)">
<p class="card-title" >{{item.name}}</p>
<p v-show="item.blurb != ''" class="card-blurb">{{ item.blurb }}</p>
<p v-show="item.blurb == ''" class="card-blurb"> 暂无简介 </p>
<el-button class="card-detail" :icon="Discount" color="#626aef" plain round @click="toDetail(item.id)" >详情</el-button>
<span class="cus_remark">{{ item.remarks }}</span>
<a :href="`/filmDetail?link=${item.id}`" class="card-external-title"
v-if="global.isMobile && item.id != -99">{{ item.name.split("[")[0] }}</a>
</template>
<!--PC-->
<template v-if="!global.isMobile && item.id != -99">
<div class="card">
<img class="card-img" :src="item.picture" :alt="item.name?.split('[')[0]" @error="handleImg">
<div class="tag_group">
<span class="cus_tag ">{{ item.year.replace(/\s/g, '') ? item.year.slice(0, 4) : '未知' }}</span>
<span v-if="item.cName.replace(/\s/g, '')" class="cus_tag ">{{ item.cName }}</span>
<span class="cus_tag ">{{ item.area.replace(/\s/g, '') ? item.area.split(',')[0] : '未知' }}</span>
</div>
<a class="card-info" :href="`/filmDetail?link=${item.id}`">
<p class="text-title">{{ item.name }}</p>
<p v-if="item.blurb == '' || item.blurb == '...' " class="text-body"> 暂无简介 </p>
<p v-else class="text-body">{{ item.blurb }}</p>
<el-button class="card-button " :icon="Discount" color="#626aef" plain round @click="toDetail(item.id)">
详情
</el-button>
</a>
</div>
</div>
<a v-if="!global.isMobile && item.id != -99" :href="`/filmDetail?link=${item.id}`" class="content_text_tag hidden-sm-and-down">{{ item.name.split("[")[0] }}</a>
<span class="cus_remark">{{ item.remarks }}</span>
<a :href="`/filmDetail?link=${item.id}`"
class="content_text_tag">{{ item.name.split("[")[0] }}</a>
</template>
</div>
</template>
@@ -45,7 +55,7 @@
<script setup lang="ts">
import { inject, reactive, watchEffect} from 'vue'
import {inject, reactive, watchEffect} from 'vue'
import {Discount} from "@element-plus/icons-vue";
const props = defineProps({
@@ -61,10 +71,11 @@ const d = reactive({
const global = inject('global')
// 图片加载失败事件
const handleImg = (e: Event) => {
e.target.style.display = "none"
// e.target.style.display = "none"
e.target.src = '/src/assets/image/404.png'
}
const toDetail = (id:any) =>{
const toDetail = (id: any) => {
location.href = `/filmDetail?link=${id}`
}
@@ -88,6 +99,15 @@ watchEffect(() => {
// d.list = l
d.list = l.map((item: any) => {
item.blurb = item.blurb.replace(/<[^>]*>/g, '')
if (item.remarks.match(/\d+/)) {
if (item.remarks.includes("期")) {
item.remarks = `${item.remarks.match(/\d+/)}`
} else if (item.remarks.includes("集")) {
item.remarks = `${item.remarks.match(/\d+/)}`
}
}
// console.log(item.blur)
return item
})
@@ -97,11 +117,6 @@ watchEffect(() => {
</script>
<style scoped>
.default_image {
background: url("/src/assets/image/404.png") no-repeat;
background-size: cover;
}
:deep(.el-empty) {
--el-empty-fill-color-1: rgba(155, 73, 231, 0.72);
--el-empty-fill-color-2: #67d9e891;
@@ -114,11 +129,139 @@ watchEffect(() => {
--el-empty-fill-color-9: rgb(43 51 63 / 44%);
}
.c_content {
max-width: 99%;
}
.card {
width: 100%;
aspect-ratio: 3/4.1;
/* padding: 1.9rem;*/
padding: 0;
background: #f5f5f5;
position: relative;
display: flex;
align-items: flex-end;
box-shadow: 0 7px 20px rgba(43, 8, 37, 0.2);
/* transition: all 0.3s ease-out;*/
transition: transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) 0.1s;
overflow: hidden;
}
.card:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transition: 0.5s;
}
.card-info {
position: relative;
z-index: 3;
color: #f5f5f5cf;
display: flex;
flex-direction: column;
justify-content: flex-end;
opacity: 0;
width: 100%;
height: 115%;
padding-bottom: 16%;
background: rgba(0, 0, 0, 0.5);
transform: translateY(6%);
/* transition: 0.5s;*/
transition: transform 0.8s cubic-bezier(0.165, 0.84, 0.44, 1) 0.1s;
}
/*Text*/
.text-title {
max-width: 80%;
margin: 0 auto;
/* font-size: 1rem;*/
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #FFC570;
}
.text-body {
letter-spacing: 1px;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
/*Button*/
.card-button {
margin: 0 auto;
outline: none;
border: none;
font-weight: bold;
transition: 0.4s ease;
}
/*Image*/
.card-img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
object-fit: cover;
object-position: center;
transition: transform 0.8s ease-out;
}
/*Hover*/
.card:active, .card:hover {
transform: translateY(-2%);
}
.card:hover .card-img {
transform: scale(1.1);
}
.card:hover:before {
opacity: 1;
}
.card:hover .card-info {
z-index: 10;
opacity: 1;
transform: translateY(0);
}
.cus_remark {
position: absolute;
right: -5px;
color: white;
border-radius: 6px 3px 0 6px;
font-weight: bold;
z-index: 2;
}
.cus_remark::after {
content: "";
position: absolute;
width: 0;
height: 0;
border-width: 6px;
border-style: solid;
}
</style>
<style scoped>
/*wrap*/
@media (max-width: 768px) {
/*展示区域*/
.c_content {
width: 100%;
width: 98%;
display: flex;
flex-flow: wrap;
justify-content: space-between;
@@ -127,9 +270,9 @@ watchEffect(() => {
.c_content .item {
/* flex-basis: calc(33% - 7px);
max-width: 33%;*/
position: relative;
margin: 0 4px 20px 4px;
box-sizing: border-box;
overflow: hidden;
}
.item .link_content {
@@ -141,18 +284,52 @@ watchEffect(() => {
background-size: cover;
}
img {
position: absolute;
top: 0;
left: 0;
border-radius: 5px;
object-fit: cover;
width: 100%;
height: 100%;
.card {
border-radius: 0.3em;
}
.card-img {
border-radius: 0.3em;
}
.card-button {
width: 56%;
height: 20px;
padding: 0.37em !important;
border-radius: 4px;
font-size: 12px;
background: #00EAEAB3;
color: white;
}
.card-button:active {
background: rgb(89 205 205 / 0.66);
color: #f5f5f5;
}
:deep(.el-button [class*=el-icon]+span) {
margin-left: 0 !important;
}
.tag_group {
display: none;
display: block;
width: 100%;
position: absolute;
font-size: 10px;
overflow: hidden;
height: 18px;
z-index: 2;
line-height: 18px;
padding-left: 2px;
margin-bottom: 2px;
text-align: start;
}
.cus_tag {
border-radius: 3px;
background: rgba(0,0,0, 0.3);
margin-right: 5px;
padding: 2px 3px;
}
.content_text_tag {
@@ -169,17 +346,42 @@ watchEffect(() => {
overflow: hidden;
}
.text-title {
font-size: 0.8rem;
}
.text-body {
font-size: 0.65rem;
margin: 5px 0 8px 0;
}
.item:hover .cus_remark {
visibility: hidden;
}
.cus_remark {
z-index: 10;
position: absolute;
bottom: 0;
top: 6px;
font-size: 10px;
padding: 2px 3px;
background-color: #67d9e8cc;
}
.cus_remark::after {
bottom: -6px;
right: -6px;
border-color: transparent transparent transparent #67d9e8cc;
}
.card-external-title {
display: block;
width: 100%;
max-width: 70%;
margin-top: 5px;
font-size: 12px;
color: #c2c2c2;
text-align: center;
background: rgba(0, 0, 0, 0.55);
border-radius: 0 0 5px 5px;
font-weight: bold;
text-align: start;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
@@ -195,25 +397,28 @@ watchEffect(() => {
.item {
margin-bottom: 20px;
box-sizing: border-box;
position: relative;
}
.link_content {
/* padding-top: 125%;*/
background-size: cover;
width: 100%;
display: flex;
/* position: relative;*/
margin-bottom: 5px;
.card {
border-radius: 0.5em;
}
img {
position: absolute;
top: 0;
left: 0;
border-radius: 5px;
object-fit: cover;
width: 100%;
height: 100%;
.card-img {
border-radius: 0.5em;
}
.card-button {
width: 80%;
padding: 0.7rem;
border-radius: 4px;
background: #ee9ca7;
color: white;
}
.card-button:hover {
background: #f954a6c7;
color: #f5f5f5;
}
.tag_group {
@@ -253,91 +458,31 @@ watchEffect(() => {
overflow: hidden;
}
.text-title {
font-size: 1rem;
}
.text-body {
font-size: 0.75rem;
margin: 5px 0 15px 0;
}
.item:hover .cus_remark {
visibility: hidden;
}
.cus_remark {
display: block;
width: 100%;
padding-left: 3px;
top: 8px;
font-size: 12px;
color: #999999;
text-align: left;
padding: 3px 6px;
background-color: #ff69b4fa; /* 粉红色 */
}
/* 核心:画小三角 */
.cus_remark::after {
bottom: -6px;
right: -7px;
border-color: transparent transparent transparent #ff69b4fa;
}
}
</style>
<style scoped>
.film-card {
background-color: transparent;
width: 100%;
perspective: 1000px;
font-family: sans-serif;
}
.film-card-inner {
padding-top: 125%;
position: relative;
width: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.film-card:hover .film-card-inner {
transform: rotateY(180deg);
}
.film-card-front, .film-card-back {
border-radius: 5px;
position: absolute;
top: 0;
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
/* border: 1px solid rgba(255, 255, 255, 0.1);*/
box-shadow: 0 25px 25px rgba(0, 0, 0, 0.25);
}
.film-card-front {
border: none;
background: url("/src/assets/image/404.png") no-repeat;
background-size: cover;
}
.film-card-back {
cursor: pointer;
transform: rotateY(180deg);
padding: 0 5px;
background: linear-gradient(#fff2, transparent);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.card-title {
max-width: 70%;
margin: 0 auto;
font-size: 14px ;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-blurb {
margin-bottom: 30px;
display: -webkit-box;
-webkit-line-clamp: 5; /* 限制显示的行数 */
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 12px;
}
.card-detail {
position: absolute;
width: 60%;
left: 20%;
bottom: 5px;
}
</style>

View File

@@ -72,7 +72,6 @@ const data = reactive({
site: Object,
})
// 加载观看历史记录信息
const handleHistory = (flag: boolean) => {
data.historyFlag = flag
@@ -182,7 +181,8 @@ onMounted(() => {
.header {
width: 100% !important;
height: 40px;
background: radial-gradient(circle, #d275cd, rgba(155, 73, 231, 0.72), #4ad1e5);
/* background: radial-gradient(circle, #d275cd, rgba(155, 73, 231, 0.72), #4ad1e5);*/
background: radial-gradient(circle, #d275cd91, rgb(155 73 231 / 65%), #4ad1e5c2);;
}
.nav_left {

View File

@@ -44,7 +44,7 @@ provide('global', {isMobile: isMobile})
min-height: 60px;
transform: translateZ(0);
z-index: 1000;
background-color: rgba(0, 0, 0, 0.85);
background-color: rgba(0, 0, 0, 0.45);
top: 0;
}

View File

@@ -1,10 +1,10 @@
<template>
<div v-if="global.isMobile" class="container">
<div class="card" v-for="h in data.historyList">
<div class="card" v-for="h in data.historyList" >
<div class="card-left">
<a class="card-link" :href="h.link" :style="{backgroundImage: `url(${h.picture})`}"></a>
</div>
<div class="card-right">
<div class="card-right" @click="router.push(h.link)">
<h5 class="card-title"> {{ h.name }}</h5>
<div class="card-content">
<p class="card-episode">{{ `已观看: ${h.progress}` }}</p>
@@ -21,6 +21,7 @@
<script setup lang="ts">
import {inject, onMounted, reactive} from "vue";
import {COOKIE_KEY_MAP, cookieUtil} from "../../utils/cookie";
import {useRouter} from "vue-router";
const data = reactive({
historyList: [{}]
@@ -28,6 +29,8 @@ const data = reactive({
const global = inject<any>('global')
const router = useRouter()
// 清除对应的历史记录
const cleanHistory = (id: number) => {
console.log(id)
@@ -66,27 +69,32 @@ onMounted(() => {
}
.card {
width: 100%;
width: 94%;
max-height: 250px;
display: flex;
padding: 5px 5px;
flex-direction: row;
background: linear-gradient(#fff2, transparent);
border: 1px solid rgba(255, 255, 255, 0.1);
/* border-bottom: 1px solid rgba(255, 255, 255, 0.1);*/
margin: 5px auto;
margin: 3%;
border-radius: 5px;
transform: translateY(0%);
}
.card:active{
background-color: rgba(0, 0, 0, 0.2);
transform: translateY(-3%);
transition: 0.5s;
}
.card-left {
flex-basis: 27%;
min-width: 27%;
flex-basis: 30%;
min-width: 30%;
display: flex;
}
.card-right {
flex-basis: 68%;
max-width: 68%;
flex-basis: 65%;
max-width: 65%;
display: flex;
flex-direction: column;
justify-content: space-between;
@@ -102,6 +110,7 @@ onMounted(() => {
border-radius: 3px;
background-repeat: no-repeat;
background-size: cover;
opacity: 0.9;
}
@@ -118,7 +127,7 @@ onMounted(() => {
.card-content p {
margin-top: 3px;
margin-bottom: 0;
color: var(--text-content-color);
color: var(--text-content-color-light);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -133,8 +142,9 @@ onMounted(() => {
.icon-cancel1 {
flex-basis: 5%;
height: 5%;
margin-right: 0;
color: var(--text-content-color);
color: var(--text-content-color-light);
}

View File

@@ -1,7 +1,7 @@
<template>
<div class="player_area" v-show="data.loading">
<div id="player-full" />
<div ref="playerContainer" class="player_p" @touchmove.prevent @wheel.prevent />
<div ref="playerContainer" class="player_container" />
<div class="current_play_info">
<div class="play_info_left">
<h3 class="current_play_title"><a
@@ -238,9 +238,10 @@ onBeforeMount(() => {
el: playerContainer.value,
url: data.options.url,
poster: posterImg,
width: "",
height: "",
width: "100%",
height: "100%",
fluid: true,
videoFillMode: "contain",
autoplay: data.options.autoplay,
lang: 'zh-cn', // 设置语言为中文
volume: 0.7, // 初始音量
@@ -311,7 +312,12 @@ watch(data.options, (newVal) => {
mPlayer.currentTime = 0
mPlayer.src = newVal.url
// mPlayer.load()
mPlayer.play()
mPlayer.play().then(()=>{
let playBtn = mPlayer.root.querySelector('.xg-icon-play')
if (playBtn) {
playBtn.style.display = 'none'
}
})
}
})
// 自定义播放列表插件
@@ -433,6 +439,26 @@ class playListPlugin extends Plugin {
<style>
/*xgplayer 样式修改*/
/*播放容器*/
.player_container {
width: 100%;
padding-top: 56.29%!important;
aspect-ratio: 16 / 9;
margin: 0;
position: relative;
border-radius: 6px;
display: flex;
box-shadow: 3px 3px 12px rgba(255, 255, 255, 0.2);
}
.player_area .xgplayer-is-fullscreen {
padding-top: 0 !important;
}
/*进度条颜色*/
.xgplayer .xgplayer-progress-played,.xg-mini-progress xg-mini-progress-played {
background: linear-gradient(-90deg, #00EAEA80 0%, #E337F780 100%);
}
.xg-right-grid .icon-dianying1 {
display: block;
color: #ffffff;
@@ -564,14 +590,7 @@ class playListPlugin extends Plugin {
min-height: 100%;
}
.player_p {
width: 100%;
aspect-ratio: 16 / 9;
margin: 0;
position: relative;
border-radius: 6px;
display: flex;
}
/*右侧播放源选择区域*/

View File

@@ -38,7 +38,7 @@
</div>
<el-empty v-if="data.oldSearch != '' && (!data.list || data.list.length == 0) " description="未查询到对应影片"/>
<div class="pagination_container ">
<div class="pagination_container" v-if="data.list && data.list.length > 0" >
<el-pagination background layout="prev, pager, next"
v-model:current-page="data.page.current"
@current-change="changeCurrent"
@@ -61,7 +61,6 @@ import {ApiGet} from "../../utils/request";
import {ArrowLeftBold, ArrowRightBold, CaretRight, Search} from '@element-plus/icons-vue'
import {ElMessage} from "element-plus";
const router = useRouter()
const route = useRoute()
const data = reactive({
@@ -116,7 +115,7 @@ const refreshPage = (keyword: any, current: any) => {
})
}
// 组件挂载完成后触发数据初始化
onMounted(() => {
if (router.currentRoute.value.query.search == null) {
return
@@ -140,6 +139,12 @@ const changeCurrent = (currentVal: number) => {
.InputContainer {
width: 40%;
}
.input {
width: 90%;
}
.micButton {
width: 10%;
}
.card-group {
justify-content: space-between;
}
@@ -158,6 +163,7 @@ const changeCurrent = (currentVal: number) => {
}
.card-right p {
font-size: 15px;
margin-bottom: 5px;
}
.card-right span {
font-size: 12px;
@@ -168,6 +174,12 @@ const changeCurrent = (currentVal: number) => {
.InputContainer {
width: 80%;
}
.input {
width: 80%;
}
.micButton {
width: 20%;
}
.card-group {
justify-content: center;
}
@@ -207,7 +219,6 @@ const changeCurrent = (currentVal: number) => {
}
.input {
width: 90%;
height: 100%;
border: none;
outline: none;
@@ -239,7 +250,6 @@ input:-webkit-autofill:active {
.micButton {
width: 10%;
padding: 0px 15px 0px 12px;
border: none;
background-color: transparent;
@@ -255,7 +265,7 @@ input:-webkit-autofill:active {
.micButton:hover {
border-radius: 0 10px 10px 0;
background-color: rgb(201 38 237 / 0.3);
background-color: #fde2e245;
transition-duration: .3s;
}
/*-----------------------header-container-------------------------------------------*/
@@ -293,6 +303,12 @@ input:-webkit-autofill:active {
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
overflow: hidden;
transform: translateY(0%);
}
.card:active {
background-color: rgba(255, 255, 255, 0.2);
transform: translateY(-3%);
transition: 0.5s;
}
.card-left {
height: 100%;
@@ -327,7 +343,6 @@ input:-webkit-autofill:active {
-webkit-line-clamp: 1;
white-space: nowrap;
overflow: hidden;
}
.card-right span {
margin-right: 8px;
@@ -339,16 +354,18 @@ input:-webkit-autofill:active {
.card-right .tag_c{
background: rgba(155, 73, 231, 0.72);
}
.card-right p {
.card-right p:not(.blurb) {
max-width: 90%;
white-space: nowrap;
overflow: hidden;
margin-bottom: 5px;
text-overflow: ellipsis;
}
.card-right .blurb {
max-width: 90%;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.card-right p em {
font-weight: bold;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -11,8 +11,8 @@
<meta charset="UTF-8"/>
<title>(╥﹏╥)</title>
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3992367_d9xdu8zk04f.css">
<script type="module" crossorigin src="/assets/index-C7tICDmk.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DYf3Lkog.css">
<script type="module" crossorigin src="/assets/index-BJUHGEn_.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Kj7xWjhf.css">
</head>
<body>
<div id="app"></div>