AR.jsでインスタストーリーのような操作感を実現する

#インスタストーリーの操作
ストーリー作成で、テキストサイズや位置を変更したい時、ピンチイン・アウトやドラッグで簡単に操作できる。
最近話題のGoogleの動物たちや、一般的なARアプリも、同じような操作感で3Dモデルを動かすことができる。
これをマーカーベースのAR.jsでも実現したかった。

```
aframe 0.8.0
ar.js 1.7.7
```

#ソースコード

```index.js
function pintch() {
    // イベントリスナー用の透明でフルサイズのレイヤーを準備する。
    let divElement = document.getElementById("target");

    let elScale = {width: 1, height: 1}
    let elPos = {x: 0, y: 0, z: 0}
    
    let posX = 0;
    let posY = 0;
    let prevPosX = 0;
    let prevPosY = 0;

    // a-obj-model タグをid指定で取得
    let el = document.querySelector("#obj_model");

    // base
    let beseDistance = 0;
    let baseWidth = 0;
    let baseHeight = 0;

    // timeout id
    let timeoutId;

    // touchmoveイベントリスナー
    divElement.addEventListener("touchmove", function(event) {
        event.preventDefault();

        let touches = event.changedTouches;

        if ( touches.length > 1 ) {
            // 二本指で操作しているときの処理（ピンチ）
            let x1 = touches[0].pageX;
            let y1 = touches[0].pageY;

            let x2 = touches[1].pageX;
            let y2 = touches[1].pageY;

            let distance = Math.sqrt( Math.pow( x2-x1, 2 ) + Math.pow( y2-y1, 2 ) );

            clearTimeout( timeoutId );

            if ( beseDistance && baseWidth && baseHeight ) {
                let scale = distance / beseDistance;

                if ( scale && scale != Infinity ) {
                    elScale.width = baseWidth * scale;
                    elScale.height = baseHeight * scale;

                    // a-obj-model の大きさを変更
                    el.setAttribute('scale', {x: elScale.width, y: elScale.height, z: elScale.width});
                }

                timeoutId = setTimeout( function () {
                    beseDistance = 0;
                    baseWidth = 0;
                    baseHeight = 0;
                }, 100 );

            } else {
                console.log('else');
                beseDistance = distance;
                baseWidth = elScale.width;
                baseHeight = elScale.height;
            }
        } else {
            // 一本指で操作しているときの処理（ドラッグ）
            if (posX == 0) {
                prevPosX = touches[0].pageX;
                prevPosY = touches[0].pageY;
                posX = touches[0].pageX;
                posY = touches[0].pageY;
            } else {
                prevPosX = posX;
                prevPosY = posY;
                posX = touches[0].pageX;
                posY = touches[0].pageY;
            }

            let distanceX = posX - prevPosX;
            let distanceY = posY - prevPosY;

            let offset = 30;

            elPos.x = elPos.x + distanceX / offset;
            elPos.y = elPos.y + distanceY / offset;

            // a-obj-model の位置変更
            el.setAttribute('position', {x: elPos.x, y: 0, z: elPos.y});
        }
    });
}
```

今回使用しているobjのサイズや位置の変更は、以下の部分で行なっている。
マーカーベースなので、位置の変更は2軸だけを考える。

```index.js
// a-obj-model タグをid指定で取得
let el = document.querySelector("#obj_model");

// a-obj-model の大きさを変更
// x, y, z共に elScale.width でOKだが、気分的に縦と横だけ区別したかった
el.setAttribute('scale', {x: elScale.width, y: elScale.height, z: elScale.width});

// a-obj-model の位置変更
el.setAttribute('position', {x: elPos.x, y: 0, z: elPos.y});

// 属性指定の値を変更する
// el.setAttribute('属性', {x: x方向の値, y: y方向の値, z: z方向の値});
```

#注意点
これを実装する際、デフォルトのtouchmove イベントリスナーを無効にする必要がある。
こちらの記事を参考にしてください。

[AR.jsでスクロールバーが発生する件](https://qiita.com/F_PEI/items/7ee348328733d65a87ef)


#参考
- [ピンチイン・ピンチアウトでズームする方法](https://lab.syncer.jp/Web/JavaScript/Snippet/39/)
- [Aframe](https://aframe.io/docs/0.9.0/components/scale.html)