概要
スマートフォンで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マーカーで半透明の豆腐が出ました。
ピンチ操作で拡縮できるように
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点タッチでリセットできるようになりました。
動作デモはこちら。スマホでQRコードから飛んで、下のHiroマーカーを写すと試せます。
A-Frame AR with pinch scale
https://yummy-rustic-shame.glitch.me
参考
A-Frame 公式サンプルの model-viewer から必要なところだけいただきました。
aframe/examples/showcase/model-viewer at master · aframevr/aframe
https://github.com/aframevr/aframe/tree/master/examples/showcase/model-viewer