【征文计划】Rokid JSAR 实践指南:打造沉浸式 "声动空间盒" 交互体验

【征文计划】Rokid JSAR 实践指南:打造沉浸式 "声动空间盒" 交互体验

概述

本文基于 Rokid JSAR 框架,从开发者视角完整复现一个具备听觉与视觉交互的空间应用 "声动空间盒"。项目通过 多音阶音频播放、3D 立方体纹理渲染、GUI 按钮交互 等模块,实现了在三维空间中可视化、可点击、可听见的沉浸式体验。开发过程中结合 Babylon.js 渲染管线与 JSAR 空间文档结构,展示了如何以 Web 前端思维快速构建 AR 场景内容,让"空间小程序"真正还原 Web 开发的所见即所得理念。

项目概述:声动空间盒交互体验

1、素材图片准备

2、音频准备

音频模块:多音阶播放逻辑设计

createAudioPlayer 函数:通过导入音频文件获 arrayBuffer、封装为 audio/mpeg 格式 Blob、生成临时 URL,返回可创建 Audio 实例播放、且支持 volume 参数调音量的播放函数

预加载处理:用立即执行异步函数,提前加载 Do、Ri、Mi、Fa音频文件并存储于 audios 对象,供后续点击按钮直接调用

js 复制代码
async function createAudioPlayer(name: string) {
  const arrayBuffer = await import(`../audio/${name}`);
  const blob = new Blob([arrayBuffer], { type: 'audio/mpeg' });
  const objectUrl = URL.createObjectURL(blob);
  return (volume?: number) => {
    const audio = new Audio(objectUrl);
    if (volume) {
      audio.volume = volume;
    }
    audio.play();
  };
}

const audios = {} as Record<string, (volume?: number) => void>;
(async function() {
  audios['Do'] = await createAudioPlayer('40.mp3');
  audios['Ri'] = await createAudioPlayer('42.mp3');
  audios['Mi'] = await createAudioPlayer('44.mp3');
  audios['Fa'] = await createAudioPlayer('45.mp3');
})();
纹理定制:立方体表面视觉增强

获取 ID 为 box1 的 3D 立方体;加载砖块纹理图 brickwork.jpeg 转为位图,通过离屏画布先绘黄色矩形再叠加砖块图,提取像素数据生成 Babylon 纹理 wallTexture(配置格式、采样模式等),最后将其设为立方体材质的漫反射纹理,完成外观定制。

js 复制代码
const wall = spatialDocument.getSpatialObjectById('box1');
createImageBitmap(new Blob([wallPic], { type: 'image/jpeg' })).then((bitmap) => {
  const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
  const ctx = canvas.getContext('2d');

  ctx.fillStyle = 'yellow';
  ctx.fillRect(0, 0, 200, 100);

  ctx.drawImage(bitmap, 0, 0);
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const wallTexture = new BABYLON.RawTexture(
    imageData.data,
    imageData.width,
    imageData.height,
    BABYLON.Engine.TEXTUREFORMAT_RGBA,
    spatialDocument.scene,
    false,
    false,
    BABYLON.Texture.TRILINEAR_SAMPLINGMODE);

  const wallMaterial = wall.asNativeType<BABYLON.Mesh>().material as BABYLON.StandardMaterial;
  wallMaterial.diffuseTexture = wallTexture;
});
界面交互:3D GUI 按钮与事件绑定

获取 ID 为 gui 的 3D 平面对象,其 shadowRoot 作为 GUI 容器;选中所有 sub 类元素对应 DoRi 等,设置尺寸背景色等样式形成按钮;绑定事件:鼠标进入变深紫、离开恢复深灰、点击时暂变深色并按文本从 audios 取对应函数播放音频音量 1.0;调用 spatialDocumentwatchInputEvent 监听空间输入,确保 3D 场景鼠标交互生效

js 复制代码
const guiPlane = spatialDocument.getSpatialObjectById('gui');
const panel = guiPlane.shadowRoot;

const subChildren = panel.querySelectorAll('.sub');
for (let sub of subChildren) {
  const subElement = sub as HTMLElement;
  subElement.style.backgroundColor = 'rgba(20,33,33,.95)';
  subElement.style.height = '200px';
  subElement.style.width = '300px';
  subElement.style.marginLeft = '50px';
  subElement.style.fontSize = '80px';
  subElement.style.color = '#fff';
  subElement.style.textAlign = 'center';
  subElement.style.border = '15px solid yellow';
  subElement.style.borderRadius = '50px';
  subElement.style.paddingTop = '20px';

  subElement.addEventListener('mouseenter', () => {
    subElement.style.backgroundColor = 'rgba(100,0,120,.95)';
  });
  subElement.addEventListener('mouseleave', () => {
    subElement.style.backgroundColor = 'rgba(60,33,33,.95)';
  });
  subElement.addEventListener('mouseup', () => {
    subElement.style.backgroundColor = 'rgba(30,33,33,.95)';
    const playAudio = audios[subElement.textContent];
    if (playAudio) {
      playAudio(1.0);
    }
  });
}
spatialDocument.watchInputEvent();

