X-Git-Url: http://git.plutz.net/?a=blobdiff_plain;f=stereoview.js;fp=stereoview.js;h=50863d5533f5219f0db0aff3362d36e2b8a4ffc6;hb=2515c4e19a1daf3c166c446ba97979f4bfebed26;hp=0000000000000000000000000000000000000000;hpb=1902cbbff7f9728f303cdb5e3fc37b18eddff4db;p=serve0 diff --git a/stereoview.js b/stereoview.js new file mode 100644 index 0000000..50863d5 --- /dev/null +++ b/stereoview.js @@ -0,0 +1,123 @@ +/* Copyright 2018 Paul Hänsch + + This file is part of Serve0 + + Serve0 is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Serve0 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Serve0 If not, see . +*/ + +var render, video, controlTimeout = 0; +var pitch = 0, roll = 0, yaw = 0; +var w, h, hdeg, vdeg, scale, fov = 90; +var lv = document.createElement("canvas"); +var rv = document.createElement("canvas"); +var debug = document.createElement("p"); +var gp; + +function draw() { + sw = fov * hdeg |0; + sh = h / 2 |0; + dh = h / 2 * scale |0; + + if ( layout == "180" ) { + sx = (w / 2 - fov * hdeg) / 2 + yaw * hdeg |0; + sy = ( h - fov * vdeg) / 2 + pitch * vdeg |0; + if (sx + sw > w / 2) { sx = w / 2 - sw; } else if (sx < 0) { sx = 0; } + lc.drawImage(video, sx, sy, sw, sh, 0, 0, lv.width, dh); + rc.drawImage(video, w / 2 + sx, sy, sw, sh, 0, 0, rv.width, dh); + } else { + sx = (w - fov * hdeg) / 2 + yaw * hdeg |0; + sy = (h - fov * vdeg) / 4 + pitch * vdeg |0; + lc.drawImage(video, sx, sy, sw, sh, 0, 0, lv.width, dh); + rc.drawImage(video, sx, h/2 + sy, sw, sh, 0, 0, rv.width, dh); + if (sx < 0) { + lc.drawImage(video, sx + w, sy, sw, sh, 0, 0, lv.width, dh); + rc.drawImage(video, sx + w, h/2 + sy, sw, sh, 0, 0, rv.width, dh); + } else if ( sx + fov * hdeg > w) { + lc.drawImage(video, sx - w, sy, sw, sh, 0, 0, lv.width, dh); + rc.drawImage(video, sx - w, h/2 + sy, sw, sh, 0, 0, rv.width, dh); + } + } + + lv.style.transform = "rotate(" + roll + "deg)"; + rv.style.transform = "rotate(" + roll + "deg)"; + + requestAnimationFrame(draw); + + gp = navigator.getGamepads()[0]; + if ( gp && Date.now() > controlTimeout ) { + if ( gp.axes[0] > .3) { video.currentTime += 10; controlTimeout = Date.now() + 500; } + if ( gp.axes[0] < -.3) { video.currentTime -= 10; controlTimeout = Date.now() + 500; } + if ( gp.axes[1] < -.3) { video.currentTime += 60; controlTimeout = Date.now() + 500; } + if ( gp.axes[1] > .3) { video.currentTime -= 60; controlTimeout = Date.now() + 500; } + if ( gp.buttons[0].pressed ) { video.currentTime += 1/30; video.pause(); } + if ( gp.buttons[1].pressed ) { video.play(); } + if ( gp.buttons[2].pressed ) { fov -= 10; controlTimeout = Date.now() + 500; } + if ( gp.buttons[3].pressed ) { fov += 10; controlTimeout = Date.now() + 500; } + } + + // debug.textContent = "" + video.currentTime + " " + controlTimeout; +}; + +function stereoview(layout, video) { + this.layout = layout; this.video = video; + document.body.appendChild( lv ); + document.body.appendChild( rv ); + document.body.appendChild( debug ); + + lv.setAttribute( "style", "position: fixed; top: 0; left: 0 ; width: 50%; height: 100%; z-index: 100;"); + rv.setAttribute( "style", "position: fixed; top: 0; left: 50%; width: 50%; height: 100%; z-index: 100;"); + debug.setAttribute( "style", "position: fixed; top: 0; left: 0; z-index: 101; background: #000;"); + + lv.setAttribute( "width", "" + lv.offsetWidth); + rv.setAttribute( "width", "" + rv.offsetWidth); + lv.setAttribute("height", "" + lv.offsetHeight); + rv.setAttribute("height", "" + rv.offsetHeight); + + lc = lv.getContext("2d"); + rc = rv.getContext("2d"); + + window.addEventListener("devicemotion", (function() { + var x = [], y = [], z = [], cnt = -1, inertia = 6; + return function(event) { + cnt = (cnt + 1) % inertia; + + x[cnt] = event.accelerationIncludingGravity.x; + y[cnt] = event.accelerationIncludingGravity.y; + z[cnt] = event.accelerationIncludingGravity.z; + + tx = 0; x.forEach( function(n, i){ tx += n; } ); tx /= inertia; + ty = 0; y.forEach( function(n, i){ ty += n; } ); ty /= inertia; + tz = 0; z.forEach( function(n, i){ tz += n; } ); tz /= inertia; + + pitch = Math.asin((tz / 9.81 > 1)?1:(tz/9.81)) / Math.PI * 180 + 22.5; + roll = - Math.asin((ty / 9.81 > 1)?1:(ty/9.81)) / Math.PI * 180; + yaw = (yaw + ty) % 360; + }; + })()); + + window.addEventListener("click", function(event) { + (lv.parentElement)?lv.parentElement.removeChild(lv):{}; + (rv.parentElement)?rv.parentElement.removeChild(rv):{}; + video.style.display = "block"; + video.pause(); + }, true); + + w = video.videoWidth; h = video.videoHeight; + hdeg = w / 360; vdeg = h / 180; + scale = lv.width / (fov * hdeg |0); + // scale = lv.width / (w / 4); + video.play(); + video.style.display = "none"; + draw(); +};