feat(console): 默认预设升级为两张(极光SVG + 海岸公路Sea01 1280px JPEG 181KB);恢复初始按钮文案去括号;种子逻辑双图入库

This commit is contained in:
Aisland
2026-09-02 00:55:33 +08:00
parent 47fa0a9f6f
commit 50a11bcf7e
7 changed files with 47 additions and 8 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@ export const CHANGELOG_V030 = `更新公告 · v0.3.0
【1.3 背景系统扩至三种可选】——单色背景、柔光背景、自定义背景,每种都有独立面板:
· 单色背景:提供色相、饱和度、明度调节滑杆,支持直接输入数值与一键恢复默认;默认颜色随当前主题自动匹配(深色=深蓝黑,浅色=米白)。
· 柔光背景:同样可调节光晕的色相、饱和度与明度,让整体氛围色调随心而变。
· 自定义背景:支持照片与视频统一入库管理——首次使用预置一张极小的默认背景示例图(可删除);可上传多张媒体、缩略图带类型角标、任意一张可单独删除;每张媒体会独立记住你的调色设置,选中即自动恢复;上传的文件以原始画质存储(不再压缩降清晰度);视频作为背景时自动循环播放,并加入首尾帧渐变交接,消除循环时的顿挫感。另有:背景网格线开关与透明度滑杆、卡片贴片模糊滑杆;所有滑杆悬停时会显示各自的功能说明。
· 自定义背景:支持照片与视频统一入库管理——首次使用预置两张默认背景示例图——极光渐变与海岸风景(均可删除);可上传多张媒体、缩略图带类型角标、任意一张可单独删除;每张媒体会独立记住你的调色设置,选中即自动恢复;上传的文件以原始画质存储(不再压缩降清晰度);视频作为背景时自动循环播放,并加入首尾帧渐变交接,消除循环时的顿挫感。另有:背景网格线开关与透明度滑杆、卡片贴片模糊滑杆;所有滑杆悬停时会显示各自的功能说明。
【1.4 每行项目数】自由调整控制台每行显示的瓷片数量(1–5 张),拖拽滑杆即时生效并配平滑动画。
+8
View File
@@ -1,2 +1,10 @@
/** 默认背景示例图(SVG 渐变极光,约 1KB):首次使用自定义背景时预置到媒体库,可选用/可删除。 */
/** base64 转 Blob(内置默认图用) */
export function b64ToBlob(b64: string, type: string): Blob {
const bin = atob(b64)
const arr = new Uint8Array(bin.length)
for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i)
return new Blob([arr], { type })
}
export const DEFAULT_BG_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720"><defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#0a0d13"/><stop offset="1" stop-color="#101a2e"/></linearGradient><radialGradient id="b1"><stop offset="0" stop-color="#4f8ef7" stop-opacity="0.55"/><stop offset="1" stop-color="#4f8ef7" stop-opacity="0"/></radialGradient><radialGradient id="b2"><stop offset="0" stop-color="#7a5cff" stop-opacity="0.45"/><stop offset="1" stop-color="#7a5cff" stop-opacity="0"/></radialGradient><radialGradient id="b3"><stop offset="0" stop-color="#00c2ff" stop-opacity="0.4"/><stop offset="1" stop-color="#00c2ff" stop-opacity="0"/></radialGradient><radialGradient id="b4"><stop offset="0" stop-color="#ff9a3d" stop-opacity="0.28"/><stop offset="1" stop-color="#ff9a3d" stop-opacity="0"/></radialGradient></defs><rect width="1280" height="720" fill="url(#g)"/><ellipse cx="300" cy="180" rx="420" ry="260" fill="url(#b1)"/><ellipse cx="980" cy="220" rx="380" ry="240" fill="url(#b2)"/><ellipse cx="760" cy="560" rx="420" ry="250" fill="url(#b3)"/><ellipse cx="180" cy="600" rx="300" ry="200" fill="url(#b4)"/></svg>'
+3 -1
View File
@@ -4,7 +4,8 @@ import { NS, zh, en, type WorktableKey } from './locales'
import { isAbs, joinPath, parentPathOf, basenameOf } from './pathutil'
import { splitStore, SplitWorkspace, setSplitT, setSplitEnv, type LayoutSpec, type SplitPane, type ConsoleCardData } from './split'
import { photoStore, kindOf } from './photoStore'
import { DEFAULT_BG_SVG } from './defaultBg'
import { DEFAULT_BG_SVG, b64ToBlob } from './defaultBg'
import { WAVE_BG_B64 } from './waveBg'
/**
* dsh-worktable 客户端(v2):侧边栏底部「工作台」区块。
@@ -1406,6 +1407,7 @@ function WorktableSection(props: any) {
if (records.length === 0 && localStorage.getItem('dsh.worktable.defaultBgSeeded.v1') !== '1') {
try {
await photoStore.add(new Blob([DEFAULT_BG_SVG], { type: 'image/svg+xml' }))
await photoStore.add(b64ToBlob(WAVE_BG_B64, 'image/jpeg'))
localStorage.setItem('dsh.worktable.defaultBgSeeded.v1', '1')
records = await photoStore.list().catch(() => [])
} catch {}
+1 -1
View File
@@ -1946,7 +1946,7 @@ function ConsolePane() {
<div className="dsh-wt_hslRow" data-tip={T('console.bgTipH')}><span className="dsh-wt_hslLabel">H</span><input className="dsh-wt_hslSlider" type="range" min={-180} max={180} step={1} value={v.h} onChange={(e) => editHsl(bgEdit, { h: Number(e.target.value) })} /><HslValInput value={v.h} min={-180} max={180} onCommit={(n) => editHsl(bgEdit, { h: n })} /></div>
<div className="dsh-wt_hslRow" data-tip={T('console.bgTipS')}><span className="dsh-wt_hslLabel">S</span><input className="dsh-wt_hslSlider" type="range" min={0} max={sMax} step={1} value={v.s} onChange={(e) => editHsl(bgEdit, { s: Number(e.target.value) })} /><HslValInput value={v.s} max={sMax} onCommit={(n) => editHsl(bgEdit, { s: n })} /></div>
<div className="dsh-wt_hslRow" data-tip={T('console.bgTipL')}><span className="dsh-wt_hslLabel">L</span><input className="dsh-wt_hslSlider" type="range" min={0} max={lMax} step={1} value={v.l} onChange={(e) => editHsl(bgEdit, { l: Number(e.target.value) })} /><HslValInput value={v.l} max={lMax} onCommit={(n) => editHsl(bgEdit, { l: n })} /></div>
<button type="button" className="dsh-wt_hslReset" onClick={() => resetHsl(bgEdit)}>{T('console.bgEditReset')}(含 B/T)</button>
<button type="button" className="dsh-wt_hslReset" onClick={() => resetHsl(bgEdit)}>{T('console.bgEditReset')}</button>
</>)
})()}
</div>
File diff suppressed because one or more lines are too long
+20
View File
@@ -0,0 +1,20 @@
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$src = 'G:\01 Media\02 Video\20260423 意、西、葡\【无人机】\20260511-2西岸沿海公路(Praia da Arriba)\Sea01.jpg'
$img = [System.Drawing.Image]::FromFile($src)
$max = 1280
$scale = [Math]::Min(1.0, $max / [Math]::Max($img.Width, $img.Height))
$w = [int][Math]::Max(1, [Math]::Round($img.Width * $scale))
$h = [int][Math]::Max(1, [Math]::Round($img.Height * $scale))
$bmp = New-Object System.Drawing.Bitmap($w, $h)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.InterpolationMode = 'HighQualityBicubic'
$g.DrawImage($img, 0, 0, $w, $h)
$enc = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object MimeType -eq 'image/jpeg'
$ep = New-Object System.Drawing.Imaging.EncoderParameters(1)
$ep.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, [long]82)
$out = 'C:\Users\SJL\AppData\Local\Temp\wave-bg.jpg'
$bmp.Save($out, $enc, $ep)
$g.Dispose(); $bmp.Dispose(); $img.Dispose()
$f = Get-Item $out
'{0}x{1} -> {2:N0} KB' -f $w, $h, ($f.Length/1KB)