]> git.plutz.net Git - serve0/blob - static/stereoview.js
base drawing logic on rotation, define field of view
[serve0] / static / stereoview.js
1 /*  Copyright 2018 Paul Hänsch
2    
3     This file is part of Serve0
4     
5     Serve0 is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Affero General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9     
10     Serve0 is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Affero General Public License for more details.
14     
15     You should have received a copy of the GNU Affero General Public License
16     along with Serve0  If not, see <http://www.gnu.org/licenses/>. 
17 */
18
19 var render, video;
20 var pitch = 0, roll = 0, yaw = 0;
21 var w, h, hdeg, vdeg, scale, fov = 90;
22 var lv = document.createElement("canvas");
23 var rv = document.createElement("canvas");
24 var debug = document.createElement("p");
25
26 function draw() {
27   sw = fov * hdeg |0;
28   sh = h / 2 |0;
29   dh = h / 2 * scale |0;
30
31   if ( layout == "180" ) {
32     sx = (w / 2 - fov * hdeg) / 2 +   yaw * hdeg |0;
33     sy = (    h - fov * vdeg) / 2 + pitch * vdeg |0;
34     if   (sx + sw > w / 2) { sx = w / 2 - sw; } else if (sx < 0) { sx = 0; }
35     lc.drawImage(video,         sx, sy, sw, sh, 0, 0, lv.width, dh);
36     rc.drawImage(video, w / 2 + sx, sy, sw, sh, 0, 0, rv.width, dh);
37   } else {
38     sx = (w - fov * hdeg) / 2 + yaw   * hdeg |0;
39     sy = (h - fov * vdeg) / 4 + pitch * vdeg |0;
40     lc.drawImage(video, sx,       sy, sw, sh, 0, 0, lv.width, dh);
41     rc.drawImage(video, sx, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
42     if (sx < 0) {
43       lc.drawImage(video, sx + w,       sy, sw, sh, 0, 0, lv.width, dh);
44       rc.drawImage(video, sx + w, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
45     } else if ( sx + fov * hdeg > w) {
46       lc.drawImage(video, sx - w,       sy, sw, sh, 0, 0, lv.width, dh);
47       rc.drawImage(video, sx - w, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
48     }
49   }
50
51   lv.style.transform = "rotate(" + roll + "deg)";
52   rv.style.transform = "rotate(" + roll + "deg)";
53
54   requestAnimationFrame(draw);
55 };
56
57 function stereoview(layout, video) {
58   this.layout = layout; this.video = video;
59   document.body.appendChild( lv );
60   document.body.appendChild( rv );
61   // document.body.appendChild( debug );
62   
63   lv.setAttribute( "style", "position: fixed; top: 0; left:  0 ; width: 50%; height: 100%; z-index: 100;");
64   rv.setAttribute( "style", "position: fixed; top: 0; left: 50%; width: 50%; height: 100%; z-index: 100;");
65   debug.setAttribute( "style", "position: fixed; top: 0; left: 0; z-index: 101; background: #000;");
66
67   lv.setAttribute( "width", "" + lv.offsetWidth);
68   rv.setAttribute( "width", "" + rv.offsetWidth);
69   lv.setAttribute("height", "" + lv.offsetHeight);
70   rv.setAttribute("height", "" + rv.offsetHeight);
71   
72   lc = lv.getContext("2d");
73   rc = rv.getContext("2d");
74   
75   window.addEventListener("devicemotion", (function() {
76     var x = [], y = [], z = [], cnt = -1, inertia = 6;
77     return function(event) {
78       cnt = (cnt + 1) % inertia;
79
80       x[cnt] = event.accelerationIncludingGravity.x;
81       y[cnt] = event.accelerationIncludingGravity.y;
82       z[cnt] = event.accelerationIncludingGravity.z;
83
84       tx = 0; x.forEach( function(n, i){ tx += n; } ); tx /= inertia;
85       ty = 0; y.forEach( function(n, i){ ty += n; } ); ty /= inertia;
86       tz = 0; z.forEach( function(n, i){ tz += n; } ); tz /= inertia;
87
88       pitch =   Math.asin((tz / 9.81 > 1)?1:(tz/9.81)) / Math.PI * 180;
89       roll  = - Math.asin((ty / 9.81 > 1)?1:(ty/9.81)) / Math.PI * 180;
90       yaw   = (yaw + ty) % 360;
91     };
92   })(), true);
93
94   window.addEventListener("click", function(event) {
95     (lv.parentElement)?lv.parentElement.removeChild(lv):{};
96     (rv.parentElement)?rv.parentElement.removeChild(rv):{};
97     video.style.display = "block";
98     video.pause();
99   }, true);
100
101   w = video.videoWidth; h = video.videoHeight;
102   hdeg = w / 360; vdeg = h / 180;
103   scale = lv.width / (fov * hdeg |0);
104   // scale = lv.width / (w / 4);
105   video.play();
106   video.style.display = "none";
107   draw();
108 };