【共创稿事节】HarmonyOS 7空间排布原则:视锥、舒适区与可达性
空间界面里能放东西的地方看似无限实际上有一圈硬边界看得清的、够得着的、待着不累的只有一个有限的区域。把内容丢到视野边缘或者手臂够不着的地方用户就得转头、伸手、扭腰体验立刻掉档。这篇讲三件事——视锥怎么限制可见范围、舒适区怎么界定体感、可达性怎么决定交互成本最后给一份能直接用的排布参数表。视锥看得见不等于看得清人眼不是均匀感光的。视野可以粗略分成三圈区域视角范围相对视线中心能力适合放什么中心凹视野约 ±5°最高分辨率、能读细节当前焦点、正文、关键数字舒适注视野约 ±30°清晰可读转头幅度小主要内容、卡片、按钮周边视野±30° ~ ±60°能感知、难辨认次要提示、状态、氛围边缘视野 ±60°有动静才注意不建议放需要读的信息垂直方向的可用范围比水平方向窄而且不对称向上看的舒适角度比向下小抬头久了脖子会酸。所以顶部内容的可用高度要留得更保守。这些角度决定了主内容区不能铺太开。超过 ±30° 的东西用户得转头才能看清一转原来的空间参照就丢了。稳妥的做法是把必须读的内容压在中心 ±30° 内把可感知不可读的内容放到 ±30°~60°再往外只放氛围和背景。舒适区距离决定体验同一块内容放远放近体验差别很大。按距离可以把空间分成几段区域视距参考用途交互方式近场阅读区0.35 ~ 0.6 m读正文、看细节、输入视线 手势精度要求高操作区0.6 ~ 1.2 m按钮、列表、卡片点选手势、控制器浏览区1.2 ~ 2.0 m浏览大图、卡片墙、场景视线、转向环境区2.0 m 以上背景、氛围、空间锚点一般不交互0.35m 以内太近眼睛要用力对焦容易疲劳1.2m 以上手势精度会明显下降因为手在空中画弧抖动被放大。交互目标越精细越要往近场放越只是看着的越可以往远放。手部可达性还要单独算一笔账。人手臂伸直大约 0.6~0.7m舒服的操作范围是前方偏下 0.4~0.6m、水平 ±30° 的锥形区里肩膀不动就能覆盖。超出这个范围的动作要么耸肩要么转体长时间会累。频繁操作的元素确认、返回、切换位置要固定在这个可达锥里别指望用户每次都大臂一挥。距离、角度与可读性内容在视野里占多大取决于两个量它自身的物理尺寸以及它到眼睛的距离。二者之比就是视角tan(视角/2) 元素尺寸 / (2 × 视距)推到实用结论元素尺寸要随视距线性放大。距离翻倍尺寸也得大致翻倍否则视觉大小减半、可读性掉档。人眼舒适阅读的字符视角大约在 0.3°~1° 之间低于 0.3° 就费劲了。这条规律对透视布局很关键用透视把内容推到远处z 变小时若不同步做大它就会缩成看不清的一小块。只要物理尺寸 / 视距这个比值稳定远近内容就能保持一致的视觉大小。Fitts 定律在 3D 里的延伸Fitts 定律原本描述 2D 点选到达目标的时间 T 与目标距离 D 和有效尺寸 W 有关T a b × log2(2D / W)距离越远、目标越小就越慢越容易错。到了 3D这条规律仍成立但多了几个变量D 是三维距离。不光左右上下前后也算。一个没那么远、但偏后的目标移动成本并不低。W 受视角影响。同样的物理尺寸放远了有效命中区域就小等效于 W 变小。指向有深度误差。手在空中的前后抖动最大深度方向上的精度最差所以 3D 目标在 z 方向要留更大容错。命中方式变了。视线点选有视线抖动手势点选有手部抖动两者叠加时误差更大。实用推论3D 目标要比 2D 更大尤其是在深度方向。常见的补偿手段有给目标加吸附范围、把常用操作固定在近场、用够得着就够得着的软吸附接近即命中而不是要求像素级对准。空间排布参数建议表下面这份表汇总了上面几条原则可以直接当作设计和评审的默认基线。数值是常规区间具体项目按设备形态头显、眼镜、裸眼 3D微调。参数建议值说明主内容水平视角±30° 内超出后转头成本明显上升主内容垂直视角向上 20°向下 -25°向上舒适度更差周边提示视角±30° ~ ±60°只放可感知信息正文阅读视距0.4 ~ 0.6 m近场配大字号交互目标视距0.5 ~ 1.0 m手势精度可接受浏览内容视距1.2 ~ 2.0 m看为主少交互环境背景视距2.0 m 以上不做交互最小可点击目标≥ 48 × 48 vp近场远场按视距等比放大深度容错z 方向≥ 目标尺寸的 0.3 倍深度方向抖动最大单屏主内容数量4 ~ 7 个与工作记忆容量匹配场景切换移动距离尽量 ≤ 60° 转头超过需给过渡提示按视锥和舒适区排布一组卡片把上面的规则写成代码。核心是两个辅助函数一个把视角换算成该视距下的物理尺寸一个判断某个位置是否落在舒适锥内。// SpatialLayout.ets —— 按视锥与舒适区约束排布卡片import{matrix4}fromkit.ArkUI;// 常用约束常量集中管理方便评审时对照constFOV{focus:30,// 舒适注视野半角度peripheral:60,// 周边视野半角度verticalUp:20,// 向上舒适半角verticalDown:25// 向下舒适半角}// 依据视角恒定原则给定视距与目标视角算出应设置的尺寸// 保证内容在不同深度上视觉大小一致functionsizeForViewAngle(distanceM:number,viewAngleDeg:number):number{constradviewAngleDeg*Math.PI/180// 返回米调用方再换算为 vp 或毫米return2*distanceM*Math.tan(rad/2)}// 判断某个极坐标位置是否落在水平舒适视锥内functioninComfortCone(angleDeg:number):boolean{returnMath.abs(angleDeg)FOV.focus}// 判断是否落在可见可感知范围functioninVisibleCone(angleDeg:number):boolean{returnMath.abs(angleDeg)FOV.peripheral}EntryComponentstruct SpatialCardWall{// 卡片数据角度偏移(度) 视距(米)privatecards:Array{title:string;angle:number;dist:number}[{title:推荐,angle:-24,dist:1.4},{title:关注,angle:-8,dist:1.4},{title:首页,angle:8,dist:1.4},{title:历史,angle:24,dist:1.4},{title:提示,angle:52,dist:2.2},// 周边视野只做感知{title:设置,angle:78,dist:2.2}// 超出周边仅氛围]// 1 米视距大约对应多少 vp用于把物理尺寸折算成布局单位privatereadonlyvpPerMeter:number900build(){Stack({alignContent:Alignment.Center}){ForEach(this.cards,(card:{title:string;angle:number;dist:number}){// 依据视距算出该卡片的宽度越远越大视觉大小保持一致constwidthVpsizeForViewAngle(card.dist,12)*this.vpPerMeter// 依据角度换算水平摆放位置constxVpcard.dist*this.vpPerMeter*Math.sin(card.angle*Math.PI/180)Column(){Text(card.title).fontSize(16).fontColor(Color.White)}.width(widthVp).height(widthVp*0.62).borderRadius(16)// 背景用深色保证文字对比.backgroundColor(#1E2740)// 转到该角度对应的朝向同时让卡片朝向用户.rotate({angle:card.angle,centerX:50%,centerY:600%,perspective:1400}).translate({x:xVp})// 超出舒适锥的卡片降权只做提示.opacity(inComfortCone(card.angle)?1.0:0.55).blur(invisibleOverride(card.angle))},(card:{title:string;angle:number;dist:number})card.title)}.width(100%).height(100%).backgroundColor(#0B1020)}}// 超出可见范围的卡片给一点模糊暗示不在当前视野内functioninvisibleOverride(angleDeg:number):number{returninVisibleCone(angleDeg)?0:6}这里用角度定朝向、视距定大小、视角恒定保证视觉一致三件事配合卡片围成一圈转头就能切换视野而内容始终是清晰可读的。是否是否放不下通过列出内容并排序优先级视角是否在 ±30 度内放舒适注视野可读可交互是否在 ±60 度内放周边视野只做提示放边缘仅氛围或移除按视距折算尺寸校验可达锥内是否放得下高频操作下移层级或改布局落位举个例子文旅展馆的展品信息牌展馆里用户会在展品之间走动信息牌如果贴得太高、太偏就得仰头侧身。按上面的原则排一版主标题展品名放在视线中心偏下一点水平居中视角压在 ±8° 内视距 1.0m 左右用户站定就能读。说明正文主标题下方向下的方向多留空间下视野比上视野宽字号按 0.5° 视角设保证 0.6~1.5m 都能读。操作按钮“语音讲解”加入行程放在可达锥内视距 0.6m尺寸放大到 56vp 以上减少空中点选的误差。引导提示放在 ±40° 的周边位置用箭头提示旁边还有内容不要求用户立刻读。这套排布的核心是把要读的、要点的、只要知道的分到不同的角度和距离带上用户的动作量自然就降下来了。总结一下下先定视角再定尺寸。视角决定可读性尺寸只是手段。用视角恒定原则远近内容才能视觉一致。可达区和高频操作绑死。返回、确认、切换这类高频动作位置固定在可达锥里别放边缘。垂直方向更吝啬。向上看的舒适角度小顶部内容要矮一点、少一点。深度方向多留容错。手在 z 方向的抖动最大3D 目标在这个方向要比看上去更宽容。用平面思维铺满整个视野。觉得反正空间大把内容摆到 ±80°用户根本读不了还会因为频繁转头产生不适。尺寸一刀切。远近内容用同样大小远的看着小、近的看着挤视角不一致读感很乱。高频操作放在远处。每次都要大臂移动或转头几分钟就累用户会放弃使用。深度方向不留余量。空中点选在前后方向上误差最大目标按 2D 标准设大小误触率会偏高。忽略个体差异。视野、臂长、颈肩活动度因人而异参数要给区间关键操作留备选入口比如语音或遥控器。一次性摆满。内容随场景变化时动态重排会让用户失去空间记忆固定区域的职责要稳定。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →