Interactive area

Refers to an area captured by the sensor which is defined in the code and is used for triggered actions.

Bear in mind that more than area can be defined, so for example, we can define the whole area captured measure from the sensors* up to the a certain value and also area within this region which can be used for triggering the actions.

*Note that this will not necessarily matches the area which is captured with the sensors constraints. For more information and understanding of the ranges captured by the sensors check the tutorial Advanced app.

Herein we are going to create an application which changes the text when the user is either inside or outside that region. So, it will show some text when inside and different when outside.

Let’s first create a message “msg” in the HTML which will be then called from Javascript. The message as it can be seen below states “Outside of Interactive area”, and will change when an user is in or outside the defined area.

The scripts in purple are also required to make this work, so keep that in mind and copy the lines to make sure it works properly!

HTML

<html>
<head>
</head>

<body> 
<h1><h1 id="msg">Outside of Interactive area</h1></h1>


<div id="position-viewer">
<div id="interactive-area"></div>
<div id="player1" class="player"></div>
<div id="spinecenter1"></div>
</div>
<canvas id="skeletonsCanvas" width="640" height="480" ></canvas>
<div id="user-position"></div>


<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.0/TweenMax.min.js"></script>


</body>

</html>

 

We are going to add some lines as well onto the CSS to give some style and make visible the player and its position within the canvas along with the area which is captured by the sensors.

The position-viewer refers to the whole area captured by the sensors whereas the interactive-area to be area in which will be triggered the required action. User position does not come into play that is why is set to display:none to hide it.

CSS

/* application css */

body{
width: 100%;
height: 100%;
}

#main-container{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: #efc31a;
overflow: hidden;
}

/* ---- Position Viewer ---- */

#position-viewer{
position: absolute;
bottom: 100px;
right: 100px;
width: 180px;
height: 180px;
background-color: rgba(255,255,255,0.1);
border: 1px solid #00f;
}

#interactive-area{
position: absolute;
top: 0px;
left: 0px;
border: 1px solid #0f0;
background-color: rgba(255, 255, 255, 0.65);
}

.player{
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: none;
}

#user-position{
position:absolute;
color: #3399ff;
background-color: #000;
font-size: 50px;
padding: 20px;
top: 0;
right: 0;
font-family: sans-serif;
display:none;
}

 

We are going to define the area and the position of the viewer, also for better visual inspection we will show as well the X and Z (ie. the position in the horinzontal axis and the depth) on the top right of the screen,these are assigned to the spinecenter joint (see getskeletons) to capture the movements of the body.

Finally, we are going to add the required line into the Javascript code to change the HMTL code. This will show a different sentence when is inside or outside the area defined.

JAVASCRIPT

/* Vision Range Area */
var xPosMin = 0;
var xPosMax = 100;
var zPosMin = 0;
var zPosMax = 100;

/* Interactive Area */
var xPosMin_i = 35;
var xPosMax_i = 65;
var zPosMin_i = 35;
var zPosMax_i = 65;
var xDistance = (xPosMax + (xPosMin * -1));
var zDistance = (zPosMax + (zPosMin * -1));

/* Variables handle the users position */
var mainXPos, xPos1, xPos2 = 0;
var mainZPos, zPos1, zPos2 = 0;

/* Other Variables */
var currentZone = 0;
var selectedZone = -1;
var webTest = false;


// POSITION VIEWER

function createPositionViewer(){
$('#interactive-area').css('height', zPosMax_i - zPosMin_i + '%').css('top', zPosMin_i + '%');
$('#interactive-area').css('width', xPosMax_i - xPosMin_i + '%').css('left', xPosMin_i + '%');
}

createPositionViewer();


// X AND Z MOVEMENT

