source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/StreetSamplePage.html@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 18.3 KB
Line 
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>
Note: See TracBrowser for help on using the repository browser.