从 Axolotl 1.9.7 移植皮肤编辑器的盔甲/盔甲纹饰预览功能, 让玩家在皮肤选择页可试穿盔甲并调整纹饰。 新增: - 前端组件 ArmorTrimTab / SkinListSkeleton 及 skin-armor-preview helper - packages/ui 组件 ArmorPreviewControls / ArmorTrimPanel - packages/ui armor 预览 composable(armor-preview-assets/types、use-armor-preview) - packages/ui webgl 盔甲渲染(armor-geometry / armor-preview-object / armor-rendering) - packages/ui/src/assets/minecraft-armor 盔甲素材 改动: - SkinPreviewRenderer 增加 armorPreview/armorControls props、 armorConfig model 与 useArmorPreview 集成 - Skins.vue 增加盔甲 tab、状态逻辑与模板接入 - 补齐 skin/composables/utils 的导出 适配说明:ArmorPreviewControls 原版依赖 reka-ui 的 popover, Starlight 无该依赖且只用 external 模式,故改写为 external-only, 去除 reka-ui 与 overlays.css 依赖。
This commit is contained in:
1 parent
20d5d2baab
commit
ae2992d7f8
151 files changed
+1936
-32
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
ARMOR_SLOTS,
|
||||
ARMOR_TRIM_MATERIALS,
|
||||
ARMOR_TRIM_PATTERNS,
|
||||
armorMaterialsForSlot,
|
||||
type ArmorPreviewConfig,
|
||||
createDefaultArmorPreviewConfig,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
const STORAGE_KEY = 'axolotl:skin-armor-preview'
|
||||
|
||||
function includes<T extends string>(values: readonly T[], value: unknown): value is T {
|
||||
return typeof value === 'string' && values.some((item) => item === value)
|
||||
}
|
||||
|
||||
export function loadSkinArmorPreview(): ArmorPreviewConfig {
|
||||
const config = createDefaultArmorPreviewConfig()
|
||||
try {
|
||||
const saved = JSON.parse(globalThis.localStorage?.getItem(STORAGE_KEY) ?? 'null')
|
||||
if (!saved || typeof saved !== 'object' || Array.isArray(saved)) return config
|
||||
|
||||
for (const slot of ARMOR_SLOTS) {
|
||||
const piece = saved[slot]
|
||||
if (!piece || typeof piece !== 'object' || Array.isArray(piece)) continue
|
||||
if (piece.material === null || includes(armorMaterialsForSlot(slot), piece.material)) {
|
||||
config[slot].material = piece.material
|
||||
}
|
||||
if (piece.trimPattern === null || includes(ARMOR_TRIM_PATTERNS, piece.trimPattern)) {
|
||||
config[slot].trimPattern = piece.trimPattern
|
||||
}
|
||||
if (includes(ARMOR_TRIM_MATERIALS, piece.trimMaterial)) {
|
||||
config[slot].trimMaterial = piece.trimMaterial
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Invalid or unavailable local storage falls back to a fresh preview.
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
export function saveSkinArmorPreview(config: ArmorPreviewConfig): void {
|
||||
try {
|
||||
globalThis.localStorage?.setItem(STORAGE_KEY, JSON.stringify(config))
|
||||
} catch {
|
||||
// The preview remains usable when local storage is unavailable.
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user