function updatePos(sklxz){

var currentPlayer;
if(sklxz != null){
mainZPos = window['zPos' + sklxz];
mainXPos = window['xPos' + sklxz];
currentPlayer = window['player' + sklxz];
}else{
currentPlayer = window['player1'];
sklxz = 1;
}

$('#user-position').html('X = ' + mainXPos + ', Z = ' + mainZPos);
if( mainZPos <= zPosMin || mainZPos >= zPosMax || mainXPos <= xPosMin || mainXPos >= xPosMax){
$(window['player' + sklxz]).css('background-color', '#fff');
currentZone = 0;
}else if( mainZPos > zPosMin_i && mainZPos <= zPosMax_i && mainXPos > xPosMin_i && mainXPos <= xPosMax_i){
$(window['player' + sklxz]).css('background-color', '#f00');
currentZone = 2;
}else{
$(window['player' + sklxz]).css('background-color', '#000');
currentZone = 1;
}

if(currentZone != selectedZone){
selectedZone = currentZone;
changeContent(selectedZone); 
}

}

function changeContent(num){

  if(num >= 2){
     document.getElementById("msg").innerHTML = "In interactive area!";
  }else{
    document.getElementById("msg").innerHTML = "Outside of                  interactive area!";
}

}


/* application source */
var canvas = document.getElementById("skeletonsCanvas");
var context = canvas.getContext("2d");

function getSkeletons(jsonObject) {

if (context == null) {
return;
}

var skl = 0;

context.clearRect(0, 0, canvas.width, canvas.height);
try {

for (var i = 0; i < jsonObject.skeletons.length; i++) {
skl++;


for (var j = 0; j < jsonObject.skeletons[i].joints.length; j++) {

var joint = jsonObject.skeletons[i].joints[j];

// Draw!!!
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(joint.x, joint.y, 10, 0, Math.PI * 2, true);
context.closePath();
context.fill();

var cordx = (joint.x * 100) / 640;
var cordy = 100 - ((joint.y * 100) / 480);
var cordz = (joint.z * 100) / 4;

if(joint.name == 'spinecenter') {

document.getElementById('spinecenter' + skl).style.left = cordx + 'px';
document.getElementById('spinecenter' + skl).style.top = cordy + 'px';
document.getElementById('spinecenter' + skl).style.zIndex = Math.floor(cordz);

window['xPos' + skl] = Math.round (document.getElementById('spinecenter' + skl).style.left.replace("px", ""));
window['yPos' + skl] = Math.round (document.getElementById('spinecenter' + skl).style.top.replace("px", ""));
window['zPos' + skl] = Number(document.getElementById('spinecenter' + skl).style.zIndex);

$('#player' + skl).css('top', ((window['zPos' + skl]-zPosMin)*100)/zDistance + '%');
$('#player' + skl).css('left', ((window['xPos' + skl]-xPosMin)*100)/xDistance + '%');

$('#player' + skl).show();

}

updatePos(1);

}
}

} catch(err) {
//do nothing
}

}

As this is not a built-in function but a custom one, we can test it on the web browser mimicking the sensors with the mouse.  For doing so, paste the following code into the javascript windows. Pressing the Enter key will let you activate the function that mimics the users position moving the cursor across the screen. On the bottom right you will see both areas, being the small square the active area.

// JUST FOR WEB TESTING

function follow(evt) {

  if(webTest){
    mainXPos = Math.round((evt.pageX/window.innerWidth) * 100);
    mainZPos = Math.round((evt.pageY/window.innerHeight) * 100);
    $('#player1').css('top', ((mainZPos-zPosMin)*100)/zDistance + '%').css('left', ((mainXPos-xPosMin)*100)/xDistance + '%').show();
    updatePos(null);
  }

}

function checkKeyUp(e) {

  e = e || window.event; 
  if (e.keyCode == '13') {
    document.onmousemove = follow; 
    webTest = true;
    $('#player1, #position-viewer').css('opacity', '1').show();
  }

}

window.onkeyup = checkKeyUp

We have created an example for you on this link to test this application*.

*If you are not logged in you will be taken to the login page.