View in English

  • 打开菜单 关闭菜单
  • Apple Developer
搜索
关闭搜索
  • Apple Developer
  • 新闻
  • 探索
  • 设计
  • 开发
  • 分发
  • 支持
  • 账户
在“”范围内搜索。

快捷链接

5 快捷链接

视频

打开菜单 关闭菜单
  • 专题
  • 相关主题
  • 所有视频
  • 关于

返回 WWDC25

  • 简介
  • 概要
  • 转写文稿
  • 代码
  • 空间网页的新功能

    了解 visionOS 26 上适用于网页的最新空间功能。我们将介绍如何使用全新的 HTML 模型元素来显示内联 3D 模型。我们还将分享模型照明、交互和动画等强大功能。了解如何在你的网站上嵌入新支持的沉浸式媒体,例如 360 度视频和 Apple 沉浸视频。另外,你还将抢先体验如何在网页中添加自定环境。

    章节

    • 0:00 - 简介
    • 0:55 - 嵌入 3D 模型
    • 21:24 - 呈现沉浸式媒体
    • 26:14 - 提供自定环境

    资源

    • GitHub: element that displays 3D explainer
    • GitHub: model element samples
    • GitHub: Spatial Backdrop explainer
    • Learn more about Reality Composer
    • MDN: Properly configuring server MIME types
    • QuickLook example files
    • The HTML model element in Apple Vision Pro
      • 高清视频
      • 标清视频

    相关视频

    WWDC25

    • 了解 Apple Projected Media Profile
    • 探索 visionOS 的视频体验
    • 支持 visionOS App 播放沉浸视频
    • Safari 浏览器和 WebKit 的新功能

    WWDC24

    • 为你的沉浸式 visionOS App 创建自定环境

    WWDC23

    • 探索 USD 生态系统
    • 认识 Reality Composer Pro
  • 搜索此视频…

    大家好 我是 Eddy 来自 visionOS Safari 浏览器团队 空间网页迎来了重要的一年 我们带来了令人兴奋的新功能 将把网页体验提升到一个新的维度

    我们支持根据其他网页内容 对 3D 模型进行立体渲染 同时支持用户与模型交互 我们现在还支持播放沉浸式媒体 这是一种超越平面屏幕的新型媒体

    我们增加了一些 新的开发者预览功能 例如网站环境 我将为大家演示 如何应用这些新功能 我将展示如何 在网页上嵌入 3D 模型 呈现沉浸式媒体 并提供自定义网页环境 我们言归正传 在过去的几十年里 网页开发者 利用 HTML 图像元素 在网页上呈现图像 随着我们进入空间计算时代 我们将引入一种新方式 让你可以在网页上嵌入 并显示 3D 模型 从而为网页内容增加新的维度 这是一个全新的 HTML 模型元素 几年前就有人向 Web 标准组织 建议增加这种元素 今年 我们就会在 visionOS 的 Safari 浏览器中 默认支持这种元素 只需要添加简单的标记 就能让访客看到 3D 模型 与其他内容一起嵌入到网页中 与现有的模型渲染库不同 这种模型元素 以立体方式渲染 让用户能感知到对象的深度 并从不同的角度查看模型 我们会从多个方面介绍 嵌入式 3D 模型 从准备资源到完美渲染 支持交互和动画等 要嵌入 3D 模型 第一步就是创建模型 现在在 visionOS 的 Safari 浏览器中 模型元素支持 USDZ 文件格式 这是 3D 内容行业中 广泛使用的格式 使用现有工具 你可以获取、转换或创建 USDZ 文件 你可以使用 iPhone 将真实对象 采集到 3D 模型文件中 只需从 App Store 下载 Reality Composer App 就可以开始采集 iOS 上的 Object Capture API 支持 App 以类似的方式获取和生成模型文件 可能有人已经在自己的用例中 使用一些 3D 模型了 但你们使用的可能是其他格式 macOS 原生支持 使用预览或命令行工具 将各种 3D 模型格式 转换为 USDZ 文件 一些高级用户已经在 使用现有的 3D 建模软件 来构建令人惊叹的精美 3D 模型 例如 Blender、Houdini、Maya、 Reality Composer Pro 等等 许多建模软件都支持导出到 USDZ USD 生态系统提供了很多工具 可以用在我们的工作流程中 如需了解详情 请观看 WWDC23 的 讲座:“探索 USD 生态系统” 如果你以前没有创建过 3D 模型 可以先观看 WWDC23 的讲座: “认识 Reality Composer Pro” 如果你想测试模型元素 可以轻松获取测试 USDZ 文件 获取 USDZ 文件最快的方式 是从 developer.apple.com/cn/ 下载 有些文件是使用物体捕捉制作的 还有一些则是 用 3D 建模软件精心制作的 与所有网页素材一样 应该尽量让文件小一点 文件越小 加载速度越快 我最喜欢的方法是 使用 Mac 上的预览功能 导出经过压缩的素材副本 优化文件的方法还有很多 WWDC24 讲座: “为空间计算优化 3D 素材资源” 中深入介绍了具体的方式 准备好素材文件后 我们可以将文件嵌入到网页中 嵌入模型的语法很简单 只需在模型元素的 source 属性中 应用 USDZ 文件 别忘记加结束标签 还可以将 source 元素 放在一个空的模型元素中 和添加图片元素的做法差不多

    模型元素的运作方式 与其他视觉 DOM 元素一样 因此 你希望在哪里显示模型 就可以把它放在哪里 需要记住的一点是 模型始终在网页表面下进行渲染 我们可以把模型元素想象成 通往网页下的虚拟空间的大门 模型就位于这个空间里 这样可以防止在模型元素 滚动到视图中时 内容意外突出到页面外 默认情况下 浏览器会使模型放大或缩小 以适应元素的边界 它通过拟合元素中 模型边界框的 x-y 面 并使它居中来实现

    一些较旧的网页服务器或 CDN 可能无法识别 USDZ 文件扩展名 并且可能会在 HTTP 响应标头中 返回错误的内容类型 为了返回正确的内容类型 我们可能需要 向网页服务器添加一些配置 下面是一些为不同的网页服务器 指定 USDZ MIME 类型的示例 有关详细信息 请查看相应网页服务器软件的文档 构建出色网站的关键是 能够适应使用不同设备的所有访客 因此提供向后兼容的 回退图像非常重要 若要提供回退图像 可以将图像放在模型元素中

    我个人喜欢提供模型的 2D 渲染图 以便让使用其他浏览器的用户 仍然可以看到对象的呈现效果 除了静态图像 我们还可以利用现有的第三方库 提供 2D 观看体验 这样的第三方库包括 Three.js、BabylonJS、 model-viewer 等等

    这是一个 利用 model-viewer 库的示例 这个库使用 JavaScript 将给定模型呈现到 2D 画布上 我们可以用它来提供回退体验 只需要将模型元素 封装在 2D 查看器代码周围 通过这项设置 在 visionOS 上 使用 Safari 浏览器的用户 将看到具有深度的立体渲染模型 而使用其他浏览器的用户 可以看到 2D 渲染效果 如果想自定义回退行为 可以使用 JavaScript 来检测 模型元素是否受支持

    可以检查是否存在 window.HTMLModelElement 对象 但我不建议大家 检测用户代理 是不是 visionOS Safari 浏览器 这样存在风险 以后当其他浏览器 开始支持模型元素时 可能会出错 请记住 检测的是功能 而不是代理 USDZ 文件的大小很容易超过 10 MB 因此 在速度较慢的网络上 可能需要几秒钟时间才能加载 你可能想知道模型何时加载完毕 以便对 UI 执行更新 一个常见的示例是加载指示器

    模型元素有一个 ready 属性 它会返回一个 Promise 对象 当模型完全加载时 promise 将解析 然后 你可以隐藏加载指示器 并显示模型元素 发生加载错误时 ready promise 可能会失败 所以还要恰当地处理错误 例如提供重试按钮 根据我的经验 为访客提供视觉提示 让他们知道正在加载内容 有助于让访客继续留在页面上 否则他们会离开页面

    现在我们已经嵌入了模型 现在要做的是 让它在网站上呈现理想效果 模型元素定义了 一个渲染模型的虚拟空间 建议将空间的颜色设置为 与周围网页内容相同的颜色 这样能让模型元素很好地融入页面

    在向页面添加模型元素时 整个模型元素会被虚拟空间取代 因此 用户将看不到 相应区域的原始背景颜色 要解决这个问题 应该 使用 CSS background-color 属性 设置虚拟空间的颜色 请记住 这需要在模型元素上进行设置 不能在它的上级进行设置 如果使用 alpha 指定背景色 它将被转换为不透明 如果不想重复定义颜色 可以使用 CSS 自定义属性 来避免代码重复 模型元素融入页面后 你就可以轻松呈现内容了

    在前一个示例中 我将模型元素延伸到了右侧面板下 为面板应用了磨砂玻璃效果 以特定角度露出下方的相机 营造出一种非常强烈的层次感

    有好几种方法可以达到相同的效果 我演示的只是我自己的做法 首先我使用 position: absolute 将模型元素延伸到面板后 backdrop-filter 通过 模糊模型元素的像素 渲染出了磨砂玻璃效果 线性渐变在边缘上提供镜面高光 这样可以营造厚重感 同时为面板使用浅色 以确保文字容易阅读 这些都是很早以前的 CSS 技巧了 但如果结合模型元素的景深效果 它们确实也能大放异彩 这个页面现在看起来非常不错 但我们可以通过调整照明效果 来让模型更好看 在这里 我把不同的照明效果 应用到同一个模型文件 注意一点 它们的效果 取决于所选照明效果 要控制照明效果 可以使用一种特殊的图像 来确定模型的环境 这样你的模型就会反射环境中的光 这种技术称为 基于图像的照明 简称 IBL 这种图像通常称为 IBL 文件 IBL 文件可能看起来是扭曲的 因为它是将环境 360 度投影到平面图像上 这种扁平的球面投影 也称为等距柱状投影 在 IBL 文件里非常常见 请注意 IBL 文件 不是 USDZ 文件的一部分 因此必须在渲染期间单独指定

    要指定模型元素的 IBL 应该使用 EnvironmentMap 属性 如果不提供这个属性 浏览器会为模型应用默认照明效果 由于 IBL 不包含在 USDZ 文件中 在网页外使用模型文件时 它不会获得相同的照明效果 这样能让演示的 App 根据观看体验 应用最合适的照明效果 我建议大家考虑 为 IBL 文件使用 OpenEXR 和 Radiance HDR 格式 这两种格式会让 反射效果更加逼真 因为它们能呈现 许多量级的亮度级别 另一方面 JPEG IBL 看起来非常暗淡和扁平 现在模型的视觉效果已经很棒了 可以让访客与模型交互了 模型元素支持多种 现成的用户交互方式 默认情况下 捏住模型元素 将启动拖放交互 用户可以将模型拖放到 另一个 App 或空白位置 通过“快速查看” 在他们空间中查看模型 这种方式能让用户 很好地看到模型的真实尺寸 并将逼真的照明效果应用于模型 让模型看起来更真实 用户可以把它固定在一个表面上 把它转过来、让它变大或变小 除了拖放 你还可以在模型元素上 启用捏合并拖动功能 以便在内嵌显示时旋转模型 我们可以将模型上下倾斜 模型将在释放时恢复正常

    启用这种内嵌旋转行为 可以通过指定 stageMode 等于 模型元素上的 orbit 来实现 沿 y 轴进行旋转 手势操作期间 允许小幅度垂直倾斜 浏览器引擎也会 缩放和偏移模型 以确保它在旋转过程中 保持在页面表面下 如果这个 stagemode 旋转行为 还不足以满足你的用例 可以手动实现自定义交互 如果要以特定方式 手动移动模型和控制模型方向 可以使用 JavaScript 来实现 你可以精确控制 模型在虚拟空间中的位置和方向 这一点可以通过更改 模型元素公开的转换矩阵来实现

    转换矩阵通过 entityTransform 属性公开 模型加载时 浏览器会计算默认定位 所需的转换并将结果保存到 entityTransform 属性中 ready promise 解析完成后 将填充这一属性

    我来展示一个自定义模型位置的例子 在这里我要提供一个链接 这个链接能将模型旋转到面向右侧 在 turnRight 函数中 读取来自 entityTransform 属性的 浏览器计算的转换矩阵 接着使用 rotateAxisAngle 方法 沿 y 轴旋转 90 度 这个方法是 DOMMatrix 类的现有 API 0-1-0 表示 y 轴 90 表示旋转 90 度 得到新矩阵后 将它设置回 entityTransform 属性 才能生效 entityTransform 矩阵支持的运算 包括均匀缩放、旋转和平移 如果为 entityTransform 属性 指定一个包含不支持的操作的矩阵 则会收到报错 对于大多数用例 默认实体转换应该可以满足要求 但可能有人想弄懂默认计算 背后的数学逻辑 要搞懂这一点 我们需要回到基础知识 并介绍单位矩阵的实体转换行为

    如果将实体转换设置为单位矩阵 它会将 USDZ 文件的原点 与模型元素的中心点对齐 请记住 模型仅在 页面表面下的空间内呈现 因此 向前延伸的部分都将被截断 此外 在 USDZ 文件中渲染 1 厘米 相当于 CSS 中的 1 厘米 在 CSS 中约为 38px 在 visionOS 中 当用户远离时 Safari 浏览器窗口会变大 因此 当模型显示在网页上时 USDZ 文件中使用的单位 和现实世界中的物理单位 之间没有关系 如果需要展示物体的实际物理尺寸 最好的方法是 让用户将物体拖出页面 并通过“快速查看”查看 正如我们之前介绍的那样 使用 entityTransform 属性时 你可以充分发挥自己的创意 在前面的示例中 随着我们切换相机的不同细节 它放大了模型的不同部分 只需要移动它 就可以使用模型动画 演示打开和关闭相机屏幕 我来演示一下具体方法 USDZ 文件格式支持 在文件本身中定义动画 并且所有主要创作工具 都能很好地支持这个功能 一些 USDZ 文件还包含 多个动画轨道 模型元素支持播放 USDZ 文件中定义的 第一个动画轨道 对于简单的循环动画 你可以使用 loop 和 autoplay 属性 如果想手动控制动画 可以在模型元素上 使用 play 和 pause 方法 可以使用 paused 属性 确定动画是否正在播放 你可能很熟悉这几个 API 因为它们与视频元素中的 API 相同

    对于更复杂的用例 可以使用 3D 建模软件 为模型构建时间线 用动画表现不同状态的切换 在相机模型文件中 我先展示打开和关闭相机闪光灯 接着展示打开和关闭相机屏幕 动画信息存储在 USDZ 文件中 在将动画模型放入模型元素中时 可以使用 currentTime 属性 跳转到时间线中的任意点 例如 如果想打开相机上的闪光灯 只需将 currentTime 属性设置为 1 请记住 currentTime 属性 的单位是秒 同样 如果我想打开屏幕 我只需将这个属性设置为 3 请注意模型在没有任何隐式动画 的情况下是如何即时更新的 这让我们可以跳转到 不连续的时间戳 以实现我们需要的任何特定效果 通过将 currentTime 与一些交互挂钩 我们可以打造有趣的体验

    这里有一个滑块 它的值介于 2 和 3 之间 表示涵盖屏幕打开动画 的这部分时间线 我添加了一个事件侦听器 来侦听滑块值的变化 侦听到变化时 我把当前时间设置为滑块的值 这样就可以让访客使用滑块 来控制屏幕的位置 你可以将这个创意 应用到其他交互 例如滚动页面 或自定义拖动事件 你还可以用自己的方式 组合 currentTime 和 entityTransform 在前面的相机页面示例中 动画根据计时器而变化 各个部分使用 currentTime 属性 进行动画处理 而整个相机的动作 使用 entityTransform 属性 进行动画处理 页面效果非常好 但我们还可以更进一步 可以添加个人风格 例如允许用户对产品进行自定义 但是你可能不知道要提前 把哪些文本放到 USDZ 模型中 这时候就可以使用动态生成的模型 如果你的用例需要显示 依赖于运行时用户输入的模型 可以使用 JavaScript 以编程方式 在浏览器中生成一个 USDZ 文件 并将它显示在模型元素中 Three.js 是一个强大的 JavaScript 库 支持以编程方式创建 3D 模型 Three.js 本身就是一个很深的课题 所以我们今天不打算讨论 其中的细节 概括来说 THREE.Scene 对象 包含以程序方式创建的模型 因此 假设你已经有一个 精心设计的场景对象 Three.js 附带一个 可以导入的 USDZ 导出器模块 导入后 你可以使用 parseAsync 方法 为模型场景的完整 USDZ 文件 生成数据块 可以使用 URL.createObjectURL 方法 创建指向已生成的数据块的对象 URL 有了对象 URL 我们可以将它设置为 模型元素的 source 属性 然后它就会开始渲染 借助这项技术 我们不用再局限于 使用离线准备的 静态已知 USDZ 文件

    我们可以根据访客输入的数据 向模型添加自定义项 就像为产品添加名称 或更改文本颜色一样

    很棒的一点是 模型仍然可以拖出 并在用户的空间内查看

    ModelElement 支持很多 API 我们今天只介绍了其中的一部分 如果你在网页上采用模型 或许可以用到其他的 API

    如果要了解关于模型元素的更多信息 可以访问 MDN 文档页面 还可以查看 W3C 网站上的 模型元素方案 你可以在本讲座的 相关链接中找到这些 URL 我来介绍一下另一类内容 沉浸式媒体 去年 我们推出了在网站上 显示全景照片和空间照片的方法 我们正在将支持扩展到 空间视频、180 度、360 度 和宽视野视频 以及 Apple 沉浸视频 我们还对全景照片和空间照片的 呈现方式做了一些更新 在 iPhone 15 Pro 或更新机型上 你可以直接使用“相机”App 拍摄空间视频 在 Apple Vision Pro 的照片 App 中 还能以空间方式查看这些照片 现在 visionOS 新增了 对三种沉浸式媒体类型的支持 即 180 度、360 度和宽视野视频 这些媒体类型不仅限于平面 而是环绕用户以提供沉浸式体验 此外还新增了 对 Apple 沉浸视频的支持 高分辨率立体视频 与拍摄视频的相机镜头完美配合 你可以在今年的 WWDC 讲座 “探索 visionOS 的视频体验”中 了解这些新的媒体类型

    当沉浸式媒体文件嵌入到页面上时 例如这个 360 度视频 它将渲染为 2D 视频 为了让人身临其境地观看 可以全屏显示你的视频 视频将以正确的投射方式 环绕在用户周围 全屏播放器还支持立体内容 常见的视频格式有 180 度视频和 Apple 沉浸视频 你以前可能拍摄过 一些沉浸式媒体内容 现在可以把它们用到你的网站上了 你可以使用现有的视频元素 在网站中嵌入这些媒体类型 不涉及新元素或属性 你还可以使用 HTTP Live Streaming 像往常一样提供大型视频资源 对于 180 度、360 度和宽视野媒体 文件应符合 APMP 格式 即 Apple Projected Media Profile 其中包含用于描述媒体投射的 额外元数据 如需了解如何将 现有媒体转换为 APMP 请观看今年的 WWDC 讲座: “了解 Apple Projected Media Profile” 要了解 Apple 沉浸视频 请观看 “了解 Apple 沉浸视频技术” 这是宽视野 APMP 的示例 元数据将采集 录制期间使用的相机参数 然后由 visionOS 呈现媒体 呈现的形状能将 每个像素与预期位置对齐 从而在播放过程中产生正确的投影 请注意在全屏视图中 即使是在边缘 直线看起来也是笔直的 这就是 APNP 的魅力所在 视频元素的默认控件 支持用户进入全屏 我们还可以借助 JavaScript 使用requestfFullScreen API 以编程方式进入全屏 事实上 这就是你在网页中 呈现全景照片和空间照片所用的 API 对于全景图 现在可以 为同一图片元素提供不同的源 这样就可以在全屏显示之前 显示合适的缩略图 进入全屏后 将使用最宽的变体

    对于空间照片 requestFullscreen API 的工作原理相同 内嵌显示时 空间照片将渲染为平面 2D 图像 并在全屏显示时进行空间渲染 根据我的经验 我总是需要告诉访客 某个图片实际上是空间图片 他们要点击才能查看图片细节 以后 这项操作可能会变得更简单 可以使用新属性 controls 来实现 从 visionOS 2.4 开始 都已添加 这个属性来实现开发者预览功能 controls 属性会添加空间照片标记 表示图片是空间照片 访客只需要点击全屏按钮 就可以轻松查看图像的空间版本 实现这些甚至不需要 编写一行 JavaScript 代码 与所有开发者预览功能一样 你必须明确启用这项功能 才能使用它 要启用这项功能 需要前往设置> App > Safari 浏览器>高级>功能标志 并启用 Spatial Image Controls API 现在我们还要启用另一个功能 网站环境 也就是我们接下来要讨论的功能 网站环境是一项新的开发者预览功能 今年 我们还允许网站 为访客提供虚拟环境 我来说一下运作机制 这个示例页面指定了 一个 USDZ 文件作为环境 用户可以通过页面菜单 选择显示这种环境 同时不需要离开 Safari 浏览器和网站 用户可以使用数字旋钮 全身心融入到沉浸式环境中 这是提升网站的绝佳方式 让用户不再局限于浏览器窗口中

    要提供环境 需要使用链接元素 指定等于 spatial-backdrop 的 rel 然后使用 href 属性 指向你的环境 USDZ 文件 和 3D 模型一样 我们可以使用 environmentmap 属性 为 USDZ 文件提供自定义 IBL 有了精心设计的环境 网站访客会觉得自己就好像 穿越到了另一个地方 比如餐厅、潜艇或地牢 由于这是一个开发者预览功能 你需要先在“设置”中启用这项功能 然后才能使用 在网页标准化的过程中 标记将来可能会更改 Apple 正在积极引领 这项功能的开发 你的反馈将对这项功能的未来发展 发挥重大作用 要了解有关创建自定义环境 的更多信息 请观看 WWDC24 讲座 “为你的沉浸式 visionOS App 创建自定环境” 今天 我们介绍了许多 新的空间网页功能 我们介绍了 新的 HTML 模型元素 它支持交互、 自定义照明和手动放置 借助现有的视频元素 我们可以直接显示网站中 一系列新的沉浸式媒体 你可以抢先了解 未来的网站环境会是什么样子

    为帮助你轻松入门 我们在 webkit.org 上 添加了一些模型元素的示例用法 亲自使用 Apple Vision Pro 观看 才是体验这些功能的最佳方式 如果你做好了准备 就马上试试在自己的 网页中添加 3D 模型吧 给网站访客带去 令人惊叹的新体验 如果你的网站提供视频服务 现在就可以在网站上添加沉浸式媒体 希望大家可以试着添加自定义环境 并与我们分享你的反馈 除了空间网页 我们还为网页增加了许多新功能 如需了解更多信息 请观看 今年的讲座 “Safari 浏览器和 WebKit 新功能”

    如果要报告关于网页技术的问题 或是提出功能请求 请前往 WebKit 的问题追踪页面 网址是 bugs.webkit.org 如要报告关于 Safari 浏览器界面、visionOS 或其他 Apple 平台的问题 请访问 feedbackassistant.apple.com 我们期盼 大家能利用这些新技术构建精彩网页 感谢大家参加这次讲座 祝你们在 WWDC 度过美妙的时光

    • 1:00 - Embed 3D models - Basic syntax

      <model src="teapot.usdz"></model>
    • 4:15 - Embed 3D models with source element

      <model>
        <source src="teapot.usdz" type="model/vnd.usdz+zip">
      </model>
    • 5:30 - Example server configurations to add USDZ MIME type support

      # Apache
      
      ```
      AddType model/vnd.usdz+zip .usdz
      ```
      
      # NGINX mime.types
      
      ```
      types {
        ...
        model/vnd.usdz+zip usdz;
      }
      ```
      
      # Python HTTP server
      
      ```
      import http.server
      Handler = http.server.SimpleHTTPRequestHandle
      Handler.extensions_map = { ".usdz": "model/vnd.usdz+zip" }
      httpd = http.server.HTTPServer(("", 8000), Handler)
      httpd.serve_forever()
      ```
    • 5:51 - Specify a fall back image for element

      <model src="camera.usdz">
        <img src="camera.png">
      </model>
    • 6:17 - Example 2D rendering fallback experience

      <!-- <model-viewer> library from https://modelviewer.dev/ -->
      <script type="module" 
        src="https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js">
      </script>
      
      <model src="camera.usdz">
        <!-- Fallback experience for backward compatibility -->  
        <model-viewer src="camera.glb"></model-viewer>
      </model>
    • 6:52 - Detect if the model element is supported

      if (window.HTMLModelElement) {
        // Supported by this browser
      } else {
        // Not supported by this browser
      }
    • 7:32 - Implementing a loading indicator using .ready promise

      <model src="camera.usdz" id="mymodel"></model>
      
      <script>
      const mymodel = document.getElementById("mymodel");
      
      if (window.HTMLModelElement) {
        mymodel.ready.then(result => {
      	// Hide the loading indicator
      	// Show the model
       }).catch(error => {
      	// Loading error occurred, show a retry button
       });
      }
      </script>
    • 8:23 - CSS example for setting the color of the virtual space

      <body>
        <!-- page content here -->
        <model src="camera.usdz" class="my_model"></model>
      </body>
      
      <style>
      :root {
        --main-bg-color: rgb(240, 240, 240);
      }
      
      body {
        background-color: var(--main-bg-color);
      }
      
      .my_model {
        /* set the virtual space color */
        background-color: var(--main-bg-color); 
      }
      </style>
    • 9:21 - CSS example for frosted glass panel on top of a

      <div class="container">
        <model src="camera.usdz"></model>
        <div class="panel"> ... </div>
      </div>
      
      <style>
      .container {
        position: relative;
      }
      
      .panel {
        position: absolute;
        left: 60%;
        backdrop-filter: blur(20px);
        background: linear-gradient(to right,
                                    rgba(240, 240, 240, 0.8),
                                    rgba(240, 240, 240, 0.5) 4px);
      }
      </style>
    • 10:56 - Setting image-based lighting (IBL) with environmentmap

      <model src="camera.usdz" environmentmap="sunset.exr"></model>
    • 12:41 - Allowing inline rotation with stagemode

      <model src="teapot.usdz" stagemode="orbit"></model>
    • 13:31 - Customize placement with JavaScript entityTransform

      <model src="teapot.usdz" id="mymodel"></model>
      
      <script>
      const mymodel = document.getElementById("mymodel");
      mymodel.ready.then(result => {
        const matrix = mymodel.entityTransform; // DOMMatrixReadOnly
      });
      </script>
    • 13:49 - Make the model face right with entityTransform

      <model src="teapot.usdz" id="mymodel"></model>
      <a onclick="turnRight()">Right</a>
      
      <script>
      const mymodel = document.getElementById("mymodel");
      function turnRight() {
        const matrix = mymodel.entityTransform; // DOMMatrixReadOnly
        const newMatrix = matrix.rotateAxisAngle(0, 1, 0, 90);
        mymodel.entityTransform = newMatrix;
      }
      </script>
    • 15:03 - Setting the entityTransform to an identity matrix

      model.entityTransform = new DOMMatrix();
    • 16:31 - Basic animation control

      <model src="toy.usdz" id="mymodel" loop autoplay></model>
      <button onclick="toggleAnimation()">Play/Pause</button>
      
      <script>
      const mymodel = document.getElementById("mymodel");
      
      function toggleAnimation() {
        if (mymodel.paused) {
      	mymodel.play();
        } else {
      	mymodel.pause();
        }
      }
      </script>
    • 17:35 - Jump to animation timestamp using .currentTime property

      <model src="camera.usdz" id="mymodel"></model>
      
      <script>
      const mymodel = document.getElementById("mymodel");
      
      function openFlash() {
        mymodel.currentTime = 1; // Unit is seconds
      }
      
      function openScreen() {
        mymodel.currentTime = 3; // Unit is seconds
      }
      </script>
    • 18:11 - Update .currentTime with a slider

      <model src="camera.usdz" id="mymodel"></model>
      <input type="range" id="slider" min="2" max="3" step="any" value="2">
      
      
      <script>
      const mymodel = document.getElementById("mymodel");
      
      slider.addEventListener("input", (event) => {
        mymodel.currentTime = event.target.value;
      });
      </script>
    • 19:35 - Generate USDZ with three.js and display with

      import * as THREE from "three";
      import { USDZExporter } from "three/examples/exporters/USDZExporter.js";
      
      async function generateModel() {
      	const scene = new THREE.Scene();
      	// ... create a really nice scene procedurally ...
      
      	const bytes = await new USDZExporter().parseAsync(scene);
      	const objURL = URL.createObjectURL(new Blob([bytes]));
      
      	const mymodel = document.getElementById("mymodel");
      	mymodel.setAttribute("src", objURL);
      }
    • 23:10 - Embed immersive media

      <video src="spatial_video.mov"></video>  <!-- Single file -->
      <video src="360_video.m3u8"></video>  <!-- HTTP Live Streaming -->
    • 24:25 - Going full screen with Javascript for elements

      <video src="360_video.m3u8" id="player" controls></video>
      
      <script>
      const player = document.getElementById("player");
      player.requestFullScreen();
      </script>
    • 24:35 - Embed panoramas and offer full screen with Javascript

      <picture>
        <source media="(max-width: 799px)" srcset="thumbnail.jpg">
        <source media="(min-width: 800px)" srcset="panorama.jpg">
        <img src="panorama.jpg" id="pano">
      </picture>
          
      <script>
      const pano = document.getElementById("pano");
      pano.requestFullScreen();
      </script>
    • 24:57 - Embed spatial photos and offer full screen with Javascript

      <img src="spatial.heic" id="img">
        
      <script>
      const img = document.getElementById("img");
      img.requestFullScreen();
      </script>
    • 25:21 - Embed spatial photos with the new "controls" attribute

      <img src="spatial.heic" id="img" controls>
    • 26:49 - Provide a custom environment

      <link rel="spatial-backdrop" href="office.usdz" environmentmap="lighting.hdr">
    • 0:00 - 简介
    • visionOS Safari 团队今年针对空间网页推出了新功能,包括立体 3D 模型渲染、沉浸式媒体播放以及网站环境等开发者预览功能。

    • 0:55 - 嵌入 3D 模型
    • Web 开发在不断发展的过程中引入了 HTML 模型元素,使 3D 模型能够直接无缝嵌入到网页中。这项新功能现已成为 visionOS 上的 Safari 浏览器默认配置。它通过提供立体渲染,彻底改变了人们与 Web 内容的交互方式,使人们能够感知深度并从不同角度探索 3D 对象。

    • 21:24 - 呈现沉浸式媒体
    • 我们扩展了对网站上沉浸式媒体的支持,你可以嵌入各种格式,例如空间视频、180 度视频、360 度视频和宽视野视频。使用 iPhone 15 Pro 或更新机型,用户可以直接通过“相机”App 拍摄空间视频,然后在 Apple Vision Pro 上查看。

    • 26:14 - 提供自定环境
    • Safari 浏览器还推出了一项名为“网站环境”的全新开发者预览功能。这项功能允许网站使用 USDZ 文件创建虚拟环境,使访客能在保持 Safari 浏览器和网站可见的同时,体验餐厅、潜艇或地牢等沉浸式场景。 实现这一功能的具体方法为:使用特定的 HTML 标记、链接到 USDZ 文件并使用 IBL 来自定环境。这项功能目前正在开发中,欢迎大家提供反馈,共塑未来前景。

Developer Footer

  • 视频
  • WWDC25
  • 空间网页的新功能
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载 (英文)
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    获取 Apple Developer App。
    版权所有 © 2025 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则