2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AR.js Marker Based にピンチ操作を追加

Last updated at Posted at 2021-09-04

概要

スマートフォンでARマーカーを読み取らせて表示したオブジェクトをピンチ操作で拡縮したい、という需要があったのでチャレンジ。うまくいきました。

実装手順

豆腐を出すだけのシンプルなコード

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>A-Frame AR with pinch scale</title>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://raw.githack.com/jeromeetienne/AR.js/2.0.5/aframe/build/aframe-ar.js"></script>
  </head>
  <body>
    <a-scene embedded arjs>
      <a-marker preset="hiro">
        <a-box id="cube" material="opacity: 0.75;"></a-box>
      </a-marker>
      <a-entity camera></a-entity>
    </a-scene>
  </body>
</html>

hiroマーカーで半透明の豆腐が出ました。

aa.png

ピンチ操作で拡縮できるように

a-scene に独自のアトリビュート scale-controls を追加。

<a-scene embedded arjs scale-controls>

scale-controls を A-Frame に registerComponent して中身を書く(この例では cube という id の要素に対する拡縮操作にしています)。

<script>
      AFRAME.registerComponent("scale-controls", {
        init: function() {
          this.modelPivotEl = document.getElementById("cube");

          this.onTouchStart = this.onTouchStart.bind(this);
          this.onTouchMove = this.onTouchMove.bind(this);

          document.addEventListener("touchstart", this.onTouchStart);
          document.addEventListener("touchmove", this.onTouchMove);
        },

        onTouchStart: function(evt) {
          if (evt.touches.length === 3) {
            this.onTripleTouchStart(evt);
          }
        },

        onTouchMove: function(evt) {
          if (evt.touches.length === 2) {
            this.onPinchMove(evt);
          }
        },

        onTripleTouchStart: function(evt) {
          // reset
          var modelPivotEl = this.modelPivotEl;
          var modelScale = 1;
          modelPivotEl.object3D.scale.set(modelScale, modelScale, modelScale);
          this.modelScale = modelScale;
        },

        onPinchMove: function(evt) {
          // scaling
          var dX = evt.touches[0].clientX - evt.touches[1].clientX;
          var dY = evt.touches[0].clientY - evt.touches[1].clientY;
          var modelPivotEl = this.modelPivotEl;
          var distance = Math.sqrt(dX * dX + dY * dY);
          var oldDistance = this.oldDistance || distance;
          var distanceDifference = oldDistance - distance;
          var modelScale = this.modelScale || modelPivotEl.object3D.scale.x;

          modelScale -= distanceDifference / 50;
          modelScale = Math.min(Math.max(0.1, modelScale), 2.0);
          // Clamp scale.
          modelPivotEl.object3D.scale.set(modelScale, modelScale, modelScale);

          this.modelScale = modelScale;
          this.oldDistance = distance;
        }
      });
    </script>

実行結果

ピンチで拡縮、3点タッチでリセットできるようになりました。

ezgif.com-gif-maker.gif

動作デモはこちら。スマホでQRコードから飛んで、下のHiroマーカーを写すと試せます。

exported_qrcode_image_600.png

A-Frame AR with pinch scale
https://yummy-rustic-shame.glitch.me

hiro.png

参考

A-Frame 公式サンプルの model-viewer から必要なところだけいただきました。

aframe/examples/showcase/model-viewer at master · aframevr/aframe
https://github.com/aframevr/aframe/tree/master/examples/showcase/model-viewer

2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?