Feature(custom): support custom background image opacity and blur

This commit is contained in:
Kuingsmile
2026-01-27 14:37:05 +08:00
parent d64cf2d4f3
commit a6f54e6493
9 changed files with 62 additions and 8 deletions

View File

@@ -37,7 +37,7 @@
- 接入主题仓库 [PicList ThemeHub](https://github.com/Kuingsmile/PicList-ThemeHub),支持自定义下载 - 接入主题仓库 [PicList ThemeHub](https://github.com/Kuingsmile/PicList-ThemeHub),支持自定义下载
- 提供 12 个内置主题(如 bilibili、二次元、极夜紫等风格 - 提供 12 个内置主题(如 bilibili、二次元、极夜紫等风格
- 支持自定义主题编辑和保存 - 支持自定义主题编辑和保存
- 支持自定义背景图片 - 支持自定义背景图片及其透明度和模糊效果
- 重新设计了管理功能的全部页面 - 重新设计了管理功能的全部页面
- 优化相册页面卡片样式,边界更清晰,提升选择框视觉效果 - 优化相册页面卡片样式,边界更清晰,提升选择框视觉效果
- 优化多个页面在窄屏下的显示,避免内容溢出 - 优化多个页面在窄屏下的显示,避免内容溢出

View File

@@ -37,7 +37,7 @@ Use custom `javascript` scripts to extend PicList's functionality without the ne
- Integrated theme repository [PicList ThemeHub](https://github.com/Kuingsmile/PicList-ThemeHub), supporting custom downloads. - Integrated theme repository [PicList ThemeHub](https://github.com/Kuingsmile/PicList-ThemeHub), supporting custom downloads.
- Provided 12 built-in themes (such as bilibili, Anime, purple styles). - Provided 12 built-in themes (such as bilibili, Anime, purple styles).
- Supports custom theme editing and saving. - Supports custom theme editing and saving.
- Supports custom background images. - Supports custom background images and their opacity and blur effects.
- Redesigned all pages of the management function - Redesigned all pages of the management function
- Optimized album page card styles, clearer boundaries, improved selection box visual effects. - Optimized album page card styles, clearer boundaries, improved selection box visual effects.
- Optimized the display of multiple pages under narrow screens to avoid content overflow. - Optimized the display of multiple pages under narrow screens to avoid content overflow.

View File

@@ -14,8 +14,13 @@ function setTheme(mode: string) {
document.documentElement.classList.toggle('light', m === 'light') document.documentElement.classList.toggle('light', m === 'light')
} }
function injectCSS(css: string, config: { imageUrl?: string; opacity?: string; blur?: string }) { async function injectCSS(css: string, config: { imageUrl?: string; opacity?: string; blur?: string }) {
const id = '__piclist_theme__' const id = '__piclist_theme__'
if (!document.documentElement) {
await new Promise(resolve => {
window.addEventListener('DOMContentLoaded', resolve, { once: true })
})
}
let el = document.getElementById(id) as HTMLStyleElement | null let el = document.getElementById(id) as HTMLStyleElement | null
if (!el) { if (!el) {
el = document.createElement('style') el = document.createElement('style')
@@ -40,15 +45,17 @@ function injectCSS(css: string, config: { imageUrl?: string; opacity?: string; b
const allConfig = await ipcRenderer.invoke('RPC_ACTIONS_INVOKE', 'PICLIST_GET_CONFIG', []) const allConfig = await ipcRenderer.invoke('RPC_ACTIONS_INVOKE', 'PICLIST_GET_CONFIG', [])
const enableCustomBgImg = allConfig?.settings?.enableCustomBgImg || false const enableCustomBgImg = allConfig?.settings?.enableCustomBgImg || false
const customBgImgPath = allConfig?.settings?.customBgImgPath || '' const customBgImgPath = allConfig?.settings?.customBgImgPath || ''
const customBgOpacity = allConfig?.settings?.customBgImgOpacity || '0.7'
const customBgBlur = allConfig?.settings?.customBgImgBlur || 5
const config = enableCustomBgImg const config = enableCustomBgImg
? { ? {
imageUrl: customBgImgPath, imageUrl: customBgImgPath,
opacity: '0.7', opacity: customBgOpacity,
blur: '5px', blur: `${customBgBlur}px`,
} }
: {} : {}
if (document.documentElement) setTheme(mode) if (document.documentElement) setTheme(mode)
if (css) injectCSS(css, config) if (css) await injectCSS(css, config)
} catch (e) { } catch (e) {
console.error('[theme] bootstrap failed', e) console.error('[theme] bootstrap failed', e)
} }
@@ -140,11 +147,13 @@ try {
const allConfig = await ipcRenderer.invoke('RPC_ACTIONS_INVOKE', 'PICLIST_GET_CONFIG', []) const allConfig = await ipcRenderer.invoke('RPC_ACTIONS_INVOKE', 'PICLIST_GET_CONFIG', [])
const enableCustomBgImg = allConfig?.settings?.enableCustomBgImg || false const enableCustomBgImg = allConfig?.settings?.enableCustomBgImg || false
const customBgImgPath = allConfig?.settings?.customBgImgPath || '' const customBgImgPath = allConfig?.settings?.customBgImgPath || ''
const customBgOpacity = allConfig?.settings?.customBgImgOpacity || '0.7'
const customBgBlur = allConfig?.settings?.customBgImgBlur || 5
const config = enableCustomBgImg const config = enableCustomBgImg
? { ? {
imageUrl: customBgImgPath, imageUrl: customBgImgPath,
opacity: '0.7', opacity: customBgOpacity,
blur: '5px', blur: `${customBgBlur}px`,
} }
: {} : {}
injectCSS(css, config) injectCSS(css, config)

View File

@@ -901,6 +901,8 @@
"autoLaunchDesc": "Automatically start PicList when system boots", "autoLaunchDesc": "Automatically start PicList when system boots",
"chooseLanguage": "Choose Language", "chooseLanguage": "Choose Language",
"chooseTheme": "Choose Theme", "chooseTheme": "Choose Theme",
"customBgImgBlur": "Custom Background Image Blur",
"customBgImgOpacity": "Custom Background Image Opacity",
"customBgImgPath": "Select custom background img", "customBgImgPath": "Select custom background img",
"customMiniIconPath": "Custom Mini Icon Path", "customMiniIconPath": "Custom Mini Icon Path",
"downloadingThemes": "Downloading...", "downloadingThemes": "Downloading...",

View File

@@ -901,6 +901,8 @@
"autoLaunchDesc": "登录时自动启动 PicList", "autoLaunchDesc": "登录时自动启动 PicList",
"chooseLanguage": "选择语言", "chooseLanguage": "选择语言",
"chooseTheme": "选择主题", "chooseTheme": "选择主题",
"customBgImgBlur": "自定义背景图片模糊度",
"customBgImgOpacity": "自定义背景图片不透明度",
"customBgImgPath": "自定义背景图片选择", "customBgImgPath": "自定义背景图片选择",
"customMiniIconPath": "自定义迷你窗口图标路径", "customMiniIconPath": "自定义迷你窗口图标路径",
"downloadingThemes": "下载中...", "downloadingThemes": "下载中...",

View File

@@ -901,6 +901,8 @@
"autoLaunchDesc": "系統啟動時自動啟動 PicList", "autoLaunchDesc": "系統啟動時自動啟動 PicList",
"chooseLanguage": "選擇語言", "chooseLanguage": "選擇語言",
"chooseTheme": "選擇主題", "chooseTheme": "選擇主題",
"customBgImgBlur": "自定義背景圖片模糊度",
"customBgImgOpacity": "自定義背景圖片不透明度",
"customBgImgPath": "選擇自定義背景圖片", "customBgImgPath": "選擇自定義背景圖片",
"customMiniIconPath": "自定義迷你窗口圖標路徑", "customMiniIconPath": "自定義迷你窗口圖標路徑",
"downloadingThemes": "下載中...", "downloadingThemes": "下載中...",

View File

@@ -148,6 +148,29 @@
<CustomButton type="primary" :text="t('pages.settings.clickToSet')" @click="handleCustomBgImg" /> <CustomButton type="primary" :text="t('pages.settings.clickToSet')" @click="handleCustomBgImg" />
</template> </template>
</CustomNavCard> </CustomNavCard>
<SettingCard v-if="formOfSetting.enableCustomBgImg">
<CustomInput
v-model="formOfSetting.customBgImgOpacity"
type="number"
min="0"
max="1"
step="0.01"
:title="t('pages.settings.system.customBgImgOpacity')"
placeholder="0.7"
@blur="handleBlurCustomBgImgOpacity"
/>
</SettingCard>
<SettingCard v-if="formOfSetting.enableCustomBgImg">
<CustomInput
v-model="formOfSetting.customBgImgBlur"
type="number"
min="1"
step="1"
:title="t('pages.settings.system.customBgImgBlur')"
placeholder="5"
@blur="handleBlurCustomBgImgBlur"
/>
</SettingCard>
</SettingSection> </SettingSection>
<!-- Window Behavior Section --> <!-- Window Behavior Section -->
@@ -1424,6 +1447,8 @@ const formOfSetting = ref<ISettingForm>({
theme: 'default.css', theme: 'default.css',
enableCustomBgImg: false, enableCustomBgImg: false,
customBgImgPath: '', customBgImgPath: '',
customBgImgOpacity: 0.7,
customBgImgBlur: 5,
}) })
/* computed properties */ /* computed properties */
@@ -1722,6 +1747,16 @@ const addWatch = () => {
) )
} }
function handleBlurCustomBgImgBlur() {
saveConfig({ [configPaths.settings.customBgImgBlur]: formOfSetting.value.customBgImgBlur })
window.electron.sendRPC(IRPCActionType.RELOAD_WINDOW)
}
function handleBlurCustomBgImgOpacity() {
saveConfig({ [configPaths.settings.customBgImgOpacity]: formOfSetting.value.customBgImgOpacity })
window.electron.sendRPC(IRPCActionType.RELOAD_WINDOW)
}
/* methods */ /* methods */
async function cancelSyncSetting() { async function cancelSyncSetting() {
syncVisible.value = false syncVisible.value = false

View File

@@ -190,6 +190,8 @@ export const configPaths = {
isDisableGPU: 'settings.isDisableGPU', isDisableGPU: 'settings.isDisableGPU',
enableCustomBgImg: 'settings.enableCustomBgImg', enableCustomBgImg: 'settings.enableCustomBgImg',
customBgImgPath: 'settings.customBgImgPath', customBgImgPath: 'settings.customBgImgPath',
customBgImgOpacity: 'settings.customBgImgOpacity',
customBgImgBlur: 'settings.customBgImgBlur',
}, },
needReload: 'needReload', needReload: 'needReload',
picgoPlugins: 'picgoPlugins', picgoPlugins: 'picgoPlugins',

View File

@@ -44,6 +44,8 @@ interface ISettingForm {
theme: string theme: string
enableCustomBgImg: boolean enableCustomBgImg: boolean
customBgImgPath: string customBgImgPath: string
customBgImgOpacity: number
customBgImgBlur: number
} }
interface IToolboxItem { interface IToolboxItem {