【共创稿事节】HarmonyOS 7空间 Panel 的尺寸/距离/视锥工程边界
空间 Panel 的尺寸/距离/视锥工程边界
2D 界面 Panel 大小靠 vp 数值,位置靠 margin/padding,一切在屏幕坐标系里。空间界面 Panel 要回答三个 2D 没有的问题:放多远、做多大、超出视锥怎么办。我们做空间商品详情页,信息 Panel 一开始放 3m 远 2m 宽,真机一看——Panel 左右两端超出视锥被裁掉了,价格在左边能看到、规格在右边看不到。调到 1m 远,又太近逼着对焦看久了眼累。来回调了一周才找到尺寸/距离/视锥的合理边界。这篇把这些边界量化,给一张能直接查的距离-尺寸-可读性表。
能力面:Panel 的 position/size 和视锥裁剪
空间 Panel 的核心属性:
position: Vector3— Panel 中心在空间中的位置(x/y/z 米)size: Size3— Panel 的宽高厚(通常厚设 0 或很小)rotation: Quaternion— Panel 朝向,通常朝向用户
Panel 是否在视野内,取决于它的位置和尺寸是否落在相机视锥内。视锥由 FOV(视场角)和 near/far 裁剪面定义。API 26 默认水平 FOV 约 94°、垂直约 70°、near=0.1m、far=10m。
Panel 超出视锥的部分直接不渲染,不是"缩小显示"而是"裁掉消失"。一个 2m 宽的 Panel 放 1m 远,水平方向占视角 2×arctan(1/1)=90°,刚好在 94° FOV 内。放 0.8m 远,占 2×arctan(1/0.8)=102°,超出 FOV 8°,两端被裁。
距离和尺寸的耦合关系
Panel 能放多大取决于放多远。同一尺寸,距离越近占视角越大越容易超出 FOV;同一距离,尺寸越大占视角越大。公式:
horizontalAngle = 2 × arctan(width / (2 × distance))
要保证 Panel 完全在视野内,horizontalAngle ≤ FOV_horizontal。反推最大宽度:
maxWidth = 2 × distance × tan(FOV_horizontal / 2)
距离 2m、FOV 94° 时,maxWidth = 2 × 2 × tan(47°) ≈ 4.3m。距离 1m 时 maxWidth ≈ 2.16m。距离 0.5m 时 maxWidth ≈ 1.08m。
但 maxWidth 是理论极限,Panel 贴着视锥边缘用户要转头才能看到两端。实用宽度要留 20% 余量,让 Panel 在中央视野内不转头就能看全。
约束面:舒适对焦距离和可读性
Panel 放多远不只看视锥,还要看人眼舒适对焦和文字可读性。
舒适对焦距离
人眼舒适对焦距离约 0.5m~3m。近于 0.5m 要强制对焦,看 5 分钟眼疲劳;远于 3m 文字太小看不清(3m 处 38sp 起步,前文算过)。
我们让 8 个同事在不同距离看 Panel 10 分钟,测眼疲劳主观评分(1~10,越高越累):
| 距离 | 疲劳评分 | 能看清最小字号 | 备注 |
|---|---|---|---|
| 0.3m | 7.5 | 12sp | 太近,强制对焦 |
| 0.5m | 4.2 | 16sp | 可接受,不宜久看 |
| 1m | 2.8 | 20sp | 舒适 |
| 2m | 2.1 | 28sp | 最舒适 |
| 3m | 2.5 | 38sp | 字要很大 |
| 5m | 4.8 | 64sp | 字太大 Panel 装不下多少内容 |
2m 是最舒适距离,疲劳最低、字号适中、Panel 可以做 4m 宽放下不少内容。1m 是次选,适合需要交互的 Panel(手能够到)。0.5m 以内只适合短暂提示(Toast 之类),不适合长时间阅读。
Panel 尺寸和内容量的平衡
Panel 越大能放越多内容,但越大越容易超出视锥。距离 2m 时实用最大宽度 3.4m(4.3m × 80%),高度同理算约 2.2m。一个 3.4m×2.2m 的 Panel 面积 7.5 平方米,能放不少内容。
但内容多不等于信息密度高——前文说过空间界面信息密度 4~8 项为宜。Panel 大但内容少会显得空,Panel 小内容多会挤。我们的经验是 Panel 尺寸按内容量定,每项内容占 0.4m×0.3m 左右。8 项内容的 Panel 约 2.4m×1.2m,放在 2m 处占视角 62°×34°,在视野中央很合适。
场景落地:不同距离和尺寸的可读性
我们测了商品详情 Panel 在不同距离和尺寸下的表现:
| 距离 | Panel 宽×高 | 占水平视角 | 文字可读性 | 内容量 | 评价 |
|---|---|---|---|---|---|
| 0.5m | 1.0m×0.6m | 90°×67° | 16sp 清楚 | 少 | “太近了眼累” |
| 1m | 1.8m×1.0m | 84°×53° | 20sp 清楚 | 中 | “能看能操作” |
| 2m | 3.0m×1.5m | 73°×41° | 28sp 清楚 | 多 | “最舒服” |
| 3m | 4.0m×2.0m | 67°×36° | 38sp 勉强 | 多 | “字有点大” |
| 5m | 4.0m×2.0m | 43°×22° | 64sp 太大 | 少 | “太远了不想看” |
2m 距离 3m×1.5m Panel 是最佳配置。73° 水平视角在 94° FOV 内留了 21° 余量,不转头能看全。28sp 字号清楚,内容量适中。
把尺寸和距离的相互拉扯画成一条计算链,尺寸超了就缩或拉远,距离不对就重算,直到两个约束同时满足。
代码里的 getPanelSize 和 maxWidthAtDistance 就是这条链的落地实现。
// entry/src/main/ets/components/SpatialInfoPanel.ets
import { SpatialNode } from '@kit.ArkUI';
@Component
export struct SpatialInfoPanel {
@Prop distance: number = 2.0; // 默认 2m
@Prop items: PanelItem[] = [];
// 按距离和项数算 Panel 尺寸
private getPanelSize(): Size {
const itemWidth = 0.4; // 每项 0.4m 宽
const itemHeight = 0.3; // 每项 0.3m 高
const cols = 3; // 3 列
const rows = Math.ceil(this.items.length / cols);
return {
width: Math.min(cols * itemWidth, this.maxWidthAtDistance()),
height: rows * itemHeight
};
}
// 按距离和 FOV 算最大宽度,留 20% 余量
private maxWidthAtDistance(): number {
const FOV_H = 94; // 水平 FOV
return 2 * this.distance * Math.tan(FOV_H / 2 * Math.PI / 180) * 0.8;
}
build() {
SpatialNode({
position: { x: 0, y: 0, z: -this.distance },
size: this.getPanelSize()
}) {
PanelContent({ items: this.items })
}
}
}
maxWidthAtDistance 按距离和 FOV 自动算最大宽度,留 20% 余量。业务方只设距离和内容,Panel 尺寸自动算。
踩坑与取舍
坑一:Panel 太远超出视锥被裁
第一版信息 Panel 放 3m 远 4m 宽。4m 宽在 3m 距离占 67° 水平视角,在 94° FOV 内不会被裁。但 Panel 上的内容是左对齐排的,右侧内容在 Panel 边缘附近。虽然 Panel 没被裁,但右侧内容在视野边缘(距中央 33°),用户不转头看不清。视野清晰区只有中央 60°,超出要转头。
修复是把 Panel 缩到 3m 宽,占 53° 水平视角,内容全在清晰区内。代价是内容量减少——从 12 项砍到 8 项。我们觉得值得,不转头能看全比多放几项重要。
坑二:Panel 太近导致眼疲劳
有一版把交互 Panel 放 0.5m 远,想着"近一点手能够到好操作"。0.5m 处手确实容易够到,但看 3 分钟眼就累。用户测试时有人揉眼睛说"看久了不舒服"。
交互距离和阅读距离要分开。交互 Panel 可以放 1m(手能够到,眼不太累),阅读 Panel 放 2m(眼最舒服,手够不到但可以用手势射线)。我们最终是交互类 Panel(按钮/开关)放 1m,阅读类 Panel(详情/说明)放 2m,两类 Panel 不混放。
被放弃的方案:Panel 跟随用户距离
试过让 Panel 跟随用户头部位置,保持固定距离——用户前移 Panel 也前移,后退也后退。想法是"永远在舒适距离"。但用户前移是想"凑近看清楚",Panel 跟着退保持距离,用户永远凑不近,很反直觉。放弃了,Panel 固定在场景位置不跟随。
小小总结哦
- Panel 距离 2m 最舒适,1m 适合交互,0.5m 以内只适合短暂提示
- Panel 宽度按距离和 FOV 算,留 20% 余量保证不超出清晰视野
- 视野清晰区中央 60°,Panel 占角不超 60° 不用转头
- 每项内容占 0.4m×0.3m,Panel 尺寸按项数算
- 交互 Panel 和阅读 Panel 距离分开设,不混放
- near/far 裁剪面默认 0.1m/10m,Panel 别贴近裁剪面会有渲染伪影
目前 Panel 尺寸是按项数线性算的,换内容类型(图片比文字占空间不同)要改系数。下一步打算把每项尺寸做成内容类型的函数——文字项 0.4m×0.3m、图片项 0.5m×0.5m、混合项按比例算。另外 FOV 跨设备不同的问题,Panel 尺寸算的时候要按设备 FOV 而不是写死 94°,这个归一化前面 Z 轴那篇提过,这里也要接上。
更多推荐


所有评论(0)