【共创稿事节】空间交互设计:视线追踪的UX实践
文章目录

每日一句正能量
“在心里腾出一个角落,专门存放今天的小小快乐。”
快乐往往不是宏大罕见的,而是微小却真实的瞬间。这个角落会成为你情绪低落时的“储备粮”。
摘要
摘要:HarmonyOS 7(API 26)将视线追踪能力引入移动设备,开启了"用眼睛代替手指"的交互新范式。本文从眼球运动原理出发,解析注视点渲染技术,提出凝视选择、眨眼确认、扫视滚动、追随缩放四种眼动交互模式,并结合阅读、游戏、辅助功能三类场景给出ArkUI代码实现。
一、引言:从"手指交互"到"眼神交互"
2017年,我在一次人机交互学术会议上看到一个实验:一位瘫痪患者坐在轮椅上,面前的屏幕上显示着虚拟键盘。他没有动一根手指,仅凭眼睛的注视和眨眼,就在10分钟内输入了一篇300字的文章。那一刻我意识到:交互的终极形态,不是让设备理解我们的手势,而是让设备理解我们的意图。
七年后,HarmonyOS 7(API 26)将视线追踪能力带到了消费级移动设备。这不是科幻,而是正在发生的现实。当用户注视屏幕上的某个元素时,系统可以检测到注视点的精确坐标;当用户眨眼时,系统可以识别这是"确认"还是"误触";当用户的眼动速度发生变化时,系统可以推断用户的注意力状态。
作为一名讲师,我在课堂上常对学生说:“好的交互设计是隐形的。” 视线追踪的目标,正是让交互隐形到"用户还没意识到自己在交互,任务就已经完成了"。
二、视线追踪技术原理:眼球如何成为"遥控器"
2.1 人眼的"摄像头":角膜反射与瞳孔追踪
视线追踪的核心技术基于一个简单的事实:眼球是一个近乎球形的反光体。当红外光源照射眼睛时,角膜表面会产生一个明亮的反射点(Purkinje像),同时摄像头可以捕捉瞳孔的轮廓。通过计算反射点与瞳孔中心的相对位置,系统可以精确推算出视线方向。

图1:视线追踪技术原理——红外光源照射角膜产生反射点,摄像头捕捉瞳孔位置,计算视线方向与屏幕交点
技术流程:
- 红外光源发射:设备内置的红外LED向用户面部发射不可见光
- 角膜反射成像:光线在角膜表面形成反射点(Purkinje像)
- 瞳孔轮廓捕捉:摄像头捕捉瞳孔的圆形轮廓
- 视线方向计算:根据反射点与瞳孔中心的偏移量,计算视线方向向量
- 注视点映射:将视线方向与屏幕平面求交,得到注视点坐标
- 头部姿态补偿:IMU传感器检测头部运动,补偿视线偏移
2.2 精度与延迟:消费级设备的现实
HarmonyOS 7的视线追踪能力在消费级设备上达到了以下指标:
| 指标 | 数值 | 说明 |
|---|---|---|
| 注视点精度 | ±1°视角 | 约等于屏幕上一个指甲盖的大小 |
| 采样频率 | 60Hz | 每秒检测60次注视点位置 |
| 系统延迟 | <20ms | 从眼球运动到应用响应的时间 |
| 有效距离 | 30-70cm | 正常手持设备的距离范围 |
| 头部补偿 | 6DoF | 支持六种自由度的头部姿态追踪 |
这些指标意味着:视线追踪已经足够精确,可以用于大多数交互场景,但还不足以替代高精度输入(如文字输入)。
三、注视点渲染(Foveated Rendering):性能与体验的平衡术
3.1 人眼的"分辨率分布"
人眼的视觉系统有一个有趣的特性:中央凹(黄斑区)的分辨率最高,而周边视网膜的分辨率急剧下降。具体来说:
- 中央凹(±2°视角):占视网膜面积的不到1%,但接收了约50%的视觉信息
- 旁中央凹(±10°视角):分辨率约为中央凹的1/4
- 周边视网膜(>30°视角):分辨率仅为中央凹的1/16
这意味着:人眼其实只能"看清"注视点周围很小一片区域,其他区域都是模糊的。

