为空间网页做优化
Optimize for the spatial web
2024年6月10日
一句话判断
visionOS 2 的 Safari 不只是”在头显里看网页”,它给了网页真正的空间交互能力——眼动追踪的高亮区域可以用 SVG 精细控制、WebSpeech API 做免手操控的全语音交互、Spatial Photo 和 3D 模型直接嵌入网页——而且所有处理都在设备本地完成,不需要后端 API。
这场 Session 讲了什么
visionOS 的 Safari 正在定义”空间网页”的交互范式。Session 分三个层面展开:交互、沉浸内容、调试工具。
交互层面,visionOS 的核心输入方式是”眼睛注视 + 手指捏合”。系统会自动给可交互元素画高亮区域,但今年你可以用 SVG path 自定义这些区域的形状——对于复杂图形(比如一张自行车示意图的不同零件)非常有用。WebSpeech API 在 Vision Pro 上特别适合:语音识别和语音合成都完全在设备端运行,零 API key、零后端依赖。
沉浸内容方面,网页现在可以嵌入 Spatial Photos(空间照片)、Panorama(全景照片)、3D 模型(通过 <model> 标签)、空间音频,甚至完整的 WebXR VR 体验。Session 用一个自行车爱好者网站做案例,逐步添加这些能力。
调试方面,Safari 的 Web Inspector 可以连接到 visionOS Simulator 或真机上的 Safari,还提供了 XR Inspector 来调试 WebXR 场景的空间布局。
值得深挖的点
交互区域的设计哲学
visionOS 上”眼睛看到哪里就高亮哪里”的交互模型,对网页设计提出了新要求。传统的 hover 效果在桌面端靠鼠标位置触发,但在空间端,注视高亮是由系统进程绘制的——Safari 本身都不知道用户在看哪里(隐私保护)。这意味着你不能用 JavaScript 监听”用户在看哪个元素”。
但你可以在 CSS 里用 -apple-interactive-region-* 属性(通过 SVG path)自定义高亮形状。Session 里那个自行车安全检查清单的案例很直观:每个零件(车把、踏板、车轮)对应一个 SVG 路径作为独立的交互区域,比传统的矩形高亮精确得多。
对于包含大图媒体的链接,高亮会在几秒后自动淡化——这是一个体感细节。持久的高亮会遮挡图片内容,淡化处理让用户先看到”这里有可交互元素”,然后内容本身接管注意力。
WebSpeech 在空间场景的独特价值
WebSpeech API 不是新技术,但在 Vision Pro 上获得了全新的使用场景。核心优势:完全离线运行。语音识别和合成都在设备端处理,不发送数据到云端。这对于一个头戴设备来说至关重要——用户不太可能愿意让麦克风数据持续上传。
Session 里那个”Bike! Color! Shout!”游戏很好地展示了语音作为独立输入通道的价值:用户眼睛盯着游戏画面,嘴里喊出答案,不需要用手点击任何东西。这种”眼睛看 + 嘴巴说”的组合在传统设备上做不到(手机需要手持,电脑需要键盘鼠标),但空间计算天然适合。
代码片段
用 SVG 自定义交互区域
/* 为复杂形状的元素定义精确的交互区域 */
.bike-part-handlebar {
-apple-interactive-region: path(
'M 20,30 Q 40,10 60,30 Q 65,35 60,40 L 20,40 Q 15,35 20,30'
);
}
<!-- 配合 SVG hover 效果,在桌面端和空间端都能用 -->
<a href="/safety/handlebar" class="bike-part-handlebar">
<svg><!-- 车把形状 --></svg>
</a>
场景:让自行车零件图在 visionOS 上每个部件都有精确的注视高亮。坑:SVG path 的坐标系是相对于元素自身的,不是页面全局——定义路径时要先搞清楚参考系。
WebSpeech 语音识别做游戏输入
// 创建语音识别器(Safari 前缀 webkit)
const recognition = new webkitSpeechRecognition();
// 监听识别结果
recognition.addEventListener('result', (event) => {
const results = event.results;
const latestResult = results[results.length - 1];
const transcript = latestResult[0].transcript.toLowerCase();
// 简单匹配用户说出的颜色
const colors = ['pink', 'orange', 'green', 'blue'];
const matched = colors.find(c => transcript.includes(c));
if (matched) handleColorGuess(matched);
});
// 必须在用户交互事件中启动
startButton.addEventListener('click', () => recognition.start());
场景:语音控制游戏或免手操控场景。坑:第一次调用需要用户授权麦克风权限,要在合适的时机请求并说明原因——不然用户在头显里看到一个突兀的权限弹窗会很懵。
WebSpeech 语音合成反馈
// 游戏结束后语音播报得分
function announceScore(score) {
const utterance = new SpeechSynthesisUtterance(
`游戏结束!你猜对了 ${score} 个颜色。`
);
utterance.lang = 'zh-CN'; // 设置中文
speechSynthesis.speak(utterance);
}
场景:在用户无法方便看屏幕时提供语音反馈。坑:某些语言/方言可能不支持,建议先检查 speechSynthesis.getVoices() 的可用列表。
最佳实践
已有项目: 如果你已有网站,先从交互区域优化入手。给链接加 padding 让注视高亮更容易触发,用圆角匹配视觉风格。对于包含图片的链接,确保 <a> 标签包裹了图片元素本身,这样高亮淡化后内容不受影响。
新项目: 如果为 Vision Pro 做专门的空间网页体验,WebSpeech 应该是第一优先级——它不需要任何 API key 或后端支持,开箱即用。3D 模型和空间照片则根据内容类型决定,不是每个网站都需要沉浸内容。
还有什么值得关注
- WebXR 在 visionOS Safari 上支持完整的 VR 沉浸体验,配合
<model>标签可以在网页里嵌入可交互的 3D 模型。 - Safari 的 Web Inspector 可以直接连接 visionOS 设备调试,XR Inspector 可以检查 WebXR 场景的空间坐标系。
- 给链接添加 padding 是一个低成本的改进:在手机上让点击区域更大,在 Vision Pro 上让注视区域更大——一次改动,多端受益。