📑
AR.jsでWebARしてみる(9) Detection
はじめに
WebARで分かったことメモしていく
参考
※Detection (detection.html)
を勉強する
デモ
- 以下の環境で動作を確認
- iOS 13.7 Safari
- Android 9 Chrome
- Windows10 Firefox 81.0.1
ソース
参考で紹介したサイトのDetection (detection.html)のソース
<!doctype HTML>
<html>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="js/aframe.min.js"></script>
<script src="js/aframe-ar.js"></script>
<body style="margin: 0px; overflow: hidden;">
<script>
let markerVisible = { "redMarker": false, "yellowMarker": false, "blueMarker": false };
AFRAME.registerComponent('registerevents', {
init: function ()
{
let marker = this.el;
marker.addEventListener('markerFound', function() {
markerVisible[ marker.id ] = true;
// console.log( markerVisible );
});
marker.addEventListener('markerLost', function() {
markerVisible[ marker.id ] = false;
// console.log( markerVisible );
});
}
});
AFRAME.registerComponent('loop',
{
init: function()
{
this.box = document.querySelector("#theBox");
},
tick: function (time, deltaTime)
{
// for convenience
let mv = markerVisible, r = "redMarker", y = "yellowMarker", b = "blueMarker";
if ( mv[r] && mv[y] && mv[b] )
this.box.setAttribute("color", "#654321");
else if ( mv[r] && mv[y] && !mv[b] )
this.box.setAttribute("color", "#FF8800");
else if ( mv[r] && !mv[y] && mv[b] )
this.box.setAttribute("color", "purple");
else if ( mv[r] && !mv[y] && !mv[b] )
this.box.setAttribute("color", "red");
else if ( !mv[r] && mv[y] && mv[b] )
this.box.setAttribute("color", "green");
else if ( !mv[r] && mv[y] && !mv[b] )
this.box.setAttribute("color", "yellow");
else if ( !mv[r] && !mv[y] && mv[b] )
this.box.setAttribute("color", "blue");
else // if ( !mv[r] && !mv[y] && !mv[b] )
this.box.setAttribute("color", "gray");
}
});
</script>
<a-scene embedded vr-mode-ui="enabled: false;" arjs="debugUIEnabled: false; detectionMode: mono_and_matrix; matrixCodeType: 3x3;">
<a-assets>
<img id="grid" src="images/border.png" />
</a-assets>
<a-marker type="pattern" url="data/kanji.patt" id="baseMarker">
<a-box id="theBox"
position="0 0.5 0"
color = "white"
material="src:#grid; transparent: true; opacity: 0.90;">
</a-box>
</a-marker>
<a-marker type="barcode" value="0" id="redMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: red">
</a-plane>
</a-marker>
<a-marker type="barcode" value="1" id="yellowMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: yellow">
</a-plane>
</a-marker>
<a-marker type="barcode" value="2" id="blueMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: blue">
</a-plane>
</a-marker>
<a-entity camera></a-entity>
<a-entity loop></a-entity>
</a-scene>
</body>
</html>
確認したこと
処理の流れ
3つの変数が false/true に切り替わり、その組み合わせにより立方体の色が決まる。3つの値は、a-markerタグのIDと同じ値にしておき、ARマーカーと連動するように工夫してる。
let markerVisible = { "redMarker": false, "yellowMarker": false, "blueMarker": false };
マーカーを認識したときにここの処理が実行される。認識したマーカーIDと連動した変数の値がtrue
になる
marker.addEventListener('markerFound', function() {/*省略*/});
認識していたマーカーが消えたときにここの処理が実行される。認識したマーカーIDと連動した変数の値がfalse
になる
marker.addEventListener('markerLost', function() {/*省略*/});
赤,黄,青色の板を表示するARマーカー
<a-marker type="barcode" value="0" id="redMarker" registerevents></a-marker>
<a-marker type="barcode" value="1" id="yellowMarker" registerevents></a-marker>
<a-marker type="barcode" value="2" id="blueMarker" registerevents></a-marker>
3つのマーカーは、githubのmarkers\barcodes
にある
応用してみた
canvasタグに色を塗り、それを立方体のテクスチャにして、同じことやってみた。
ソースはこれ
<!doctype HTML>
<html>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="js/aframe.min.js"></script>
<script src="js/aframe-ar.js"></script>
<body style="margin: 0px; overflow: hidden;">
<script>
let markerVisible = { "redMarker": false, "yellowMarker": false, "blueMarker": false };
AFRAME.registerComponent('registerevents', {
init: function ()
{
let marker = this.el;
marker.addEventListener('markerFound', function() {
markerVisible[ marker.id ] = true;
// console.log( markerVisible );
});
marker.addEventListener('markerLost', function() {
markerVisible[ marker.id ] = false;
// console.log( markerVisible );
});
}
});
AFRAME.registerComponent('loop',
{
init: function()
{
this.canvas = document.querySelector("#myCanvas");
this.canvas.width = 512;
this.canvas.height = 512;
this.context = this.canvas.getContext('2d');
this.coreAreaColer = "gray";
this.redAreaColer = "red";
this.yellowAreaColer = "yellow";
this.blueAreaColer = "blue";
this.redPos = 10;
this.yellowPos = 10;
this.bluePos = 10;
},
tick: function (time, deltaTime)
{
let mv = markerVisible, r = "redMarker", y = "yellowMarker", b = "blueMarker";
if ( mv[r] && mv[y] && mv[b] ){
this.coreAreaColer = "#654321";
this.redPos = 196;
this.yellowPos = 196;
this.bluePos = 196;
}else if ( mv[r] && mv[y] && !mv[b] ){
this.coreAreaColer = "#FF8800";
this.redPos = 196;
this.yellowPos = 196;
this.bluePos = 266;
}else if ( mv[r] && !mv[y] && mv[b] ){
this.coreAreaColer = "purple";
this.redPos = 196;
this.yellowPos = 266;
this.bluePos = 196;
}else if ( mv[r] && !mv[y] && !mv[b] ){
this.coreAreaColer = "red";
this.redPos = 196;
this.yellowPos = 266;
this.bluePos = 266;
}else if ( !mv[r] && mv[y] && mv[b] ){
this.coreAreaColer = "green";
this.redPos = 266;
this.yellowPos = 196;
this.bluePos = 196;
}else if ( !mv[r] && mv[y] && !mv[b] ){
this.coreAreaColer = "yellow";
this.redPos = 266;
this.yellowPos = 196;
this.bluePos = 196;
}else if ( !mv[r] && !mv[y] && mv[b] ){
this.coreAreaColer = "blue";
this.redPos = 266;
this.yellowPos = 266;
this.bluePos = 196;
}else{
this.coreAreaColer = "gray";
this.redPos = 266;
this.yellowPos = 266;
this.bluePos = 266;
}
this.context.fillStyle = this.coreAreaColer; this.context.fillRect(0,0, 512,512);
this.context.fillStyle = "#252525"; this.context.fillRect(101,186, 190,70);
this.context.fillStyle = "#050505"; this.context.fillRect(101,256, 190,70);
this.context.fillStyle = this.redAreaColer; this.context.fillRect(111,this.redPos, 50,50);
this.context.fillStyle = this.yellowAreaColer; this.context.fillRect(171,this.yellowPos, 50,50);
this.context.fillStyle = this.blueAreaColer; this.context.fillRect(231,this.bluePos, 50,50);
let material = this.el.getObject3D("mesh").material;
if(!material.map){
reutrn;
}else{
material.map.needsUpdate = true;
}
}
});
</script>
<a-scene embedded vr-mode-ui="enabled: false;" arjs="debugUIEnabled: false; detectionMode: mono_and_matrix; matrixCodeType: 3x3;">
<a-assets>
<canvas id="myCanvas"></canvas>
</a-assets>
<a-marker type="pattern" url="data/kanji.patt" id="baseMarker" cubeObject>
<a-box id="theBox"
position="0 0.5 0"
material="src:#myCanvas; transparent: true; opacity: 0.80;"
loop>
</a-box>
</a-marker>
<a-marker type="barcode" value="0" id="redMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: red">
</a-plane>
</a-marker>
<a-marker type="barcode" value="1" id="yellowMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: yellow">
</a-plane>
</a-marker>
<a-marker type="barcode" value="2" id="blueMarker" registerevents>
<a-plane position="0 0 0"
rotation="-90 0 0"
material="color: blue">
</a-plane>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
Discussion