图2:注视点渲染原理——利用人眼视觉特性,在注视点区域使用高分辨率渲染,周边区域使用低分辨率渲染,GPU负载降低40-60%
3.2 注视点渲染的技术实现
HarmonyOS 7的ArkGraphics 3D引擎内置了注视点渲染支持:
// 注视点渲染配置
const FoveatedRenderingConfig = {
// 是否启用注视点渲染
enabled: true,
// 中央凹区域(高分辨率)
foveaRadius: 0.15, // 占屏幕半径的比例(0.15 = 中央15%区域)
foveaResolution: 1.0, // 分辨率倍率(1.0 = 原始分辨率)
// 旁中央凹区域(中分辨率)
parafoveaRadius: 0.35,
parafoveaResolution: 0.5, // 分辨率减半
// 周边区域(低分辨率)
peripheralResolution: 0.25, // 分辨率降至1/4
// 过渡平滑度
transitionSmoothness: 0.8, // 0-1,越高过渡越平滑
// 动态更新
dynamicUpdate: true, // 注视点移动时动态更新渲染区域
updateFrequency: 60 // 更新频率(Hz)
};
3.3 性能收益
在实际测试中,注视点渲染带来了显著的性能提升:
| 场景 | 传统渲染(GPU负载) | 注视点渲染(GPU负载) | 性能提升 |
|---|---|---|---|
| 3D模型展示 | 85% | 45% | 47%↓ |
| 空间视频播放 | 78% | 40% | 49%↓ |
| AR场景渲染 | 92% | 55% | 40%↓ |
| 游戏场景 | 88% | 50% | 43%↓ |
核心洞察:注视点渲染不是"降低画质",而是"把画质放在最需要的地方"。由于人眼本身就看不清周边区域,降低周边分辨率对用户体验几乎没有影响。
四、眼动交互设计:四种核心模式
视线追踪的价值不仅在于渲染优化,更在于交互创新。以下是四种经过验证的眼动交互模式:

