@@ -425,38 +425,25 @@ export async function openSettings(): Promise<void> {
425425 const bgHint = el ( 'div' , { class : 'bg-preview__hint' } ) ;
426426 bgPreview . append ( bgMedia , bgHint ) ;
427427
428- /* 背景图不透明度:仅控制背景层 */
429- const bgOpacityLabel = el ( 'div' , { class : 'field__hint' , text : `背景不透明度 ${ store . background . opacity } %` } ) ;
430- const bgOpacityRange = el ( 'input' , { class : 'range' , type : 'range' , min : '0' , max : '100' , value : String ( store . background . opacity ) } ) ;
431- bgOpacityRange . addEventListener ( 'input' , ( ) => {
432- const v = Number ( bgOpacityRange . value ) ;
433- bgOpacityLabel . textContent = `背景不透明度 ${ v } %` ;
434- void store . setBackground ( { opacity : v } ) ;
435- } ) ;
436- const bgOpacityWrap = el ( 'div' , { style : 'flex:1;min-width:160px;display:flex;flex-direction:column;gap:6px' } ) ;
437- bgOpacityWrap . append ( bgOpacityLabel , bgOpacityRange ) ;
438-
439- /* 页面内容层不透明度:让顶栏/侧栏/卡片半透明,背景透出 */
440- const pageOpacityLabel = el ( 'div' , { class : 'field__hint' , text : `页面不透明度 ${ store . background . pageOpacity } %` } ) ;
441- const pageOpacityRange = el ( 'input' , { class : 'range' , type : 'range' , min : '0' , max : '100' , value : String ( store . background . pageOpacity ) } ) ;
442- pageOpacityRange . addEventListener ( 'input' , ( ) => {
443- const v = Number ( pageOpacityRange . value ) ;
444- pageOpacityLabel . textContent = `页面不透明度 ${ v } %` ;
445- void store . setBackground ( { pageOpacity : v } ) ;
446- } ) ;
447- const pageOpacityWrap = el ( 'div' , { style : 'flex:1;min-width:160px;display:flex;flex-direction:column;gap:6px' } ) ;
448- pageOpacityWrap . append ( pageOpacityLabel , pageOpacityRange ) ;
449-
450- /* 视频音量:仅当背景为视频时显示 */
451- const volumeLabel = el ( 'div' , { class : 'field__hint' , text : `视频音量 ${ store . background . volume } %` } ) ;
452- const volumeRange = el ( 'input' , { class : 'range' , type : 'range' , min : '0' , max : '100' , value : String ( store . background . volume ) } ) ;
453- volumeRange . addEventListener ( 'input' , ( ) => {
454- const v = Number ( volumeRange . value ) ;
455- volumeLabel . textContent = `视频音量 ${ v } %` ;
456- void store . setBackground ( { volume : v } ) ;
457- } ) ;
458- const volumeWrap = el ( 'div' , { style : 'flex:1;min-width:160px;display:flex;flex-direction:column;gap:6px' } ) ;
459- volumeWrap . append ( volumeLabel , volumeRange ) ;
428+ /* 百分比滑块工厂:label + range,返回 wrap 与同步函数 */
429+ const percentSlider = ( name : string , value : number , onInput : ( v : number ) => void ) => {
430+ const label = el ( 'div' , { class : 'field__hint' , text : `${ name } ${ value } %` } ) ;
431+ const range = el ( 'input' , { class : 'range' , type : 'range' , min : '0' , max : '100' , value : String ( value ) } ) ;
432+ range . addEventListener ( 'input' , ( ) => {
433+ const v = Number ( range . value ) ;
434+ label . textContent = `${ name } ${ v } %` ;
435+ onInput ( v ) ;
436+ } ) ;
437+ const wrap = el ( 'div' , { style : 'flex:1;min-width:160px;display:flex;flex-direction:column;gap:6px' } ) ;
438+ wrap . append ( label , range ) ;
439+ const sync = ( v : number ) => { range . value = String ( v ) ; label . textContent = `${ name } ${ v } %` ; } ;
440+ return { wrap, sync } ;
441+ } ;
442+
443+ // 背景层不透明度、页面内容层不透明度、视频音量(音量仅视频时显示)
444+ const bgOpacity = percentSlider ( '背景不透明度' , store . background . opacity , ( v ) => void store . setBackground ( { opacity : v } ) ) ;
445+ const pageOpacity = percentSlider ( '页面不透明度' , store . background . pageOpacity , ( v ) => void store . setBackground ( { pageOpacity : v } ) ) ;
446+ const volume = percentSlider ( '视频音量' , store . background . volume , ( v ) => void store . setBackground ( { volume : v } ) ) ;
460447
461448 const enToggle = toggle ( '启用背景' , '' , store . background . enabled , ( v ) => { void store . setBackground ( { enabled : v } ) ; } ) ;
462449
@@ -514,7 +501,7 @@ export async function openSettings(): Promise<void> {
514501 bgPreview . addEventListener ( 'pointercancel' , ( ) => { dragging = false ; } ) ;
515502
516503 const bgControls = el ( 'div' , { style : 'display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-top:10px' } ) ;
517- bgControls . append ( bgOpacityWrap , pageOpacityWrap , volumeWrap ) ;
504+ bgControls . append ( bgOpacity . wrap , pageOpacity . wrap , volume . wrap ) ;
518505 const bgActions = el ( 'div' , { style : 'display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px' } ) ;
519506 bgActions . append ( enToggle , uploadBtn , clearBtn ) ;
520507 bgField . append ( bgPreview , bgControls , bgActions , fileInput ) ;
@@ -528,13 +515,10 @@ export async function openSettings(): Promise<void> {
528515 bgMedia . style . backgroundPosition = `${ bg . posX } % ${ bg . posY } %` ;
529516 bgHint . textContent = bg . enabled ? ( bg . src ? '拖动调整展示区域' : '请先上传图片' ) : '未启用' ;
530517 enToggle . querySelector ( '.switch' ) ?. classList . toggle ( 'is-on' , bg . enabled ) ;
531- bgOpacityRange . value = String ( bg . opacity ) ;
532- bgOpacityLabel . textContent = `背景不透明度 ${ bg . opacity } %` ;
533- pageOpacityRange . value = String ( bg . pageOpacity ) ;
534- pageOpacityLabel . textContent = `页面不透明度 ${ bg . pageOpacity } %` ;
535- volumeRange . value = String ( bg . volume ) ;
536- volumeLabel . textContent = `视频音量 ${ bg . volume } %` ;
537- volumeWrap . style . display = bg . mime . startsWith ( 'video/' ) ? '' : 'none' ;
518+ bgOpacity . sync ( bg . opacity ) ;
519+ pageOpacity . sync ( bg . pageOpacity ) ;
520+ volume . sync ( bg . volume ) ;
521+ volume . wrap . style . display = bg . mime . startsWith ( 'video/' ) ? '' : 'none' ;
538522 } ;
539523 paintBg ( ) ;
540524
0 commit comments