1 |
|
---|
2 | <!--<!DOCTYPE HTML>-->
|
---|
3 | <html>
|
---|
4 | <head>
|
---|
5 | <title>Kinect Web Basics</title>
|
---|
6 | <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.min.js"></script>
|
---|
7 | <script type="text/javascript" src="Kinect-1.8.0.js"></script>
|
---|
8 | <script type="text/javascript">
|
---|
9 | $(document).ready(function () {
|
---|
10 | var streamImageWidth = 640;
|
---|
11 | var streamImageHeight = 480;
|
---|
12 | var streamImageResolution = streamImageWidth.toString() + "x" + streamImageHeight.toString();
|
---|
13 |
|
---|
14 | var isSensorConnected = false;
|
---|
15 | var engagedUser = null;
|
---|
16 | var cursor = null;
|
---|
17 | var userViewerCanvasElement = null;
|
---|
18 | var backgroundRemovalCanvasElement = null;
|
---|
19 |
|
---|
20 | // Log errors encountered during sensor configuration
|
---|
21 | function configError(statusText, errorData) {
|
---|
22 | console.log((errorData != null) ? JSON.stringify(errorData) : statusText);
|
---|
23 | }
|
---|
24 |
|
---|
25 | // Determine if the specified object has any properties or not
|
---|
26 | function isEmptyObject(obj) {
|
---|
27 | if (obj == null) {
|
---|
28 | return true;
|
---|
29 | }
|
---|
30 |
|
---|
31 | var numProperties = 0;
|
---|
32 |
|
---|
33 | for (var prop in obj) {
|
---|
34 | if (obj.hasOwnProperty(prop)) {
|
---|
35 | ++numProperties;
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | return numProperties <= 0;
|
---|
40 | }
|
---|
41 |
|
---|
42 | // Show or hide the cursor
|
---|
43 | function setCursorVisibility(isVisible) {
|
---|
44 | if (cursor == null) {
|
---|
45 | return;
|
---|
46 | }
|
---|
47 |
|
---|
48 | if (isVisible) {
|
---|
49 | cursor.show();
|
---|
50 | } else {
|
---|
51 | cursor.hide();
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | // Show or hide a canvas element
|
---|
56 | function setCanvasVisibility(canvasElement, isVisible) {
|
---|
57 | if (canvasElement == null) {
|
---|
58 | return;
|
---|
59 | }
|
---|
60 |
|
---|
61 | var canvasQuery = $(canvasElement);
|
---|
62 |
|
---|
63 | if (isVisible) {
|
---|
64 | if (!canvasQuery.hasClass("showing")) {
|
---|
65 | // Clear canvas before showing it
|
---|
66 | var canvasContext = canvasElement.getContext("2d");
|
---|
67 | canvasContext.clearRect(0, 0, streamImageWidth, streamImageHeight);
|
---|
68 | }
|
---|
69 |
|
---|
70 | canvasQuery.addClass("showing");
|
---|
71 | } else {
|
---|
72 | canvasQuery.removeClass("showing");
|
---|
73 | }
|
---|
74 | }
|
---|
75 |
|
---|
76 | var showPanelLabel = "Choose<br/>Background";
|
---|
77 | var hidePanelLabel = "Hide<br/>Panel";
|
---|
78 | function setChoosePanelVisibility(isVisible) {
|
---|
79 | var togglePanelElement = document.getElementById("togglePanelButton");
|
---|
80 | var spanQuery = $("span", togglePanelElement);
|
---|
81 |
|
---|
82 | if (isVisible) {
|
---|
83 | // If choose background panel is being shown, hide toggle button
|
---|
84 | // border so top of button is aligned with other buttons
|
---|
85 | $("#choosePanel").addClass("showing");
|
---|
86 | spanQuery.html(hidePanelLabel);
|
---|
87 | } else {
|
---|
88 | // If choose background panel is being hidden, show toggle button
|
---|
89 | // border to provide contrast against picture
|
---|
90 | $("#choosePanel").removeClass("showing");
|
---|
91 | spanQuery.html(showPanelLabel);
|
---|
92 | }
|
---|
93 | }
|
---|
94 |
|
---|
95 | function isChoosePanelVisible() {
|
---|
96 | return $("#choosePanel").hasClass("showing");
|
---|
97 | }
|
---|
98 |
|
---|
99 | // property and function used to keep track of when the choose background control panel
|
---|
100 | // should be hidden after an inactivity period
|
---|
101 | var hidePanelTimeoutId = null;
|
---|
102 | function resetHidePanelTimeout() {
|
---|
103 | // First clear any previous timeout
|
---|
104 | if (hidePanelTimeoutId != null) {
|
---|
105 | clearTimeout(hidePanelTimeoutId);
|
---|
106 | hidePanelTimeoutId = null;
|
---|
107 | }
|
---|
108 |
|
---|
109 | if (!isSensorConnected || (engagedUser == null)) {
|
---|
110 | // if there is no engaged user or no sensor connected, we hide the choose background
|
---|
111 | // control panel after 10 seconds
|
---|
112 | hidePanelTimeoutId = setTimeout(function () {
|
---|
113 | setChoosePanelVisibility(false);
|
---|
114 | hidePanelTimeoutId = null;
|
---|
115 | }, 10000);
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 | // Update sensor state and perform UI transitions (showing/hiding appropriate UI elements)
|
---|
120 | // related to sensor status or engagement state changes
|
---|
121 | var delayedConfigTimeoutId = null;
|
---|
122 | function updateUserState(newIsSensorConnected, newEngagedUser, sensorToConfig) {
|
---|
123 | var hasEngagedUser = engagedUser != null;
|
---|
124 | var newHasEngagedUser = newEngagedUser != null;
|
---|
125 |
|
---|
126 | // If there's a pending configuration change when state changes again, cancel previous timeout
|
---|
127 | if (delayedConfigTimeoutId != null) {
|
---|
128 | clearTimeout(delayedConfigTimeoutId);
|
---|
129 | delayedConfigTimeoutId = null;
|
---|
130 | }
|
---|
131 |
|
---|
132 | if ((isSensorConnected != newIsSensorConnected) || (engagedUser != newEngagedUser)) {
|
---|
133 | if (newIsSensorConnected) {
|
---|
134 |
|
---|
135 | var immediateConfig = {};
|
---|
136 | var delayedConfig = {};
|
---|
137 | immediateConfig[Kinect.INTERACTION_STREAM_NAME] = { "enabled": true };
|
---|
138 | immediateConfig[Kinect.USERVIEWER_STREAM_NAME] = { "resolution": streamImageResolution };
|
---|
139 | immediateConfig[Kinect.BACKGROUNDREMOVAL_STREAM_NAME] = { "resolution": streamImageResolution };
|
---|
140 |
|
---|
141 | setCursorVisibility(newHasEngagedUser);
|
---|
142 | setCanvasVisibility(userViewerCanvasElement, !newHasEngagedUser);
|
---|
143 | setCanvasVisibility(backgroundRemovalCanvasElement, newHasEngagedUser);
|
---|
144 |
|
---|
145 | if (newHasEngagedUser) {
|
---|
146 | immediateConfig[Kinect.BACKGROUNDREMOVAL_STREAM_NAME].enabled = true;
|
---|
147 | immediateConfig[Kinect.BACKGROUNDREMOVAL_STREAM_NAME].trackingId = newEngagedUser;
|
---|
148 |
|
---|
149 | delayedConfig[Kinect.USERVIEWER_STREAM_NAME] = { "enabled": false };
|
---|
150 | } else {
|
---|
151 | immediateConfig[Kinect.USERVIEWER_STREAM_NAME].enabled = true;
|
---|
152 |
|
---|
153 | if (hasEngagedUser) {
|
---|
154 | delayedConfig[Kinect.BACKGROUNDREMOVAL_STREAM_NAME] = { "enabled": false };
|
---|
155 | }
|
---|
156 | }
|
---|
157 |
|
---|
158 | // Perform immediate configuration
|
---|
159 | sensorToConfig.postConfig(immediateConfig, configError);
|
---|
160 |
|
---|
161 | // schedule delayed configuration for 2 seconds later
|
---|
162 | if (!isEmptyObject(delayedConfig)) {
|
---|
163 | delayedConfigTimeoutId = setTimeout(function () {
|
---|
164 | sensorToConfig.postConfig(delayedConfig, configError);
|
---|
165 | delayedConfigTimeoutId = null;
|
---|
166 | }, 2000);
|
---|
167 | }
|
---|
168 | } else {
|
---|
169 | setCursorVisibility(false);
|
---|
170 | setCanvasVisibility(userViewerCanvasElement, false);
|
---|
171 | setCanvasVisibility(backgroundRemovalCanvasElement, false);
|
---|
172 | }
|
---|
173 | }
|
---|
174 |
|
---|
175 | isSensorConnected = newIsSensorConnected;
|
---|
176 | engagedUser = newEngagedUser;
|
---|
177 |
|
---|
178 | resetHidePanelTimeout();
|
---|
179 | }
|
---|
180 |
|
---|
181 | // Get the id of the engaged user, if present, or null if there is no engaged user
|
---|
182 | function findEngagedUser(userStates) {
|
---|
183 | var engagedUserId = null;
|
---|
184 |
|
---|
185 | for (var i = 0; i < userStates.length; ++i) {
|
---|
186 | var entry = userStates[i];
|
---|
187 | if (entry.userState == "engaged") {
|
---|
188 | engagedUserId = entry.id;
|
---|
189 | break;
|
---|
190 | }
|
---|
191 | }
|
---|
192 |
|
---|
193 | return engagedUserId;
|
---|
194 | }
|
---|
195 |
|
---|
196 | // Respond to user state change event
|
---|
197 | function onUserStatesChanged(newUserStates) {
|
---|
198 | var newEngagedUser = findEngagedUser(newUserStates);
|
---|
199 |
|
---|
200 | updateUserState(isSensorConnected, newEngagedUser, sensor);
|
---|
201 | }
|
---|
202 |
|
---|
203 | // Create sensor and UI adapter layers
|
---|
204 | var sensor = Kinect.sensor(Kinect.DEFAULT_SENSOR_NAME, function (sensorToConfig, isConnected) {
|
---|
205 | if (isConnected) {
|
---|
206 | // Determine what is the engagement state upon connection
|
---|
207 | sensorToConfig.getConfig(function (data) {
|
---|
208 | var engagedUserId = findEngagedUser(data[Kinect.INTERACTION_STREAM_NAME].userStates);
|
---|
209 |
|
---|
210 | updateUserState(true, engagedUserId, sensorToConfig);
|
---|
211 | });
|
---|
212 | } else {
|
---|
213 | updateUserState(false, engagedUser, sensorToConfig);
|
---|
214 | }
|
---|
215 | });
|
---|
216 | var uiAdapter = KinectUI.createAdapter(sensor);
|
---|
217 |
|
---|
218 | uiAdapter.promoteButtons();
|
---|
219 | cursor = uiAdapter.createDefaultCursor();
|
---|
220 | userViewerCanvasElement = document.getElementById("userViewerCanvas");
|
---|
221 | backgroundRemovalCanvasElement = document.getElementById("backgroundRemovalCanvas");
|
---|
222 | uiAdapter.bindStreamToCanvas(Kinect.USERVIEWER_STREAM_NAME, userViewerCanvasElement);
|
---|
223 | uiAdapter.bindStreamToCanvas(Kinect.BACKGROUNDREMOVAL_STREAM_NAME, backgroundRemovalCanvasElement);
|
---|
224 |
|
---|
225 | sensor.addEventHandler(function (event) {
|
---|
226 | switch (event.category) {
|
---|
227 | case Kinect.USERSTATE_EVENT_CATEGORY:
|
---|
228 | switch (event.eventType) {
|
---|
229 | case Kinect.USERSTATESCHANGED_EVENT_TYPE:
|
---|
230 | onUserStatesChanged(event.userStates);
|
---|
231 | break;
|
---|
232 | }
|
---|
233 | break;
|
---|
234 | }
|
---|
235 | });
|
---|
236 |
|
---|
237 | setChoosePanelVisibility(false);
|
---|
238 | $("#togglePanelButton").click(function (event) {
|
---|
239 | if (isChoosePanelVisible()) {
|
---|
240 | setChoosePanelVisibility(false);
|
---|
241 | } else {
|
---|
242 | setChoosePanelVisibility(true);
|
---|
243 | resetHidePanelTimeout();
|
---|
244 | }
|
---|
245 | });
|
---|
246 | $(".imgButtonContainer .kinect-button").click(function (event) {
|
---|
247 | var imgElement = $("img", event.currentTarget)[0];
|
---|
248 | document.getElementById("backgroundImg").src = imgElement.src;
|
---|
249 | resetHidePanelTimeout();
|
---|
250 | });
|
---|
251 | });
|
---|
252 | </script>
|
---|
253 | <link rel="stylesheet" type="text/css" href="Kinect-1.8.0.css" />
|
---|
254 | <style type="text/css">
|
---|
255 | html {
|
---|
256 | width: 100%;
|
---|
257 | height: 100%;
|
---|
258 | overflow: hidden;
|
---|
259 | }
|
---|
260 |
|
---|
261 | body {
|
---|
262 | width: 100%;
|
---|
263 | height: 100%;
|
---|
264 | margin: 0;
|
---|
265 | overflow: hidden;
|
---|
266 | font-family: 'Segoe UI';
|
---|
267 | }
|
---|
268 |
|
---|
269 | #uiContainer {
|
---|
270 | position: relative;
|
---|
271 | margin: 0 auto;
|
---|
272 | width: 100vw;
|
---|
273 | height: 100%;
|
---|
274 | }
|
---|
275 |
|
---|
276 | #logoImg {
|
---|
277 | position: absolute;
|
---|
278 | top: 18px;
|
---|
279 | left: 26px;
|
---|
280 | width: 100px;
|
---|
281 | height: 40px;
|
---|
282 | }
|
---|
283 |
|
---|
284 | #sampleName {
|
---|
285 | position: relative;
|
---|
286 | display: block;
|
---|
287 | text-align: right;
|
---|
288 | font-size: 16pt;
|
---|
289 | color: gray;
|
---|
290 | top: 24px;
|
---|
291 | margin-right: 26px;
|
---|
292 | }
|
---|
293 |
|
---|
294 | #backgroundContainer {
|
---|
295 | position: absolute;
|
---|
296 | top: 80px;
|
---|
297 | width: 100vw;
|
---|
298 | height: 56.25vw;
|
---|
299 | margin-bottom: 26px;
|
---|
300 | }
|
---|
301 |
|
---|
302 | @media screen and (max-width: 960px) {
|
---|
303 | #uiContainer {
|
---|
304 | width: 960px;
|
---|
305 | }
|
---|
306 |
|
---|
307 | #backgroundContainer {
|
---|
308 | width: 960px;
|
---|
309 | height: 540px;
|
---|
310 | }
|
---|
311 | }
|
---|
312 |
|
---|
313 | @media screen and (min-width: 1600px) {
|
---|
314 | #uiContainer {
|
---|
315 | width: 1600px;
|
---|
316 | }
|
---|
317 |
|
---|
318 | #backgroundContainer {
|
---|
319 | width: 1600px;
|
---|
320 | height: 900px;
|
---|
321 | }
|
---|
322 | }
|
---|
323 |
|
---|
324 | #backgroundImg {
|
---|
325 | width: 100%;
|
---|
326 | height: 100%;
|
---|
327 | }
|
---|
328 |
|
---|
329 | .streamImageCanvas {
|
---|
330 | position: absolute;
|
---|
331 | width: 75%;
|
---|
332 | height: 100%;
|
---|
333 | top: 0;
|
---|
334 | left: 12.5%;
|
---|
335 | opacity: 0.0;
|
---|
336 | transition: opacity 1.0s;
|
---|
337 | }
|
---|
338 |
|
---|
339 | .streamImageCanvas.showing {
|
---|
340 | opacity: 1.0;
|
---|
341 | transition: opacity 1.0s;
|
---|
342 | }
|
---|
343 |
|
---|
344 | #buttonContainer {
|
---|
345 | position: absolute;
|
---|
346 | display: block;
|
---|
347 | width: 100%;
|
---|
348 | height: 160px;
|
---|
349 | bottom: 0;
|
---|
350 | }
|
---|
351 |
|
---|
352 | #choosePanel {
|
---|
353 | position: absolute;
|
---|
354 | background-color: white;
|
---|
355 | width: 100%;
|
---|
356 | height: 100%;
|
---|
357 | top: 100%;
|
---|
358 | transition: top 0.4s;
|
---|
359 | }
|
---|
360 |
|
---|
361 | #choosePanel.showing {
|
---|
362 | top: 0;
|
---|
363 | transition: top 0.4s;
|
---|
364 | }
|
---|
365 |
|
---|
366 | .commandButtonContainer {
|
---|
367 | position: absolute;
|
---|
368 | width: 18%;
|
---|
369 | height: 100%;
|
---|
370 | top: 0;
|
---|
371 | left: 3%;
|
---|
372 | }
|
---|
373 |
|
---|
374 | .imgButtonContainer {
|
---|
375 | position: absolute;
|
---|
376 | width: 18%;
|
---|
377 | height: 100%;
|
---|
378 | top: 0;
|
---|
379 | }
|
---|
380 |
|
---|
381 | #togglePanelButton {
|
---|
382 | /* Add an explicit background color to make sure mouse/touch events get routed
|
---|
383 | to button even when hovering/pressing over transparent area around button edge. */
|
---|
384 | background-color: rgba(0,0,0,0.0);
|
---|
385 | }
|
---|
386 |
|
---|
387 | #imgButtonContainer1 {
|
---|
388 | left: 25%;
|
---|
389 | }
|
---|
390 |
|
---|
391 | #imgButtonContainer2 {
|
---|
392 | left: 43%;
|
---|
393 | }
|
---|
394 |
|
---|
395 | #imgButtonContainer3 {
|
---|
396 | left: 61%;
|
---|
397 | }
|
---|
398 |
|
---|
399 | #imgButtonContainer4 {
|
---|
400 | left: 79%;
|
---|
401 | }
|
---|
402 |
|
---|
403 | .kinect-button.tile {
|
---|
404 | position: relative;
|
---|
405 | display: block;
|
---|
406 | width: 170px;
|
---|
407 | height: 100px;
|
---|
408 | margin: 30px auto;
|
---|
409 | padding: 0;
|
---|
410 | }
|
---|
411 |
|
---|
412 | .kinect-button.tile .commandButtonContent {
|
---|
413 | position: absolute;
|
---|
414 | width: 100%;
|
---|
415 | height: 100%;
|
---|
416 | border-style: solid;
|
---|
417 | border-color: white;
|
---|
418 | border-width: 2px;
|
---|
419 | transition: border-width 0.15s;
|
---|
420 | left: -2px;
|
---|
421 | top: -2px;
|
---|
422 | }
|
---|
423 |
|
---|
424 | .kinect-button.image {
|
---|
425 | position: relative;
|
---|
426 | display: block;
|
---|
427 | width: 170px;
|
---|
428 | height: 100px;
|
---|
429 | margin: 30px auto;
|
---|
430 | padding: 0;
|
---|
431 | }
|
---|
432 |
|
---|
433 | .kinect-button img {
|
---|
434 | width: 100%;
|
---|
435 | height: 100%;
|
---|
436 | }
|
---|
437 |
|
---|
438 | .kinect-button-text {
|
---|
439 | font-size: 14pt;
|
---|
440 | width: 100%;
|
---|
441 | height: 3em;
|
---|
442 | margin-top: -1.5em;
|
---|
443 | }
|
---|
444 |
|
---|
445 | @media screen and (min-width: 1280px) and (max-width: 1600px) {
|
---|
446 | #buttonContainer {
|
---|
447 | height: 186px;
|
---|
448 | }
|
---|
449 |
|
---|
450 | .kinect-button.tile {
|
---|
451 | width: 224px;
|
---|
452 | height: 126px;
|
---|
453 | }
|
---|
454 |
|
---|
455 | .kinect-button.image {
|
---|
456 | width: 224px;
|
---|
457 | height: 126px;
|
---|
458 | }
|
---|
459 |
|
---|
460 | .kinect-button-text {
|
---|
461 | font-size: 16pt;
|
---|
462 | }
|
---|
463 | }
|
---|
464 |
|
---|
465 | @media screen and (min-width: 1600px) {
|
---|
466 | #buttonContainer {
|
---|
467 | height: 222px;
|
---|
468 | }
|
---|
469 |
|
---|
470 | .kinect-button.tile {
|
---|
471 | width: 288px;
|
---|
472 | height: 162px;
|
---|
473 | }
|
---|
474 |
|
---|
475 | .kinect-button.image {
|
---|
476 | width: 288px;
|
---|
477 | height: 162px;
|
---|
478 | }
|
---|
479 |
|
---|
480 | .kinect-button-text {
|
---|
481 | font-size: 18pt;
|
---|
482 | }
|
---|
483 | }
|
---|
484 | </style>
|
---|
485 | </head>
|
---|
486 | <body>
|
---|
487 | <div class="kinect-button" style="width:400px; height:300px;">button</div>
|
---|
488 | <div id="uiContainer">
|
---|
489 | <img id="logoImg" src="Images\logo.png"/>
|
---|
490 | <span id="sampleName">Kinect Web Basics</span>
|
---|
491 |
|
---|
492 | <div id="backgroundContainer">
|
---|
493 | <!--<img id="backgroundImg" src="Images\fireworks.jpg"/>-->
|
---|
494 | <div id="backgroundImg" style="width:800px;height:600px;">foo klnsdsdfgsfgdfdb
|
---|
495 | </div>
|
---|
496 | <canvas id="userViewerCanvas" class="streamImageCanvas"></canvas>
|
---|
497 | <canvas id="backgroundRemovalCanvas" class="streamImageCanvas"></canvas>
|
---|
498 | </div>
|
---|
499 | <div id="buttonContainer">
|
---|
500 | <div id="choosePanel">
|
---|
501 | <div id="imgButtonContainer1" class="imgButtonContainer">
|
---|
502 | <div class="kinect-button image">
|
---|
503 | <img src="Images/beach.jpg"/>
|
---|
504 | </div>
|
---|
505 | </div>
|
---|
506 | <div id="imgButtonContainer2" class="imgButtonContainer">
|
---|
507 | <div class="kinect-button image">
|
---|
508 | <img src="Images/fireworks.jpg"/>
|
---|
509 | </div>
|
---|
510 | </div>
|
---|
511 | <div id="imgButtonContainer3" class="imgButtonContainer">
|
---|
512 | <div class="kinect-button image">
|
---|
513 | <img src="Images/hamlet.jpg"/>
|
---|
514 | </div>
|
---|
515 | </div>
|
---|
516 | <div id="imgButtonContainer4" class="imgButtonContainer">
|
---|
517 | <div class="kinect-button image">
|
---|
518 | <img src="Images/operahouse.jpg"/>
|
---|
519 | </div>
|
---|
520 | </div>
|
---|
521 | </div>
|
---|
522 | <div class="commandButtonContainer">
|
---|
523 | <div id="togglePanelButton" class="kinect-button tile">
|
---|
524 | <div class="commandButtonContent">
|
---|
525 | <span class="kinect-button-text"></span>
|
---|
526 | </div>
|
---|
527 | </div>
|
---|
528 | </div>
|
---|
529 | </div>
|
---|
530 | </div>
|
---|
531 | </body>
|
---|
532 | </html> |
---|