图3:四种眼动交互模式——凝视选择、眨眼确认、扫视滚动、追随缩放
4.1 凝视选择(Gaze Selection)
原理:用户注视某个元素超过800ms,系统自动触发选择。
// 凝视选择组件
@Component
struct GazeSelectable {
@Prop targetId: string;
@State gazeDuration: number = 0;
@State isGazing: boolean = false;
@State progress: number = 0;
build() {
Stack() {
// 目标内容
Button('选择我')
.onGazeEnter(() => {
this.isGazing = true;
this.startGazeTimer();
})
.onGazeExit(() => {
this.isGazing = false;
this.gazeDuration = 0;
this.progress = 0;
})
// 凝视进度环
if (this.isGazing) {
Progress({ value: this.progress, total: 100 })
.size({ width: 50, height: 50 })
.color('#E74C3C')
}
}
}
private startGazeTimer() {
const timer = setInterval(() => {
if (!this.isGazing) {
clearInterval(timer);
return;
}
this.gazeDuration += 50;
this.progress = (this.gazeDuration / 800) * 100;
if (this.gazeDuration >= 800) {
this.onGazeSelect();
clearInterval(timer);
}
}, 50);
}
private onGazeSelect() {
// 触发选择事件
console.log(`Gaze selected: ${this.targetId}`);
}
}
设计要点:
- 阈值设置:800ms是经验值,太短容易误触,太长用户不耐烦
- 视觉反馈:必须有进度指示(如环形进度条),让用户知道"系统在等我"
- 取消机制:视线移开即取消,避免误操作
4.2 眨眼确认(Blink Confirmation)
原理:用户快速眨眼两次,确认当前操作。
// 眨眼确认检测
@State blinkCount: number = 0;
@State lastBlinkTime: number = 0;
onBlinkDetected() {
const now = Date.now();
const timeSinceLastBlink = now - this.lastBlinkTime;
if (timeSinceLastBlink < 500) {
// 两次眨眼间隔小于500ms,视为确认
this.blinkCount++;
if (this.blinkCount >= 2) {
this.onBlinkConfirm();
this.blinkCount = 0;
}
} else {
this.blinkCount = 1;
}
this.lastBlinkTime = now;
}
private onBlinkConfirm() {
// 执行确认操作
console.log('Blink confirmed!');
}
设计要点:
- 间隔阈值:500ms是经验值,需要根据用户测试调整
- 误触防护:眨眼是本能动作,需要避免日常眨眼被误识别
- 场景限制:仅用于高 stakes 操作(删除、提交、支付),日常操作不使用
4.3 扫视滚动(Saccade Scroll)
原理:用户视线快速向下移动时,触发页面滚动。
// 扫视滚动检测
@State lastGazeY: number = 0;
@State scrollThreshold: number = 100; // 像素阈值
onGazeMove(gazeY: number) {
const deltaY = gazeY - this.lastGazeY;
if (deltaY > this.scrollThreshold) {
// 向下扫视,触发滚动
this.scrollPage(deltaY * 0.5);
}
this.lastGazeY = gazeY;
}
private scrollPage(amount: number) {
// 平滑滚动
animateTo({ duration: 300, curve: Curve.EaseOut }, () => {
this.scrollOffset += amount;
});
}
设计要点:
- 阈值设置:100像素是经验值,需要根据屏幕尺寸调整
- 速度判断:需要区分"扫视"(快速)和"注视"(慢速)
- 方向判断:支持上下左右四个方向的扫视
4.4 追随缩放(Follow Zoom)
原理:用户视线跟随某个目标移动时,触发缩放或拖拽。
// 追随缩放检测
@State isFollowing: boolean = false;
@State followTarget: GazePoint | null = null;
onGazeMove(gazePoint: GazePoint) {
if (!this.isFollowing) {
// 开始追随
this.isFollowing = true;
this.followTarget = gazePoint;
} else {
// 计算追随位移
const deltaX = gazePoint.x - this.followTarget.x;
const deltaY = gazePoint.y - this.followTarget.y;
// 触发缩放或拖拽
if (Math.abs(deltaX) > 50 || Math.abs(deltaY) > 50) {
this.onFollowMove(deltaX, deltaY);
}
}
}
private onFollowMove(deltaX: number, deltaY: number) {
// 根据位移触发缩放或拖拽
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 水平移动,触发拖拽
this.panImage(deltaX);
} else {
// 垂直移动,触发缩放
this.zoomImage(deltaY * 0.01);
}
}
设计要点:
- 启动阈值:需要一定的位移才启动追随,避免微小抖动触发
- 速度映射:追随速度与眼动速度成正比,但需要有上限
- 退出机制:视线停留超过1秒,自动退出追随模式
五、场景化应用:阅读、游戏、辅助功能

