feat: 新增磨砂玻璃透明度设置功能
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "frpilot",
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
+19
-10
@@ -13,6 +13,12 @@ body,
|
||||
|
||||
/* 窗口背景色与渐变(供 html / #app 复用,避免重复定义) */
|
||||
:root {
|
||||
/* 全局文字颜色:普通 HTML 文本继承使用(Antd 组件由 CSS-in-JS 自行着色,不受影响) */
|
||||
--app-text-color: rgba(15, 23, 42, 0.88);
|
||||
/* 磨砂玻璃透明度:由「外观设置」实时写入 <html>,默认值与初始外观保持一致 */
|
||||
--app-card-alpha: 0.45;
|
||||
--app-card-alpha-hover: 0.62;
|
||||
--app-modal-alpha: 0.62;
|
||||
--app-bg-color: #eef2ff;
|
||||
--app-bg-gradient:
|
||||
radial-gradient(1200px 600px at 10% -10%, rgba(99, 102, 241, 0.28), transparent 60%),
|
||||
@@ -21,6 +27,7 @@ body,
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--app-text-color: rgba(226, 232, 240, 0.92);
|
||||
--app-bg-color: #0b1220;
|
||||
--app-bg-gradient:
|
||||
radial-gradient(1200px 600px at 10% -10%, rgba(99, 102, 241, 0.35), transparent 60%),
|
||||
@@ -85,6 +92,8 @@ body {
|
||||
overflow: hidden;
|
||||
font-family: 'Inter', 'HarmonyOS Sans SC', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* 文字颜色跟随明暗主题,避免暗色下普通文本仍是浏览器默认黑色 */
|
||||
color: var(--app-text-color);
|
||||
/* 背景交由 <html>(或 macOS 下的 #app)绘制,body 保持透明避免覆盖画布背景 */
|
||||
background-color: transparent;
|
||||
}
|
||||
@@ -112,7 +121,7 @@ body {
|
||||
.glass-panel {
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55);
|
||||
background: rgba(255, 255, 255, 0.45);
|
||||
background: rgba(255, 255, 255, var(--app-card-alpha));
|
||||
backdrop-filter: blur(18px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(18px) saturate(160%);
|
||||
box-shadow: 0 8px 32px rgba(15, 23, 42, 0.12);
|
||||
@@ -120,7 +129,7 @@ body {
|
||||
|
||||
.dark .glass-panel {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
background: rgba(15, 23, 42, 0.45);
|
||||
background: rgba(15, 23, 42, var(--app-card-alpha));
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
@@ -131,7 +140,7 @@ body {
|
||||
*/
|
||||
.glass-card.ant-card {
|
||||
border: 1px solid rgba(255, 255, 255, 0.5) !important;
|
||||
background: rgba(255, 255, 255, 0.45) !important;
|
||||
background: rgba(255, 255, 255, var(--app-card-alpha)) !important;
|
||||
backdrop-filter: blur(16px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(160%);
|
||||
box-shadow: 0 6px 22px rgba(15, 23, 42, 0.08) !important;
|
||||
@@ -140,19 +149,19 @@ body {
|
||||
|
||||
.glass-card.ant-card:hover {
|
||||
border-color: rgba(99, 102, 241, 0.45) !important;
|
||||
background: rgba(255, 255, 255, 0.62) !important;
|
||||
background: rgba(255, 255, 255, var(--app-card-alpha-hover)) !important;
|
||||
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14) !important;
|
||||
}
|
||||
|
||||
.dark .glass-card.ant-card {
|
||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
||||
background: rgba(30, 41, 59, 0.5) !important;
|
||||
background: rgba(30, 41, 59, var(--app-card-alpha)) !important;
|
||||
box-shadow: 0 6px 22px rgba(0, 0, 0, 0.35) !important;
|
||||
}
|
||||
|
||||
.dark .glass-card.ant-card:hover {
|
||||
border-color: rgba(129, 140, 248, 0.5) !important;
|
||||
background: rgba(30, 41, 59, 0.62) !important;
|
||||
background: rgba(30, 41, 59, var(--app-card-alpha-hover)) !important;
|
||||
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45) !important;
|
||||
}
|
||||
|
||||
@@ -172,7 +181,7 @@ body {
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55);
|
||||
background: rgba(255, 255, 255, 0.62) !important;
|
||||
background: rgba(255, 255, 255, var(--app-modal-alpha)) !important;
|
||||
backdrop-filter: blur(24px) saturate(170%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(170%);
|
||||
box-shadow: 0 16px 48px rgba(15, 23, 42, 0.18) !important;
|
||||
@@ -187,7 +196,7 @@ body {
|
||||
|
||||
.dark .form-modal-wrap .ant-modal-content {
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
background: rgba(30, 41, 59, 0.62) !important;
|
||||
background: rgba(30, 41, 59, var(--app-modal-alpha)) !important;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
@@ -217,7 +226,7 @@ body {
|
||||
max-height: 60vh;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55);
|
||||
background: rgba(255, 255, 255, 0.72) !important;
|
||||
background: rgba(255, 255, 255, var(--app-modal-alpha)) !important;
|
||||
backdrop-filter: blur(24px) saturate(170%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(170%);
|
||||
box-shadow: 0 16px 48px rgba(15, 23, 42, 0.18) !important;
|
||||
@@ -232,7 +241,7 @@ body {
|
||||
|
||||
.dark .update-modal-wrap .ant-modal-content {
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
background: rgba(30, 41, 59, 0.72) !important;
|
||||
background: rgba(30, 41, 59, var(--app-modal-alpha)) !important;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,12 @@
|
||||
"bg6": "Background 6",
|
||||
"bg7": "Background 7",
|
||||
"bg8": "Background 8",
|
||||
"bg9": "Background 9"
|
||||
"bg9": "Background 9",
|
||||
"glass": "Glass transparency",
|
||||
"glassTip": "Drag the sliders to adjust how transparent the cards and dialogs are. Higher values are more transparent.",
|
||||
"cardTransparency": "Card transparency",
|
||||
"modalTransparency": "Dialog transparency",
|
||||
"previewTip": "Top preview shows cards, bottom shows dialogs — drag a slider to preview live."
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
|
||||
@@ -94,7 +94,12 @@
|
||||
"bg6": "背景六",
|
||||
"bg7": "背景七",
|
||||
"bg8": "背景八",
|
||||
"bg9": "背景九"
|
||||
"bg9": "背景九",
|
||||
"glass": "磨砂玻璃透明度",
|
||||
"glassTip": "拖动滑块调整卡片与弹窗背景的透明程度,数值越大越透明",
|
||||
"cardTransparency": "卡片透明度",
|
||||
"modalTransparency": "弹窗透明度",
|
||||
"previewTip": "上方为卡片效果,下方为弹窗效果,可拖动滑块实时预览"
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
|
||||
@@ -45,6 +45,27 @@ export const useAppStore = defineStore("app", () => {
|
||||
}
|
||||
})
|
||||
|
||||
// 磨砂玻璃透明度(0 - 100,数值越大越透明,持久化)
|
||||
const cardTransparency = useStorage<number>("frpilot:card-transparency", 55)
|
||||
const modalTransparency = useStorage<number>("frpilot:modal-transparency", 38)
|
||||
|
||||
/** 透明度百分比 → 背景 alpha(越大越透明,alpha 越小;并做范围兜底) */
|
||||
function alphaFromTransparency(value: number) {
|
||||
const percent = Math.min(100, Math.max(0, Number(value) || 0))
|
||||
return (100 - percent) / 100
|
||||
}
|
||||
|
||||
const cardAlpha = computed(() => alphaFromTransparency(cardTransparency.value))
|
||||
const modalAlpha = computed(() => alphaFromTransparency(modalTransparency.value))
|
||||
|
||||
// 把透明度实时写入 <html> 的 CSS 变量,供磨砂玻璃样式(卡片 / 弹窗)即时生效
|
||||
watchEffect(() => {
|
||||
const root = document.documentElement
|
||||
root.style.setProperty("--app-card-alpha", String(cardAlpha.value))
|
||||
root.style.setProperty("--app-card-alpha-hover", String(Math.min(cardAlpha.value + 0.15, 0.95)))
|
||||
root.style.setProperty("--app-modal-alpha", String(modalAlpha.value))
|
||||
})
|
||||
|
||||
// Frpc 运行状态(后续由后端驱动)
|
||||
const runStatus = ref<RunStatus>("stopped")
|
||||
|
||||
@@ -76,6 +97,8 @@ export const useAppStore = defineStore("app", () => {
|
||||
toggleDark,
|
||||
background,
|
||||
backgroundUrl,
|
||||
cardTransparency,
|
||||
modalTransparency,
|
||||
runStatus,
|
||||
antdLocale,
|
||||
setLanguage,
|
||||
|
||||
Vendored
+1
@@ -36,6 +36,7 @@ declare module 'vue' {
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASegmented: typeof import('ant-design-vue/es')['Segmented']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASlider: typeof import('ant-design-vue/es')['Slider']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
AStatistic: typeof import('ant-design-vue/es')['Statistic']
|
||||
|
||||
@@ -33,6 +33,37 @@
|
||||
</a-card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<a-divider />
|
||||
|
||||
<!-- 磨砂玻璃透明度(拖动即时生效) -->
|
||||
<section>
|
||||
<div class="mb-1 text-sm font-medium">{{ t("settings.appearance.glass") }}</div>
|
||||
<p class="mb-3 text-xs opacity-60">{{ t("settings.appearance.glassTip") }}</p>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="mb-1 flex items-center justify-between text-xs">
|
||||
<span>{{ t("settings.appearance.cardTransparency") }}</span>
|
||||
<span class="font-medium tabular-nums">{{ appStore.cardTransparency }}%</span>
|
||||
</div>
|
||||
<a-slider v-model:value="appStore.cardTransparency" :min="0" :max="100" />
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="mb-1 flex items-center justify-between text-xs">
|
||||
<span>{{ t("settings.appearance.modalTransparency") }}</span>
|
||||
<span class="font-medium tabular-nums">{{ appStore.modalTransparency }}%</span>
|
||||
</div>
|
||||
<a-slider v-model:value="appStore.modalTransparency" :min="0" :max="100" />
|
||||
</div>
|
||||
|
||||
<!-- 实时预览:两种磨砂效果叠加在彩色底图上,拖动滑块即时可见 -->
|
||||
<div class="glass-preview" aria-hidden="true">
|
||||
<div class="glass-preview-card"></div>
|
||||
<div class="glass-preview-modal"></div>
|
||||
</div>
|
||||
<p class="mt-2 text-xs opacity-60">{{ t("settings.appearance.previewTip") }}</p>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,4 +136,45 @@ function selectBackground(key: BackgroundKey) {
|
||||
rgba(148, 163, 184, 0.25) 0 8px,
|
||||
transparent 8px 16px);
|
||||
}
|
||||
|
||||
/* 透明度实时预览:纯色底图(暖调中性色,不用渐变)+ 卡片 / 弹窗两种磨砂效果 */
|
||||
.glass-preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 14px;
|
||||
border-radius: 12px;
|
||||
background-color: #a09adf;
|
||||
}
|
||||
|
||||
.dark .glass-preview {
|
||||
background-color: #a09adf;
|
||||
}
|
||||
|
||||
.glass-preview-card,
|
||||
.glass-preview-modal {
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
backdrop-filter: blur(10px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(10px) saturate(160%);
|
||||
}
|
||||
|
||||
.glass-preview-card {
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, var(--app-card-alpha));
|
||||
}
|
||||
|
||||
.glass-preview-modal {
|
||||
height: 48px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, var(--app-modal-alpha));
|
||||
}
|
||||
|
||||
.dark .glass-preview-card {
|
||||
background: rgba(30, 41, 59, var(--app-card-alpha));
|
||||
}
|
||||
|
||||
.dark .glass-preview-modal {
|
||||
background: rgba(30, 41, 59, var(--app-modal-alpha));
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user