feat(fitting): 试衣间布局 v2.1——紧凑预览 300vp+三列纯图卡+全屏查看器(设计师 Agent 出稿)
- 预览区 3:4 大图(437vp/占屏57%) → 固定 300vp + Contain 不裁切(用户要求预览变小且不裁切) - 新增 ImageViewer 全屏查看器:点预览/生成完成自动弹出;原图|效果图页签与预览角标共用 showOriginal;保存走三态口径 - 衣橱网格双列带文字行 → 三列纯图卡(104×139,品类图内左下角标),首屏可见 6 卡 vs 原 3 卡 - 试穿胶囊 52×120→44×96、品类 chips 高 32→28、角标 12→11 - 设计稿:docs/美搭配与美学诊断-UI规范.md §10(含 7 条冲突修订表与 8 条验收)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* CapsuleButton —— 「试穿」黑色竖向胶囊(《美搭配与美学诊断-UI规范》§3/§7,需求 v2 §3.2)。
|
||||
*
|
||||
* 形态:52×120 竖条(高约 120vp,对齐参考站),黑底白字 14(COLOR_BLACK_CAPSULE),
|
||||
* 形态:44×96 竖条(v2.1 §10.4 紧凑化),黑底白字 14(COLOR_BLACK_CAPSULE),
|
||||
* 右缘悬浮垂直居中;未选上衣/未传本人照/生成中置灰(§2 主按钮禁用态:
|
||||
* 底 COLOR_DIVIDER、字 COLOR_TEXT_DISABLED)。label 支持换行竖排(如 '试\n穿')。
|
||||
*/
|
||||
@@ -22,10 +22,10 @@ export struct CapsuleButton {
|
||||
.fontColor(this.isActive ? Color.White : COLOR_TEXT_DISABLED)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(52)
|
||||
.height(120)
|
||||
.width(44)
|
||||
.height(96)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.borderRadius(26)
|
||||
.borderRadius(22)
|
||||
.backgroundColor(this.isActive ? COLOR_BLACK_CAPSULE : COLOR_DIVIDER)
|
||||
.onClick(() => {
|
||||
if (this.isActive) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* CategoryChip —— 品类 chip(《美搭配与美学诊断-UI规范》§3/§7)。
|
||||
*
|
||||
* 形态:高约 32 胶囊;选中黑底白字(COLOR_BLACK_CAPSULE,试衣间专属黑),
|
||||
* 形态:高约 28 胶囊(§10.4 紧凑化);选中黑底白字(COLOR_BLACK_CAPSULE,试衣间专属黑),
|
||||
* 未选白底 + COLOR_DIVIDER 描边。用于品类过滤条与「添加衣服」品类弹层。
|
||||
* selected 随父层状态变化,必须 @Prop(普通成员只在创建时赋值一次,不随父刷新)。
|
||||
*/
|
||||
@@ -16,11 +16,11 @@ export struct CategoryChip {
|
||||
|
||||
build() {
|
||||
Text(this.label)
|
||||
.fontSize(13)
|
||||
.fontSize(12)
|
||||
.fontColor(this.selected ? Color.White : COLOR_TEXT_PRIMARY)
|
||||
.padding({ left: 14, right: 14, top: 6, bottom: 6 })
|
||||
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
||||
.backgroundColor(this.selected ? COLOR_BLACK_CAPSULE : Color.White)
|
||||
.borderRadius(16)
|
||||
.borderRadius(14)
|
||||
.border({
|
||||
width: 1,
|
||||
color: this.selected ? Color.Transparent : COLOR_DIVIDER
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
/**
|
||||
* ClothCard —— 衣橱服装卡(《美搭配与美学诊断-UI规范》§3/§7)。
|
||||
* ClothCard —— 衣橱服装卡(《美搭配与美学诊断-UI规范》§10.2 v2.1 三列纯图卡)。
|
||||
*
|
||||
* 形态:白底圆角 12;服装图 aspectRatio 3:4 Cover;名称 13 Medium 单行截断;
|
||||
* 品类 11 Secondary;右上角:槽位角标(选中时,主色底)+ 删除角标(20×20 圆,黑 60%)。
|
||||
* 选中态:2vp COLOR_PRIMARY 描边(点选=设入槽位,再点取消)。
|
||||
* 本机文件被清时 Image onError → 「已失效,点按删除」占位(需求 §4.1 ④)。
|
||||
*
|
||||
* 结构说明:角标行与卡片主体是 Stack 兄弟节点(非父子),点击角标不会
|
||||
* 误触卡片的选择事件;item 内容按 id 恒定(普通成员),selected/slotLabel
|
||||
* 随父层选择状态变化,必须 @Prop。
|
||||
* 形态:图 3:4 Cover(约 104×139),无名称/品类文字行(三列窄卡放不下,
|
||||
* 品类改图内左下小角标:黑 60% 底白字 10);选中 2vp 主色描边 + 右上槽位角标;
|
||||
* 我的衣橱卡保留 20×20 删除角标,内置精选(rawfilePath 非空)无删除、无失效态。
|
||||
* 结构说明:角标行与卡片主体是 Stack 兄弟节点(非父子),点击角标不会误触选择;
|
||||
* selected/slotLabel 随父层选择状态变化,必须 @Prop。
|
||||
*/
|
||||
|
||||
import { fileUri } from '@kit.CoreFileKit'
|
||||
@@ -17,7 +14,6 @@ import {
|
||||
COLOR_BADGE_BG,
|
||||
COLOR_IMAGE_BG,
|
||||
COLOR_PRIMARY,
|
||||
COLOR_TEXT_PRIMARY,
|
||||
COLOR_TEXT_SECONDARY
|
||||
} from '../../core/Theme'
|
||||
|
||||
@@ -47,37 +43,36 @@ export struct ClothCard {
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.padding(8)
|
||||
.backgroundColor(COLOR_IMAGE_BG)
|
||||
} else if (this.rawfilePath !== '') {
|
||||
Image($rawfile(this.rawfilePath))
|
||||
.width('100%')
|
||||
.aspectRatio(3 / 4)
|
||||
.objectFit(ImageFit.Cover)
|
||||
} else {
|
||||
Image(fileUri.getUriFromPath(this.item.uri))
|
||||
.width('100%')
|
||||
.aspectRatio(3 / 4)
|
||||
.objectFit(ImageFit.Cover)
|
||||
.onError(() => {
|
||||
this.loadFailed = true
|
||||
})
|
||||
Stack({ alignContent: Alignment.BottomStart }) {
|
||||
if (this.rawfilePath !== '') {
|
||||
Image($rawfile(this.rawfilePath))
|
||||
.width('100%')
|
||||
.aspectRatio(3 / 4)
|
||||
.objectFit(ImageFit.Cover)
|
||||
} else {
|
||||
Image(fileUri.getUriFromPath(this.item.uri))
|
||||
.width('100%')
|
||||
.aspectRatio(3 / 4)
|
||||
.objectFit(ImageFit.Cover)
|
||||
.onError(() => {
|
||||
this.loadFailed = true
|
||||
})
|
||||
}
|
||||
// 左下品类角标(黑 60% 底白字 10)
|
||||
Text(this.item.category)
|
||||
.fontSize(10)
|
||||
.fontColor(Color.White)
|
||||
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
|
||||
.borderRadius(8)
|
||||
.backgroundColor(COLOR_BADGE_BG)
|
||||
.margin(6)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
Column({ space: 2 }) {
|
||||
Text(this.item.name)
|
||||
.fontSize(13)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.fontColor(COLOR_TEXT_PRIMARY)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
Text(this.item.category)
|
||||
.fontSize(11)
|
||||
.fontColor(COLOR_TEXT_SECONDARY)
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ left: 10, right: 10, top: 8, bottom: 10 })
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.width('100%')
|
||||
.backgroundColor(Color.White)
|
||||
.backgroundColor(COLOR_IMAGE_BG)
|
||||
.borderRadius(12)
|
||||
.clip(true)
|
||||
.border({
|
||||
@@ -92,19 +87,20 @@ export struct ClothCard {
|
||||
}
|
||||
})
|
||||
|
||||
// 右上角标行(槽位角标 + 删除角标,右上 6;内置精选无删除)
|
||||
|
||||
// 右上角标行(槽位角标 + 删除角标;内置精选无删除)
|
||||
Row({ space: 4 }) {
|
||||
if (this.slotLabel !== '') {
|
||||
Text(this.slotLabel)
|
||||
.fontSize(11)
|
||||
.fontSize(10)
|
||||
.fontColor(Color.White)
|
||||
.padding({ left: 8, right: 8, top: 3, bottom: 3 })
|
||||
.borderRadius(10)
|
||||
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
|
||||
.borderRadius(8)
|
||||
.backgroundColor(COLOR_PRIMARY)
|
||||
}
|
||||
if (this.rawfilePath === '') {
|
||||
Text('×')
|
||||
.fontSize(14)
|
||||
.fontSize(13)
|
||||
.fontColor(Color.White)
|
||||
.width(20)
|
||||
.height(20)
|
||||
@@ -116,7 +112,7 @@ export struct ClothCard {
|
||||
})
|
||||
}
|
||||
}
|
||||
.margin(6)
|
||||
.margin(4)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* ImageViewer —— 试衣间全屏图片查看器(《美搭配与美学诊断-UI规范》§10.3)。
|
||||
*
|
||||
* 形态:全屏覆盖层,底 COLOR_BLACK_CAPSULE(#1A1A1A);顶部 ×关闭 + 「原图/效果图」
|
||||
* 页签(仅 hasResult 时显示页签,模特态只有 ×);图 Contain 宽 100%-32 居中,
|
||||
* 点图切换原图/效果——与页面预览共用父层 showOriginal(@Link 双向);底部
|
||||
* 「保存到相册」主按钮(走父层既有三态口径)+「再来一次」文字链(仅结果态)。
|
||||
* 关闭:点 × / 系统返回由父层 onBackPress 处理(viewerOpen 状态门闩)。
|
||||
*/
|
||||
|
||||
import {
|
||||
COLOR_BLACK_CAPSULE,
|
||||
COLOR_PRIMARY
|
||||
} from '../../core/Theme'
|
||||
|
||||
@Component
|
||||
export struct ImageViewer {
|
||||
@Link showOriginal: boolean // 与页面预览共用:false=效果图优先
|
||||
hasResult: boolean = false
|
||||
originalSrc: string = ''
|
||||
resultSrc: string = ''
|
||||
onSave: () => void = () => {}
|
||||
onRetry: () => void = () => {}
|
||||
onClose: () => void = () => {}
|
||||
|
||||
private currentSrc(): string {
|
||||
if (this.hasResult && !this.showOriginal) {
|
||||
return this.resultSrc
|
||||
}
|
||||
return this.originalSrc
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
Column() {
|
||||
// 顶栏 56:× 距左 16;页签仅结果态
|
||||
Stack({ alignContent: Alignment.Start }) {
|
||||
Text('×')
|
||||
.fontSize(24)
|
||||
.fontColor(Color.White)
|
||||
.width(40)
|
||||
.height(40)
|
||||
.textAlign(TextAlign.Center)
|
||||
.onClick(() => {
|
||||
this.onClose()
|
||||
})
|
||||
if (this.hasResult) {
|
||||
Row({ space: 24 }) {
|
||||
this.TabItem('原图', !this.showOriginal)
|
||||
this.TabItem('效果图', this.showOriginal)
|
||||
}
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height(56)
|
||||
|
||||
// 图:Contain 宽 100%-32 居中,点图切换
|
||||
Image(this.currentSrc())
|
||||
.width('100%')
|
||||
.layoutWeight(1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 16, right: 16, top: 4, bottom: 8 })
|
||||
.onClick(() => {
|
||||
if (this.hasResult) {
|
||||
this.showOriginal = !this.showOriginal
|
||||
}
|
||||
})
|
||||
|
||||
// 底区:保存主按钮 + 再来一次(仅结果态显示两者;模特态留白)
|
||||
Column({ space: 10 }) {
|
||||
if (this.hasResult) {
|
||||
Button('保存到相册')
|
||||
.width('100%')
|
||||
.height(48)
|
||||
.borderRadius(24)
|
||||
.fontSize(16)
|
||||
.backgroundColor(COLOR_PRIMARY)
|
||||
.onClick(() => {
|
||||
this.onSave()
|
||||
})
|
||||
Text('再来一次')
|
||||
.fontSize(13)
|
||||
.fontColor(Color.White)
|
||||
.padding({ top: 4, bottom: 8 })
|
||||
.onClick(() => {
|
||||
this.onRetry()
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ left: 32, right: 32, bottom: 20 })
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor(COLOR_BLACK_CAPSULE)
|
||||
}
|
||||
|
||||
@Builder
|
||||
TabItem(label: string, active: boolean) {
|
||||
Column({ space: 4 }) {
|
||||
Text(label)
|
||||
.fontSize(13)
|
||||
.fontColor(active ? Color.White : '99FFFFFF')
|
||||
Row()
|
||||
.width('100%')
|
||||
.height(3)
|
||||
.borderRadius(2)
|
||||
.backgroundColor(active ? Color.White : Color.Transparent)
|
||||
}
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.onClick(() => {
|
||||
this.showOriginal = label === '原图'
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import { FacePhotoConsent, FaceConsentStore } from '../components/f2/FacePhotoCo
|
||||
import { CategoryChip } from '../components/f2/CategoryChip'
|
||||
import { ClothCard } from '../components/f2/ClothCard'
|
||||
import { CapsuleButton } from '../components/f2/CapsuleButton'
|
||||
import { ImageViewer } from '../components/f2/ImageViewer'
|
||||
|
||||
/** 品类过滤 chips:全部 + 五品类(UI 规范 §8 文案)。 */
|
||||
const FILTER_CHIPS: string[] = ['全部'].concat(CLOTH_CATEGORIES)
|
||||
@@ -73,6 +74,7 @@ struct FittingRoomPage {
|
||||
@State lastLocalPath: string = '' // 「上次结果」卡数据源
|
||||
@State showOriginal: boolean = false
|
||||
@State showLeaveConfirm: boolean = false // 生成中离开的挽留确认
|
||||
@State viewerOpen: boolean = false // 全屏图片查看器(§10.3)
|
||||
// —— 高级项 ——
|
||||
@State desc: string = ''
|
||||
@State advancedOpen: boolean = false
|
||||
@@ -359,7 +361,8 @@ struct FittingRoomPage {
|
||||
if (gen !== this.genSeq) {
|
||||
return
|
||||
}
|
||||
this.statusText = saved ? '生成完成,点预览图可对比原图' : '结果已生成,本地暂存失败,请尽快保存到相册'
|
||||
this.statusText = saved ? '生成完成,点图可查看大图' : '结果已生成,本地暂存失败,请尽快保存到相册'
|
||||
this.viewerOpen = true // 生成完成自动弹全屏查看器恰一次(§10.1)
|
||||
} catch (e) {
|
||||
if (gen === this.genSeq) {
|
||||
this.statusText = e instanceof ApiError ? `${e.message}${e.hint ? ':' + e.hint : ''}` : '生成失败,请重试'
|
||||
@@ -392,6 +395,10 @@ struct FittingRoomPage {
|
||||
}
|
||||
|
||||
onBackPress(): boolean {
|
||||
if (this.viewerOpen) {
|
||||
this.viewerOpen = false
|
||||
return true
|
||||
}
|
||||
if (this.generating) {
|
||||
this.showLeaveConfirm = true
|
||||
return true // 拦截系统返回,交由挽留确认处理
|
||||
@@ -564,27 +571,27 @@ struct FittingRoomPage {
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor(COLOR_IMAGE_BG)
|
||||
} else {
|
||||
// 本人照/结果大图:有结果时点图切换 原图/效果 对比(沿用 v1)
|
||||
Image(this.previewSrc())
|
||||
// 本人照/结果大图(Contain 不裁切,§10.1):点图开全屏查看器
|
||||
Image(this.showOriginal || this.resultSrc === '' ? this.humanUri : this.resultSrc)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.objectFit(ImageFit.Cover)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(() => {
|
||||
if (this.resultUrl.length > 0 && !this.generating) {
|
||||
this.showOriginal = !this.showOriginal
|
||||
if (!this.generating && this.humanUri.length > 0) {
|
||||
this.viewerOpen = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 左上「模特/效果图」角标(黑 60% 胶囊,白字 12,距边 12)
|
||||
// 左上「模特/效果图」角标(黑 60% 胶囊,白字 11,距边 10,§10.4)
|
||||
if (this.humanUri.length > 0) {
|
||||
Text(this.showOriginal || this.resultSrc === '' ? '模特' : '效果图')
|
||||
.fontSize(12)
|
||||
.fontSize(11)
|
||||
.fontColor(Color.White)
|
||||
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
|
||||
.borderRadius(14)
|
||||
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
||||
.borderRadius(12)
|
||||
.backgroundColor(COLOR_BADGE_BG)
|
||||
.position({ x: 12, y: 12 })
|
||||
.position({ x: 10, y: 10 })
|
||||
}
|
||||
|
||||
// 右缘悬浮「试穿」黑胶囊:覆盖层自身不参与命中(None),点击落到图上
|
||||
@@ -637,7 +644,8 @@ struct FittingRoomPage {
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.aspectRatio(3 / 4) // 3:4 竖版:与生成结果(768x1024)/人像照同比例,Cover 不再裁成正方形
|
||||
.height(300) // 紧凑预览(§10.1):固定 300vp,占屏约 38%
|
||||
.backgroundColor(COLOR_IMAGE_BG) // Contain 灰边底
|
||||
.borderRadius(16)
|
||||
.clip(true)
|
||||
.margin({ left: 16, right: 16, top: 8, bottom: 8 })
|
||||
@@ -794,9 +802,9 @@ struct FittingRoomPage {
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
.columnsTemplate('1fr 1fr')
|
||||
.columnsGap(12)
|
||||
.rowsGap(12)
|
||||
.columnsTemplate('1fr 1fr 1fr')
|
||||
.columnsGap(8)
|
||||
.rowsGap(8)
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
@@ -834,9 +842,9 @@ struct FittingRoomPage {
|
||||
}
|
||||
}, (it: WardrobeItem) => this.cardKey(it) + '_b')
|
||||
}
|
||||
.columnsTemplate('1fr 1fr')
|
||||
.columnsGap(12)
|
||||
.rowsGap(12)
|
||||
.columnsTemplate('1fr 1fr 1fr')
|
||||
.columnsGap(8)
|
||||
.rowsGap(8)
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
@@ -1172,6 +1180,25 @@ struct FittingRoomPage {
|
||||
if (this.showAddSheet) {
|
||||
this.AddCategorySheet()
|
||||
}
|
||||
// 全屏图片查看器(§10.3):与预览共用 showOriginal/resultSrc
|
||||
if (this.viewerOpen) {
|
||||
ImageViewer({
|
||||
showOriginal: $showOriginal,
|
||||
hasResult: this.resultUrl.length > 0,
|
||||
originalSrc: this.humanUri,
|
||||
resultSrc: this.resultSrc,
|
||||
onSave: (): void => {
|
||||
this.saveResult()
|
||||
},
|
||||
onRetry: (): void => {
|
||||
this.viewerOpen = false
|
||||
this.resetResult()
|
||||
},
|
||||
onClose: (): void => {
|
||||
this.viewerOpen = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
|
||||
@@ -209,3 +209,100 @@ CTA 点击 → router 跳 DiagnosisFormPage。hero 为该页专属装饰,报
|
||||
3. 发型页 v2:双图+对比、分段控件、8 色圆点+名称、强度滑杆、吸底「应用发色」;旧三态与授权弹层行为不回归。
|
||||
4. 落地页:紫渐变 hero、5 条困扰卡、4 步步骤条、吸底「马上体验」跳填写页。
|
||||
5. 填写页:分组白卡表单、三个滚轮范围正确(100-250 / 25-300 / 年份)、必填校验+汇总条+滚动定位、隐私说明可见。
|
||||
|
||||
## 10. 试衣间布局 v2.1(FittingRoomPage 紧凑预览改版)
|
||||
|
||||
> 用户诉求:①预览区(现 3:4 大图 437vp、占屏约 57%)弄小;②我的/精选衣橱区弄大;③少滚动即可浏览选衣。
|
||||
> 本节与 §3 预览区规格、§9 验收 2 冲突处**以本节为准**,其余全部沿用。逻辑屏按 360×788vp 计算。
|
||||
|
||||
### 10.1 五项裁决
|
||||
|
||||
1. **预览 vs 不裁切 = 方案 a+c+d 组合**:预览固定高 **300vp** + `ImageFit.Contain` + 底 COLOR_IMAGE_BG(人像 3:4 渲染约 225×300 居中,两侧灰边各≈51vp)。理由:试穿必须看全全身,Cover 裁切直接劣化选衣判断且用户已投诉过「被裁切」,故预览态放弃 Cover(成为 §2 全 Cover 规则的唯一例外);小图看不全→**点图开全屏查看器**(§10.3);**生成完成后自动弹出查看器一次**(genSeq 守卫:取消/离开/迟到失效不弹,用户关闭后不重复弹)。空态(未传本人照)预览仍 300vp,占位内容居中沿用。
|
||||
2. **网格三列、纯图卡**:列/行距 8;卡宽≈104、图 104×139(3:4 Cover)。**去掉名称与品类两行文字**(104vp 窄卡放不下、品类已可由 chips 过滤),品类改为图内左下小角标;槽位角标与删除 × 保留右上。首屏可见 ≥2 整行=6 卡(原双列带文字约 3 卡)。
|
||||
3. **生成中/结果态**:生成中覆盖层压在 300vp 预览内(黑 60%):Loading 36 + 状态文案 12(最多 2 行)+ 秒数 16 + 「取消生成」高 28;结果操作行「保存到相册/再来一次」保留在预览下方原位不动;查看器内另设「保存到相册」主按钮。
|
||||
4. **胶囊/角标缩小**:「试穿」黑胶囊 **44×96**(原 52×120)、圆角 22、白字 14,右缘距预览右边 12、垂直居中,置灰条件沿用;「模特/效果图」角标字号 12→**11**、内边距 10×6、距边 10(对齐 §2 角标 11)。
|
||||
5. **全屏查看器**:全屏覆盖层、底 COLOR_BLACK_CAPSULE(#1A1A1A,复用不新增色值);与页面**共用 `showOriginal` 状态**——页签、预览左上角标、图源三处同步。
|
||||
|
||||
### 10.2 整页线框(紧凑预览版)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐ 360vp
|
||||
│ ‹ 返回 试衣间 │ 顶栏48 沿用
|
||||
├──────────────────────────────────┤
|
||||
│ ┌──────────────────────────────┐ │ 预览卡:margin16/8 高300 固定
|
||||
│ │[模特]11 ┌────┐ │ │ 底#EDEFF3 圆角16 clip
|
||||
│ │ ┌───────────┐ │试 │ │ │ 图 Contain 225×300 居中
|
||||
│ │ │ 全身完整 │ │穿 │ │ │ 两侧灰边各≈51 不裁切
|
||||
│ │ │ 不裁切 │ └────┘ │ │ 点图→全屏查看器(§10.3)
|
||||
│ │ └───────────┘ 44×96 │ │ 生成中:黑60%覆盖层
|
||||
│ └──────────────────────────────┘ │
|
||||
│ 请先选择一件上衣… / 状态/合规提示 │ 12 条件行 ≤20vp(沿用)
|
||||
├──────────────────────────────────┤
|
||||
│ 我的衣橱 精选衣橱 │ Tab32 沿用(主色3vp下划线)
|
||||
│ (全部)(上衣)(下装)(连衣裙)(外套)(套装)→│ chips高28 横滚 选中黑底白字
|
||||
├──────────────────────────────────┤
|
||||
│ ┌──────┐ ┌──────┐ ┌──────┐ │ 三列:列距8 行距8
|
||||
│ │ 图3:4 │ │ 图3:4 │[×] 图3:4 │ │ 卡宽104 图104×139 Cover
|
||||
│ │[上衣] │ │[下装] │ │ │ │ 左下品类角标(黑60%字10)
|
||||
│ └──────┘ └──────┘ └──────┘ │ 选中2vp主色描边+右上槽位角标
|
||||
│ ┌──────┐ ┌──────┐ ┌──────┐ │ 第2行 首屏完整可见
|
||||
│ │ 图 │ │ + │ │ 图 │ │ 末位添加卡:+24/添加12
|
||||
│ └──────┘ └──────┘ └──────┘ │ 底部「拍照」11 主色
|
||||
├────── ↓ 以下滚动 ↓ ───────────────┤
|
||||
│ 保存到相册 再来一次 │ 结果操作行(条件,沿用)
|
||||
│ 连衣裙、外套、套装按上衣流程… │ 脚注11+高级提示词+上次结果卡
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
垂直预算(788vp):顶栏 48 + 预览块 316(图 300+上下边距 16,占屏 40%,原 453/57%)+ 提示行 ≤20 + 滚动区 ≥404(Tab 32 + chips 36 + 网格首屏 ≥2 整行 286)。
|
||||
|
||||
### 10.3 全屏查看器线框
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐ 全屏覆盖层 底#1A1A1A
|
||||
│ × 原图 效果图 │ 顶56:×白24 距左16;页签白13
|
||||
│ ───── │ 当前=白+3vp白下划线;未选白60%
|
||||
│ │ 仅 resultUrl 非空显页签;
|
||||
│ ┌────────────┐ │ 模特态仅「×」无页签
|
||||
│ │ 原图/效果图 │ │ 图 Contain 宽100%-32 居中
|
||||
│ │ 3:4 居中 │ │ 高=顶部56与底区之外全部
|
||||
│ └────────────┘ │ 点图=切原图/效果(共用
|
||||
│ │ showOriginal,关闭后预览同步)
|
||||
│ [ 保存到相册 ] │ 主按钮 高48 圆角24 主色白字16
|
||||
│ 再来一次 │ 白13 文字链(仅结果态显示)
|
||||
└──────────────────────────────────┘
|
||||
关闭:点 × / 系统返回;保存成功回填状态文案「已保存到相册」(沿用三态口径)。
|
||||
```
|
||||
|
||||
### 10.4 尺寸与 §2/§3 冲突修订清单
|
||||
|
||||
| # | 原规则 | v2.1 修订 |
|
||||
|---|---|---|
|
||||
| 1 | §2 图片一律 ImageFit.Cover | 试衣间预览/查看器改 **Contain**(唯一例外) |
|
||||
| 2 | §2 列表/网格间距 12 | 试衣间网格列/行距 **8** |
|
||||
| 3 | §3 预览区高=屏 45% | 固定 **300vp**(含边距占屏 40%) |
|
||||
| 4 | §3 双列 3:4 卡+名称13+品类11 | **三列纯图卡**(104×139,无文字行) |
|
||||
| 5 | §3 角标白字 12、内边距 8×12、距边 12 | 字 **11**、内边距 10×6、距边 10 |
|
||||
| 6 | §3「试穿」胶囊 52×120 | **44×96** 圆角 22 |
|
||||
| 7 | §3 品类条 chips 高 32 | **28**(字 12、内边距 10×6、圆角 14) |
|
||||
|
||||
新增组件:**ImageViewer**(components/f2/ImageViewer.ets,@Component 导出;参数:imageSrc、hasResult、showOriginal 双向、onSave、onRetry、onClose)。
|
||||
|
||||
### 10.5 新增文案(逐字,其余沿用 §8)
|
||||
|
||||
| 位置 | 文案 |
|
||||
|---|---|
|
||||
| 试衣间·查看器页签 | 原图 / 效果图 |
|
||||
| 试衣间·查看器关闭 | ×(图标,无朗读文案需求,无文字) |
|
||||
| 试衣间·卡片品类角标 | 沿用品类词:上衣 / 下装 / 连衣裙 / 外套 / 套装 |
|
||||
|
||||
### 10.6 验收清单(可自动化判定)
|
||||
|
||||
1. 360×788vp 下预览块高(含上下边距)=316vp 固定;图 ImageFit.Contain、底 #EDEFF3、无裁切。
|
||||
2. 无状态提示行时,衣橱网格首屏完整可见 2 行 × 3 列(≥6 卡),Tab/chips 无需滚动。
|
||||
3. 网格 3 列、列/行距 8;服装卡无名称/品类文字行、左下品类角标;选中态 2vp #C2185B 描边+右上槽位角标;我的衣橱卡保留 20×20 删除。
|
||||
4. 点预览图弹出全屏查看器;有结果时查看器页签与预览左上角标文案一致(同一 showOriginal 状态驱动)。
|
||||
5. 生成完成自动打开查看器恰一次(取消/离开/迟到失效不弹);查看器「保存到相册」走系统保存对话框三态口径。
|
||||
6. 「试穿」胶囊 44×96 右缘悬浮、未选上衣/生成中置灰不可点(沿用);生成中覆盖层四要素(Loading/文案≤2行/秒数/取消)在 300vp 内完整显示。
|
||||
7. 「+添加」卡在网格末位,含相册(点卡)与拍照(底部链接)两入口(沿用)。
|
||||
8. 除查看器底与胶囊复用 #1A1A1A 外无新增色值;§3/§9.2 与本节冲突处按本表 §10.4 执行。
|
||||
|
||||
Reference in New Issue
Block a user