场景容器:3D 可视化空间渲染核心

立方体元素:空间物体与样式绑定

cube 标签创建一个 3D 立方体,id=box1 与头部样式中的 #box1 关联,会自动应用样式中定义的位置、旋转和材质;size=0.8 是基础尺寸,width=1.4 即 X 轴长度、depth=0.2 即 Z 轴厚度,额外调整立方体的长宽厚,最终呈现一个扁长形的粉紫色立方体。

js 复制代码
<space>
  <!-- 立方体:ID为box1,对应style中#box1的配置 -->
  <cube id="box1" size="0.8" width="1.4" depth="0.2"></cube>
  <!-- 其他3D元素... -->
</space>

平面元素:GUI 面板与布局结构

plane 标签创建的元素 id=gui,与头部样式中的 #gui 关联,会应用缩放和旋转配置,成为 3D 空间中承载 GUI 的 "面板";内部的 div id=root 是 GUI 的容器,用内联样式(padding:10px、gap:20px)控制内部元素的间距;两个 span 分别承载:4 个带 class="sub" 的音阶文本;白色大字体的说明文字,直接点明项目核心 ,还原 Web 开发体验,所见即所得

js 复制代码
<plane id="gui">
  <!-- 平面内部的GUI容器:用div组织内容,设置内边距和间距 -->
  <div id="root" style="padding:10px;gap:20px;">
    <!-- 第一行:4个音阶按钮(class="sub",后续脚本会绑定点击事件) -->
    <span>
      <span class="sub">Do</span>
      <span class="sub">Ri</span>
      <span class="sub">Mi</span>
      <span class="sub">Fa</span>
    </span>
    <!-- 第二行:说明文字 -->
    <span style="color:white;font-size:70px;line-height:1.3;">
      空间小程序还原最开始的 Web 开发体验,并所见即所得。
    </span>
  </div>
</plane>

效果展示:3D 场景视觉与交互呈现

呈现出一个 3D 面板,面板上有 Do、Ri、Mi、Fa等带样式的按钮,下方配有文字空间小程序,还原最开始的 Web 开发体验,并非所想即所得。整体营造出在 3D 空间中展示交互界面与相关说明的效果,似乎是在演示空间小程序里类似 Web 开发相关的交互与呈现

AR 调试:本地服务器与浏览器运行

1、web浏览器查看(用 serve 工具启动一个本地服务器,将端口指定为 8080,并开启跨域资源共享(CORS)功能,方便在开发中处理跨域请求)

bash 复制代码
serve -p 8080 --cors

2、浏览器看到项目目录即为服务器启动成功

3、浏览器访问如下地址

bash 复制代码
https://m-creativelab.github.io/jsar-dom/?url= http://localhost:8080   

总结

本项目以 Rokid JSAR 框架为核心,完整展示了从 空间文档结构构建、音频逻辑编程、纹理渲染到 GUI 交互绑定 的全链路开发流程。通过 Web 前端的直观方式,开发者不仅能快速实现 AR 空间中的多模态交互,还能以熟悉的 DOM 思维探索空间计算的无限可能。"声动空间盒" 不仅是一场技术实验,更是 Web 技术与空间计算融合的实践样本,它让开发者在三维世界中看得见代码的节奏,听得见交互的回响。

相关推荐
携欢2 小时前
Portswigger靶场之Exploiting a mass assignment vulnerability通关秘籍
前端·安全
什么芋泥香蕉3303 小时前
比 Manus 还好用?这款国产 AI,让 Python 小白也能玩转编程
前端·后端
为java加瓦3 小时前
前端学AI:如何写好提示词(prompt)
前端·人工智能·prompt
qq_1841776773 小时前
前端自动部署项目到服务器
服务器·前端·javascript
非凡ghost3 小时前
猫眼浏览器(Chrome内核增强版浏览器)官方便携版
前端·网络·chrome·windows·软件需求
C2X3 小时前
Vue3.0 学习总结
前端
汤姆Tom3 小时前
CSS 新特性与未来趋势
前端·css·面试
尘世中一位迷途小书童3 小时前
🚀 pnpm + Monorepo 实战指南:现代前端项目管理的最佳实践
前端·架构
杨超越luckly3 小时前
HTML应用指南:利用GET请求获取全国中国建设银行网点位置信息
前端·arcgis·html·数据可视化·门店数据