Recipes

Most of these recipes can be pasted directly into the javascript console, once zig.js is embedded.

Embed zigfu browser plugin object

<script src='http://cdn.zigfu.com/zigjs/zig.min.js'></script>
...
zig.embed();
Click here to embed zig.js in current page

Back to top

Various versions, sensor state

console.log("Browser plugin installed: " + zig.pluginInstalled);
console.log("Browser plugin version: " + zig.pluginVersion);
console.log("Zig.js version: " + zig.version);
zig.addEventListener('statuschange', function() {
	console.log("Sensor connected: " + zig.sensorConnected);
});
Back to top

User found & lost notifications

The main zig object exposes 2 events that allow us to keep track of all tracked users in the sensor field of view. Below are two ways to get notifications when the userfound and userlost events occur.
// Method 1: specific event listeners
zig.addEventListener('userfound', function(user) {
	console.log('Found user. ID: ' + user.id);
});
zig.addEventListener('userlost', function(user) {
	console.log('Lost user. ID: ' + user.id);
});

// Method 2: listener object
zig.addListener({
	onuserfound: function(user){
		console.log('Found user. ID: ' + user.id);
	},
	onuserlost: function(user){
		console.log('Lost user. ID: ' + user.id);
	}
});
Back to top

Wait for first user with full body skeleton data

The EngageUsersWithSkeleton helps us distinguish between the tracked users, and the specific tracked users that are "in control". A user controlling a game or a UI is "engaged". There are many different ways to choose the engaged user (or users) - below are a few simple use cases.
var engager = zig.EngageUsersWithSkeleton(1);
engager.addEventListener('userengaged', function(user) {
	console.log('User engaged: ' + user.id);
});
engager.addEventListener('userdisengaged', function(user) {
	console.log('User disengaged: ' + user.id);
});
zig.addListener(engager);
Back to top

Wait for multiple users with full body skeleton data

Multiple users (2 in this case). Great for split screen gaming!
var multiEngager = zig.EngageUsersWithSkeleton(2);
multiEngager.addEventListener('userengaged', function(user) {
	console.log('User engaged: ' + user.id);
});
multiEngager.addEventListener('userdisengaged', function(user) {
	console.log('User disengaged: ' + user.id);
});
multiEngager.addEventListener('allusersengaged', function(users) {
	console.log('Engaged all users, starting game');
	// start game
});
zig.addListener(multiEngager);
Back to top

Print head position every frame for first engaged user

Skeleton data can be accessed via user.skeleton. Note that the skeleton data will be valid only if user.skeletonTracked is true (this will always be the case for user engaged by EngageUsersWithSkeleton). zig.Joints contains a full list of possible joints, but not all of them will always be available. This depends on the underlying middleware used by the ZDK.
var engager = zig.EngageUsersWithSkeleton(1);
engager.addEventListener('userengaged', function(user) {
	console.log('User engaged: ' + user.id);

	user.addEventListener('userupdate', function(user) {
		console.log('Head position: ' + user.skeleton[zig.Joint.Head].position);
	});
});
engager.addEventListener('userdisengaged', function(user) {
	console.log('User disengaged: ' + user.id);
});
zig.addListener(engager);
Back to top

Single user UI session

A common ZDK use case is a UI that can be controlled by one user at a time. The singleUserSession object (this is actually an instance of HandSessionDetector) notifies us when a tracked user is trying to control the UI, and ensures that only one user can be in control at a time. Note that this is great for a "Pure UI" application. If the UI being controlled is a game menu system, it might be better to choose the engaged user in a different way (EngageUsersWithSkeleton, for instance) and then add a HandSessionDetector to the engaged user. This will ensure that only the user that is actually playing the game can control the game menus. (See separate recipe)
zig.singleUserSession.addEventListener('userengaged', function(user) {
	console.log('User started UI session: ' + user.id);
});
zig.singleUserSession.addEventListener('userdisengaged', function(user) {
	console.log('User ended UI session: ' + user.id);
});
zig.singleUserSession.addEventListener('sessionstart', function(initialPosition) {
	console.log('Session started at ' + initialPosition);
});
zig.singleUserSession.addEventListener('sessionend', function() {
	console.log('Session ended')
});
Back to top

Game menu, controllable only by engaged user

// game menu. just a simple cursor for now
var cursor = zig.controls.Cursor();
var gameMenu = {
	onsessionstart : function(fp) { /* visualize session starting in game menu */ },
	onsessionupdate : function(p) { /* visualize session ending in game menu */},
	onattach : function(user) { user.addListener(cursor); }
};

var engager = zig.EngageUsersWithSkeleton(1);
engager.addEventListener('userengaged', function(user) {
	console.log('User engaged: ' + user.id);
	// create our hand session detector, add the game menu to it
	var hsd = zig.HandSessionDetector();
	hsd.addListener(gameMenu)
	// add the session detector to the engaged user - only this user can
	// control the gameMenu
	user.addListener(hsd);
});
engager.addEventListener('userdisengaged', function(user) {
	console.log('User disengaged: ' + user.id);
});
zig.addListener(engager);
Back to top

Horizontal Fader with range of 0 - 100

var f = zig.controls.Fader(zig.Orientation.X);
f.addEventListener('valuechange', function (f) {
	console.log('Fader value: ' + (f.value * 100));
})
zig.singleUserSession.addListener(f);
Back to top

Vertical Fader with 4 items

var f = zig.controls.Fader(zig.Orientation.Y);
f.itemsCount = 4;
f.addEventListener('hoverstart', function (f) {
	console.log('Fader item hover: ' + f.hoverItem);
});
f.addEventListener('hoverstop', function(f) {
	console.log('Fader item not hovering any more: ' + f.hoverItem);
})
zig.singleUserSession.addListener(f);
Back to top