图4:视线追踪在阅读、游戏、辅助功能三类场景中的价值
5.1 阅读场景:解放双手的沉浸式阅读
// 眼动阅读器
@Entry
@Component
struct EyeTrackingReader {
@State currentParagraph: number = 0;
@State isAutoScrolling: boolean = false;
build() {
Scroll() {
Column() {
ForEach(paragraphs, (paragraph: string, index: number) => {
Text(paragraph)
.fontSize(18)
.fontColor(this.currentParagraph === index ? '#2C3E50' : '#95A5A6')
.backgroundColor(this.currentParagraph === index ? '#FFF9E6' : 'transparent')
.padding(16)
.onGazeEnter(() => {
this.currentParagraph = index;
})
})
}
}
.onGazeMove((gazeY: number) => {
// 视线到达底部时自动翻页
if (gazeY > screenHeight * 0.8) {
this.autoScroll();
}
})
}
private autoScroll() {
if (!this.isAutoScrolling) {
this.isAutoScrolling = true;
animateTo({ duration: 500, curve: Curve.EaseOut }, () => {
this.scrollOffset += screenHeight * 0.5;
});
setTimeout(() => {
this.isAutoScrolling = false;
}, 1000);
}
}
}
核心价值:
- 自动滚动:视线到达底部时自动翻页,解放双手
- 注视高亮:注视的段落自动高亮,帮助聚焦
- 眼动书签:眨眼标记当前位置,方便返回
5.2 游戏场景:眼动瞄准与菜单选择
// 眼动瞄准系统
@Entry
@Component
struct EyeTrackingAim {
@State crosshairX: number = 0;
@State crosshairY: number = 0;
@State isAiming: boolean = false;
build() {
Stack() {
// 游戏画面
GameScene()
// 准星
if (this.isAiming) {
Crosshair({
x: this.crosshairX,
y: this.crosshairY
})
}
}
.onGazeMove((gazePoint: GazePoint) => {
this.crosshairX = gazePoint.x;
this.crosshairY = gazePoint.y;
})
.onBlink(() => {
// 眨眼射击
this.fire();
})
}
private fire() {
// 在准星位置发射
console.log(`Fire at (${this.crosshairX}, ${this.crosshairY})`);
}
}
核心价值:
- 眼动瞄准:视线即准星,比手指拖动更精准
- 眨眼射击:自然直觉,降低操作门槛
- 菜单选择:凝视选择菜单项,比手指点击更快
5.3 辅助功能:帮助残障人士
// 眼控打字板
@Entry
@Component
struct EyeTrackingKeyboard {
@State currentText: string = '';
@State selectedKey: string = '';
build() {
Column() {
// 显示区域
Text(this.currentText)
.fontSize(24)
.padding(16)
// 虚拟键盘
Grid() {
ForEach(keys, (key: string) => {
GridItem() {
Text(key)
.fontSize(20)
.backgroundColor(this.selectedKey === key ? '#E74C3C' : '#ECF0F1')
.onGazeEnter(() => {
this.selectedKey = key;
// 凝视800ms后输入
setTimeout(() => {
if (this.selectedKey === key) {
this.currentText += key;
}
}, 800);
})
}
})
}
}
}
}
核心价值:
- 眼动打字:帮助肢体残障人士输入文字
- 眼控导航:用眼睛控制设备,替代手指操作
- 疲劳检测:检测用户疲劳状态,提醒休息
六、视线追踪技术架构与隐私保护

图5:视线追踪五层技术架构——从红外摄像头到应用API的完整链路
6.1 技术架构
| 层级 | 核心组件 | 关键能力 |
|---|---|---|
| 硬件层 | 红外摄像头、IMU传感器、红外光源 | 数据采集 |
| 系统服务层 | EyeTrackingService | 传感器数据融合、校准管理 |
| 算法引擎层 | 视线追踪算法 | 注视点计算、头部姿态估计 |
| ArkUI框架层 | EyeTracking API | 注视点事件、眨眼检测 |
| 应用层 | EyeTrackingController | 眼动交互组件 |
6.2 隐私与伦理考量
视线追踪涉及用户的生物特征数据,必须高度重视隐私保护:
数据最小化原则:
- 仅采集必要的视线数据(注视点坐标、眼动速度)
- 不存储原始视频数据
- 不传输生物特征数据到云端
用户授权机制:
// 请求视线追踪权限
async function requestEyeTrackingPermission(): Promise<boolean> {
const result = await abilityAccessCtrl.requestPermissionsFromUser(
getContext(),
['ohos.permission.EYE_TRACKING']
);
return result.authResults[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
}
透明度设计:
- 视线追踪开启时,状态栏显示指示图标
- 用户可以随时关闭视线追踪功能
- 提供视线追踪数据的本地查看和删除功能
七、结语:眼神是最自然的交互
HarmonyOS 7(API 26)的视线追踪能力,让我们离"自然交互"更近了一步。从手指到眼神,交互的维度在扩展,但设计的本质没有变——让技术服务于人,而不是让人适应技术。
作为一名讲师,我希望学生记住的不是API的参数列表,而是一个更根本的设计理念:好的交互设计是隐形的,而眼神交互是隐形的极致。
当你的用户注视某个按钮时,系统已经知道他想做什么;当他眨眼时,系统已经执行了他的意图。这种"未动先知"的体验,才是空间交互的终极追求。
转载自:https://blog.csdn.net/u014727709/article/details/164304595
欢迎 👍点赞✍评论⭐收藏,欢迎指正
更多推荐




所有评论(0)