👆

AR.jsのオブジェクトタップ(クリック)によるイベント処理の実装

2024/01/31に公開

目的

AR.jsで、gltf model等のオブジェクトをタップ(クリック)した際に、イベント処理をできるようにします。

前提

AR.jsのA-Frame location basedを使用します。

サンプル

赤と黄のウォーターピッチャーがあり、それぞれタップするとテキストが表示されます。

スマートフォンでご覧ください。

サンプル動作確認済み環境

AR.js 3.4.5、A-Frame 1.3.0、iOS 17.3、Chrome 113.0.5672.121

コード解説

AR.jsの Basic example をベースに、オブジェクトタップに必要なコードを追加します。ただし、本題とは直接関係のない<a-gltf-model>を動的に作成するための javascript を追加しており、オブジェクトタップに必要なコードは javascript に記述している箇所もあります。

HTML

<body>
  <a-scene
    vr-mode-ui="enabled: false"
    arjs="sourceType: webcam; videoTexture: true; debugUIEnabled: false"
    renderer="antialias: true; alpha: true"
  >
    <a-camera gps-new-camera="gpsMinDistance: 5"></a-camera>
    <a-entity cursor="rayOrigin: mouse; fuse: false" raycaster="objects: .raycastable"></a-entity>
    <a-assets>
      <a-asset-item
        id="model"
        src="https://cdn.glitch.global/5fe87342-c8ef-49b0-ac98-21d3082649c3/1057_water_pitcher.glb?v=1706572627629"
      ></a-asset-item>
    </a-assets>
  </a-scene>
</body>

AR.jsの Basic example に、以下を追加します。

<a-entity cursor="rayOrigin: mouse; fuse: false" raycaster="objects: .raycastable"></a-entity>

raycaster="objects: .raycastable"とすることで、タップイベント対象にするオブジェクトに対しては、class="raycastable"の属性を追加します。

javascript

以降、<a-gltf-model>にオブジェクトタップに必要な属性、イベントリスナーを javascript にて実装します。

createGltfModel()

// gltf modelを作成する
function createGltfModel(e, lat, lon, height, scale, color) {
  const gltf = document.createElement("a-gltf-model");
  gltf.setAttribute("src", "#gltf");
  gltf.setAttribute("gps-new-entity-place", {
    latitude: e.detail.position.latitude + lat,
    longitude: e.detail.position.longitude + lon,
  });
  gltf.setAttribute("class", "raycastable");
  gltf.setAttribute('position', {x: 0, y: -100, z: 0});
  gltf.setAttribute("mesh-color", {
    scale: scale,
    color: color,
    height: height
  });
  return gltf;
}

<a-gltf-model>を動的に作成する関数に、class="raycastable"を追加します。

createObject()

// a-gltf-modelに、a-textとイベントリスナーを追加する
function createObject(e, lat, lon, height, scale, color, colorText) {
  const gltf = createGltfModel(e, lat, lon, height, scale, color);
  const text = createText(scale, colorText);
  gltf.appendChild(text);
  gltf.addEventListener("click", {
    text: text,
    handleEvent: this.onMenuButtonClick,
  });
  document.querySelector("a-scene").appendChild(gltf);
}

次に、<a-gltf-model>に、クリックイベントリスナーを追加します。

onMenuButtonClick()

// タップイベント処理(テキスト表示非表示)
function onMenuButtonClick(e) {
  const visible = this.text.getAttribute("visible");
  this.text.setAttribute("visible", !visible);
}

タップで、テキストを表示非表示させます。

コード

index.html

Discussion