Push detector events

// PushDetector
var pushDetector = zig.controls.PushDetector();
pushDetector.addEventListener('push', function(pd) {
	console.log('PushDetector: Push');
});
pushDetector.addEventListener('release', function(pd) {
	console.log('PushDetector: Release');
});
pushDetector.addEventListener('click', function(pd) {
	console.log('PushDetector: Click');
});
zig.singleUserSession.addListener(pushDetector);
Back to top

Swipe detector events

// SwipeDetector
var swipeDetector = zig.controls.SwipeDetector();
swipeDetector.addEventListener('swipeup', function(pd) {
	console.log('SwipeDetector: Swipe Up');
});
swipeDetector.addEventListener('swipedown', function(pd) {
	console.log('SwipeDetector: Swipe Down');
});
swipeDetector.addEventListener('swipeleft', function(pd) {
	console.log('SwipeDetector: Swipe Left');
});
swipeDetector.addEventListener('swiperight', function(pd) {
	console.log('SwipeDetector: Swipe Right');
});
swipeDetector.addEventListener('swipe', function(dir) {
	console.log('SwipeDetector: Swipe direction: ' + dir);
});
zig.singleUserSession.addListener(swipeDetector);
Back to top

Wave detector events

// WaveDetector
var waveDetector = zig.controls.WaveDetector();
waveDetector.addEventListener('wave', function(pd) {
	console.log('WaveDetector: Wave');
});
zig.singleUserSession.addListener(waveDetector);
Back to top

Steady detector events

// SteadyDetector
var steadyDetector = zig.controls.SteadyDetector();
steadyDetector.addEventListener('steady', function(sd) {
	console.log('SteadyDetector: Steady');
});
steadyDetector.addEventListener('unsteady', function(sd) {
	console.log('SteadyDetector: Unsteady');
});
zig.singleUserSession.addListener(steadyDetector);
Back to top

Simple cursor

This snippet shows how to control a cursor element based on the ZDK Cursor control:
  1. Showing and hiding the cursor element when a hand session starts and ends.
  2. Moving the cursor element when we should
  3. Adding a 'pushed' class the the cursor when appropiate
  4. Simulating a 'click' event
// Create cursor and cursor dom element
var c = zig.controls.Cursor();
var ce = document.createElement('div');
ce.id = 'mycursor';
document.body.appendChild(ce);

// 1. show/hide cursor on session start/end
zig.singleUserSession.addEventListener('sessionstart', function(focusPosition) {
	ce.style.display = 'block';
});
zig.singleUserSession.addEventListener('sessionend', function() {
	ce.style.display = 'none';
});

// 2. move the cursor element on cursor move
c.addEventListener('move', function(cursor) {
	ce.style.left = (c.x * window.innerWidth - (ce.offsetWidth / 2)) + "px";
	ce.style.top = (c.y * window.innerHeight - (ce.offsetHeight / 2)) + "px";
});

// 3. Add/remove 'pushed' class on cursor push/release
c.addEventListener('push', function(c) {
	ce.classList.add('pushed');
});
c.addEventListener('release', function(c) {
	ce.classList.remove('pushed');
});

// 4. Simulate mouse click on our virtual cursor
c.addEventListener('click', function(c) {
	var xpos = c.x * window.innerWidth;
	var ypos = c.y * window.innerHeight;
	var evt = document.createEvent("MouseEvents");
	evt.initMouseEvent("click", true, true, window, 1, xpos, ypos, xpos, ypos, false, false, false, false, 0, null);
	window.dispatchEvent(evt);
});

// Add cursor to our single user UI session
zig.singleUserSession.addListener(c);
And of course some basic styling for our cursor. Lets just use a blue square for now, red when pushed:
#mycursor {
	position: fixed;
	display : none;
	width : 40px;
	height : 40px;
	background-color : blue;
}

#mycursor.pushed {
	background-color: red;
}
Back to top

Top-down "users radar"

function usersRadar(parentElement) {
	// physical dimensions of radar in room. Lets use 4m x 4m
	this.radarWidth = 4000;
	this.radarHeight = 4000;
 
	this.onuserfound = function(user) {
		// create a new element for this user, add to dom
		var el = document.createElement('div');
		el.classList.add('user');
		parentElement.appendChild(el);
		// we can simply add the newly created element to the tracked user object
		// for later
		user.radarElement = el;
 
		// move the element every frame
		var that = this;
		user.addEventListener('userupdate', function(user) {
			// we need to convert [user.x, user.z] to [screen.x, screen.y]
			// first get normalized user position
			var xpos = (user.position[0] / that.radarWidth) + 0.5; // 0 for x is actually the center of the depthmap
			var ypos = (user.position[2] / that.radarHeight);
			// convert normalized position to fit into our radar element
			var el = user.radarElement;
			el.style.left = xpos * parentElement.offsetWidth - (el.offsetWidth / 2) + "px";
			el.style.top = ypos * parentElement.offsetHeight - (el.offsetHeight / 2) + "px";
		});
	}
	
	this.onuserlost = function(user) {
		// remove the element we created from the dom and ZDK user object
		parentElement.removeChild(user.radarElement);
		delete user.radarElement;
	}
}

// make sure you add <div id='radar'></div> to your html body
var radar = new usersRadar(document.getElementById('radar'));
zig.addListener(radar);
And the style sheet for the radar:
#radar {
	width: 	300px;
	height: 300px;
	border-radius: 15px;
	bottom: 20px;
	right: 20px;
	background:url('http://cdn.zigfu.com/zigjs/toys/radar.png'); 
	overflow:hidden;
	position: fixed;
}

#radar .user {
	width:	35px;
	height: 35px;
	background-image: url('http://cdn.zigfu.com/zigjs/toys/user.png');
	position:relative;
}
Back to top