feat(glass): 插件卡片改为染色玻璃

将插件卡片与市场卡片头部的实色背景改为变量驱动的染色层:
图标主色只作为透光色相,玻璃主题下叠加吸收遮罩与镜面高光,
并按 frosted/tinted 材质与透明度调整强度;文件夹卡片渐变底
同步降低不透明度让卡片本体玻璃透出。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
jxxghp
2026-07-28 13:52:50 +08:00
co-authored by Claude Opus 5
parent 8a4ca2482c
commit 8d86bd6e92
4 changed files with 107 additions and 20 deletions
+8 -10
View File
@@ -2,7 +2,7 @@
import api from '@/api'
import type { Plugin } from '@/api/types'
import { getLogoUrl } from '@/utils/imageUtils'
import { getDominantColor } from '@/@core/utils/image'
import { getCardAccentRgbFromImage } from '@/composables/useCardAccentColor'
import { isNullOrEmptyObject } from '@/@core/utils'
import { formatDownloadCount } from '@/@core/utils/formatters'
import { useToast } from 'vue-toastification'
@@ -35,8 +35,8 @@ const $toast = useToast()
const createConfirm = useConfirm()
// 背景颜色
const backgroundColor = ref('#28A9E1')
// 卡片头部染色所用的图标主色(CSS 变量可直接消费的 RGB 通道值)
const accentRgb = ref('40, 169, 225')
// 图片对象
const imageRef = ref<any>()
@@ -76,8 +76,8 @@ function closeInstallProgress() {
async function imageLoaded() {
isImageLoaded.value = true
const imageElement = imageRef.value?.$el.querySelector('img') as HTMLImageElement
// 从图中提取背景色
backgroundColor.value = await getDominantColor(imageElement)
// 从图中提取主色,作为卡片头部染色玻璃的色相来源
accentRgb.value = await getCardAccentRgbFromImage(imageElement, '#28A9E1')
}
// 计算图标路径
@@ -236,15 +236,13 @@ onUnmounted(() => {
:width="props.width"
:height="props.height"
@click="showPluginDetail"
class="app-hover-lift-card flex flex-col h-full"
class="plugin-card app-hover-lift-card flex flex-col h-full"
:class="{
'app-hover-lift-card--hovering': hover.isHovering,
}"
:style="{ '--plugin-card-accent-rgb': accentRgb }"
>
<div
class="flex-grow"
:style="`background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.5) 100%), linear-gradient(${backgroundColor} 0%, ${backgroundColor} 100%)`"
>
<div class="plugin-card__banner flex-grow">
<VCardText class="px-2 pt-2 pb-0">
<VCardTitle
class="text-white px-2 pb-0 text-lg text-shadow whitespace-nowrap overflow-hidden text-ellipsis"
+8 -10
View File
@@ -4,7 +4,7 @@ import { useConfirm } from '@/composables/useConfirm'
import api from '@/api'
import type { Plugin } from '@/api/types'
import { getLogoUrl } from '@/utils/imageUtils'
import { getDominantColor } from '@/@core/utils/image'
import { getCardAccentRgbFromImage } from '@/composables/useCardAccentColor'
import { formatDownloadCount } from '@/@core/utils/formatters'
import { useDisplay } from 'vuetify'
import { useI18n } from 'vue-i18n'
@@ -40,8 +40,8 @@ const { t } = useI18n()
// 显示器宽度
const display = useDisplay()
// 背景颜色
const backgroundColor = ref('#28A9E1')
// 卡片头部染色所用的图标主色(CSS 变量可直接消费的 RGB 通道值)
const accentRgb = ref('40, 169, 225')
// 图片对象
const imageRef = ref<any>()
@@ -98,8 +98,8 @@ watch(
async function imageLoaded() {
isImageLoaded.value = true
const imageElement = imageRef.value?.$el.querySelector('img') as HTMLImageElement
// 从图中提取背景色
backgroundColor.value = await getDominantColor(imageElement)
// 从图中提取主色,作为卡片头部染色玻璃的色相来源
accentRgb.value = await getCardAccentRgbFromImage(imageElement, '#28A9E1')
}
// 显示更新日志
@@ -573,17 +573,15 @@ watch(
:width="props.width"
:height="props.height"
@click="handleCardClick"
class="app-hover-lift-card flex flex-col h-full"
class="plugin-card app-hover-lift-card flex flex-col h-full"
:class="{
'app-hover-lift-card--hovering': hover.isHovering && !props.sortable,
'cursor-move': props.sortable,
}"
:style="{ '--plugin-card-accent-rgb': accentRgb }"
:ripple="!props.sortable"
>
<div
class="flex-grow"
:style="`background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.5) 100%), linear-gradient(${backgroundColor} 0%, ${backgroundColor} 100%)`"
>
<div class="plugin-card__banner flex-grow">
<VCardText class="px-2 pt-2 pb-0">
<VCardTitle
class="text-white px-2 pb-0 text-lg text-shadow whitespace-nowrap overflow-hidden text-ellipsis"