initial upload
[apps/native/smart-surveillance-camera.git] / dashboard / public / js / app.js
1  /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 const IMG_WIDTH = 640;
18 const IMG_HEIGHT = 480;
19 const CANVAS_WIDTH = 640;
20 const CANVAS_HEIGHT = 480;
21
22 window.onload = function(){
23     var canvas;
24     var frame_timestamp = new Array(100);
25     var request_time;
26     var frame_number = 0;
27
28     var xhr = new XMLHttpRequest();
29     xhr.onreadystatechange = function() {
30         var previewElement = document.getElementById('camera-view');
31
32         if (xhr.readyState === 4) {
33             update_fps();
34             // console.log(JSON.stringify(frame_timestamp));
35
36             var latencyTag = document.getElementById('latency');
37             if (latencyTag != null)
38                 latencyTag.innerHTML = 'latency: ' + (Date.now() - request_time) + ' ms';
39
40             previewElement.src = xhr.response;
41         }
42     };
43
44     canvas = new Canvas("camera-view-canvas");
45
46     runWebSocket();
47
48     function update_fps() {
49         frame_timestamp[frame_number] = Date.now();
50         var fpsTag = document.getElementById('fps');
51         if (fpsTag != null)
52             fpsTag.innerHTML = JSON.stringify(fps());
53         if (++frame_number == frame_timestamp.length) frame_number = 0;
54     }
55
56     function fps() {
57         var i = frame_number;
58         var now = Date.now();
59         do { // backtrace to find the frame 1000 milliseconds before
60             if (now - frame_timestamp[i] >= 1000) {
61                 var fps = frame_number - i;
62                 if (fps < 0)
63                     fps += frame_timestamp.length;
64                 return fps;
65             }
66             if (--i < 0) // wrap around to the last slot in the array
67                 i = frame_timestamp.length - 1;
68         } while (i != frame_number)
69     }
70
71     function runWebSocket() {
72         // var wsUri = "ws://192.168.1.211:8888/";
73         var wsUri = "ws://" + window.location.hostname + ":8888/";
74
75         websocket = new WebSocket(wsUri);
76         websocket.onopen = function(evt) { onOpen(evt) };
77         websocket.onclose = function(evt) { onClose(evt) };
78         websocket.onmessage = function(evt) { onMessage(evt) };
79         websocket.onerror = function(evt) { onError(evt) };
80
81         // // polling
82         // setInterval(function() {
83         //   // console.log('hey!');
84         //   xhr.open('POST', '/requestImage' , true);
85         //   xhr.send();
86         //   request_time = Date.now();
87         //   // console.log('update image');
88         // }, 100);
89     }
90
91     function onOpen(evt)
92     {
93         writeToScreen("CONNECTED");
94         doSend("HELLO FROM BROWSER via WebSocket!!!!!!!!!!!!");
95     }
96
97     function onClose(evt)
98     {
99         writeToScreen("DISCONNECTED");
100     }
101
102     function onMessage(evt)
103     {
104         // writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
105
106         var urlCreator = window.URL || window.webkitURL;
107         var imageUrl = urlCreator.createObjectURL(evt.data);
108         document.querySelector("#camera-view").src = imageUrl;
109         update_fps();
110
111         var arrayBuffer;
112         var fileReader = new FileReader();
113         fileReader.onload = function(event) {
114             arrayBuffer = event.target.result;
115             var exif = EXIF.readFromBinaryFile(arrayBuffer);
116             var exifInfoString = asciiToStr(exif.UserComment, 8);
117             var type = 'blur';
118             if (getResultType(exifInfoString) != 0) {
119                 type = 'active';
120             }
121
122             var pointArray = getPointArrayFromString(exifInfoString.slice(4));
123
124             if (pointArray.length <= 0) {
125                 document.querySelector("#mobile-detection").innerHTML = "No<br>Motion";
126             } else {
127                 document.querySelector("#mobile-detection").innerHTML = "Motion<br>Detected";
128             }
129
130             canvas.clearPoints();
131             canvas.drawPoints(pointArray, type);
132         };
133         fileReader.readAsArrayBuffer(evt.data);
134
135         doSend("ack", true);
136
137         // websocket.close();
138
139         // var reader = new FileReader();
140         // reader.readAsDataURL(evt.data);
141         // reader.onloadend = function() {
142         //     base64data = reader.result;
143         //     var previewElement = document.getElementById('camera-view');
144         //     previewElement.src = base64data;
145         //     update_fps();
146         // }
147     }
148
149     function onError(evt)
150     {
151         writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
152     }
153
154     function doSend(message, dont_print_log)
155     {
156         websocket.send(message);
157         if (!dont_print_log)
158             writeToScreen("SENT: " + message);
159     }
160
161     function writeToScreen(message)
162     {
163         var output = document.getElementById("output");
164         if (output == null)
165             return;
166         var pre = document.createElement("p");
167         pre.style.wordWrap = "break-word";
168         pre.innerHTML = message;
169         output.appendChild(pre);
170     }
171
172     function asciiToStr(asciiArr, start) {
173         var string = "";
174         var i = start;
175
176         for (; i < asciiArr.length; i++) {
177             string += String.fromCharCode(asciiArr[i]);
178         }
179
180         return string;
181     }
182
183     function getResultType(str) {
184         return Number(str.slice(0, 2));
185     }
186
187     function getPointArrayFromString(pointStr) {
188         var strLen = pointStr.length;
189         var i = 0;
190         var pointArray = [];
191
192         while (i < strLen) {
193             pointArray.push(pointStr.slice(i, i + 8));
194             i += 8;
195         }
196
197         return pointArray;
198     }
199
200     var step = 0
201     const total_steps = 8
202     setInterval(function() {
203         for (var i = 0; i < total_steps; i++) {
204             var className = '.step' + (i + 1);
205             $('li' + className).removeClass('blink');
206             $('.d-text-tizen' + className).removeClass('blink');
207             $('.d-text-st' + className).removeClass('blink');
208             $('.arrow' + className).removeClass('blink');
209             $('.try-it-bullet').removeClass('shake-it');
210         }
211         var className = '.step' + (step + 1);
212         $('li' + className).addClass('blink');
213         $('.d-text-tizen' + className).addClass('blink');
214         $('.d-text-st' + className).addClass('blink');
215         $('.arrow' + className).addClass('blink');
216         if (step == 7)
217             $('.try-it-bullet').addClass('shake-it');
218         step = ++step % total_steps;
219     }, 4000);
220 };
221
222 function Canvas(canvasId) {
223     this.viewCanvas = document.getElementById(canvasId);
224     this.viewContext = this.viewCanvas.getContext("2d");
225 }
226
227 Canvas.prototype.clearCanvas = function() {
228     this.viewContext.clearRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
229 }
230
231 Canvas.prototype.clearPoints = function () {
232     this.clearCanvas();
233 }
234
235 Canvas.prototype.drawRect = function(x, y, width, height, color) {
236     this.viewContext.beginPath();
237     this.viewContext.moveTo(x, y);
238     this.viewContext.lineTo(x, y + height);
239     this.viewContext.lineTo(x + width, y + height);
240     this.viewContext.lineTo(x + width, y);
241     this.viewContext.closePath();
242     this.viewContext.lineWidth = 3;
243     this.viewContext.strokeStyle = color;
244     this.viewContext.stroke();
245 }
246
247 Canvas.prototype.drawPoints = function (pointArray, type) {
248     var i = 0;
249     var x, y, w, h;
250     var color;
251
252     if (type == 'blur') {
253         color = "rgba(115,232,57,0.8)";
254     } else {
255         color = "rgba(255,0,0, 0.8)";
256     }
257
258     for (i = 0; i < pointArray.length; i++) {
259         x = IMG_WIDTH / 99 * parseInt(pointArray[i].slice(0,2));
260         y = IMG_HEIGHT / 99 * parseInt(pointArray[i].slice(2,4));
261         w = IMG_WIDTH / 99 * parseInt(pointArray[i].slice(4,6));
262         h = IMG_HEIGHT / 99 * parseInt(pointArray[i].slice(6,8));
263
264         this.drawRect(x, y, w, h, color);
265     }
266 }