summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/assets/javascripts/app.js2
-rw-r--r--public/assets/javascripts/mx/extensions/mx.movementsMobile.js203
-rw-r--r--public/assets/javascripts/ui/reader/ReaderView.js2
3 files changed, 160 insertions, 47 deletions
diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js
index cfbe4bf..9b46a3e 100644
--- a/public/assets/javascripts/app.js
+++ b/public/assets/javascripts/app.js
@@ -68,8 +68,6 @@ app.launch = function () {
scene.update()
}
- window.inAnimation = true
-
var loader = new Loader(function(){
$("#loader").hide()
window.environment && window.environment.init()
diff --git a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
index 994c8d7..8810649 100644
--- a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
+++ b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
@@ -14,56 +14,169 @@ MX.MobileMovements = function (cam) {
var pos = { x: 0, y: viewHeight, z: 0, rotationX: 0, rotationY: 0 }
var pointX, pointY, deltaX, deltaY, distX = 0, distY = 0, absDistX = 0, absDistY = 0, startTime
-
- return {
+
+ var rotationX = 0, rotationY = 0, destRotationX = 0, destRotationY = 0
+ var rotationSum = 0
+ var rotationMedian = 0
+ var orientationMax = 0
+ var samples = 0
+ var sampleThreshold = 120
+ var lastAlpha
+
+ var is_portrait
+
+ var exports = {
init: function () {
- document.addEventListener("touchstart", function(e){
- if (e.touches.length == 1) {
- touching = true
-
- startTime = Date.now()
-
- var point = event.touches[0]
- pointX = point.pageX
- pointY = point.pageY
- distX = distY = 0
- pos.x = cam.x
- pos.z = cam.z
- pos.rotationY = cam.rotationY
- }
- })
- document.addEventListener("touchmove", function(e){
- e.preventDefault()
- if (e.touches.length == 1) {
+ exports.orientationchange()
+
+ document.addEventListener("touchstart", exports.touchstart)
+ document.addEventListener("touchmove", exports.touchmove)
+ document.addEventListener("touchend", exports.touchend)
+ window.addEventListener('orientationchange', exports.orientationchange)
+ window.addEventListener("devicemotion", exports.devicemotion)
+ window.addEventListener("deviceorientation", exports.deviceorientation)
+ },
+ touchstart: function(e){
+ if (e.touches.length == 1) {
+ touching = true
+
+ startTime = Date.now()
+
+ var point = event.touches[0]
+ pointX = point.pageX
+ pointY = point.pageY
+ distX = distY = 0
+ pos.x = cam.x
+ pos.z = cam.z
+ pos.rotationY = cam.rotationY
+ }
+ },
+ touchmove: function(e){
+ e.preventDefault()
+ if (e.touches.length == 1) {
+
+ var timestamp = Date.now()
+ var point = event.touches[0]
+ deltaX = point.pageX - pointX
+ deltaY = point.pageY - pointY
+
+ pointX = point.pageX
+ pointY = point.pageY
+
+ distX += deltaX
+ distY += deltaY
+ absDistX = abs(distX)
+ absDistY = abs(distY)
+ }
+ },
+ touchend: function(e){
+ e.preventDefault()
+ if (e.touches.length == 0) {
+ touching = directionLocked = false
+ var timestamp = Date.now()
+ var duration = startTime - timestamp
+ if (duration < 300) {
+ }
+ }
+ },
+ orientationchange: function(e){
+ is_portrait = window.innerWidth < window.innerHeight
+ if (is_portrait) {
+ lastAlpha = 0
+ }
+ },
+ devicemotion: function(e) {
+ if (! is_portrait) return;
+ var rotationBeta = e.rotationRate.alpha; // weird!
+ rotationSum += rotationBeta;
+ samples += 1;
+ },
+ deviceorientation: function (e) {
+ if (! lastAlpha) { lastAlpha = e.alpha }
+ is_portrait ? exports.portraitorientation(e) : exports.landscapeorientation(e)
+ },
+ portraitorientation: function(e) {
+ // compass gives most accurate orientation in portrait mode
+ var alpha, dx = 0, dy = 0
+
+ if (e.webkitCompassHeading) {
+ alpha = 180 - e.webkitCompassHeading;
+ }
+ else {
+ alpha = 180 - e.alpha;
+ }
+
+ // android rotates in reverse
+ if (is_android) {
+ alpha = 360 - alpha
+ }
+
+ // use rotationRate to gauge if we've tilted the screen past vertical
+ // for looking at ceiling
+ if (e.beta > orientationMax) {
+ orientationMax = e.beta
+ rotationMedian = rotationSum
+ }
+
+ // this number was only going to 83 max.. not 90.. weird
+ var beta = e.beta + 7;
+
+ // if we've got enough motion data, we should be able to determine
+ // if we've tilted backwards. otherwise, lock to the horizon.
+ if (! is_android && samples > sampleThreshold) {
+ dx = rotationSum > rotationMedian ? e.beta - 90 : 90 - e.beta
+ }
+ else {
+ dx = 0
+ }
+
+ // avoid jumping around in a circle
+ if (Math.abs(alpha - lastAlpha) < 100 || Math.abs(alpha - lastAlpha) > 300) {
+ dy = alpha - lastAlpha
+ lastAlpha = alpha
+ }
+
+ // avoid jumping around in a circle #2
+ if (dy > 300) {
+ dy -= 360
+ } else if (dy < -300) {
+ dy += 360
+ }
+
+ destRotationX = MX.toRad(dx)
+ destRotationY += MX.toRad(dy)
+ },
+
+ landscapeorientation: function (e) {
+ var dx, dy
+
+ dx = e.gamma > 0 ? 90 - e.gamma : 90 + e.gamma
+ dy = e.alpha - lastAlpha
+ lastAlpha = e.alpha
- var timestamp = Date.now()
- var point = event.touches[0]
- deltaX = point.pageX - pointX
- deltaY = point.pageY - pointY
-
- pointX = point.pageX
- pointY = point.pageY
+ // avoid the sudden jump from 0 to -360
+ if (dy > 300) {
+ dy -= 360
+ }
+ else if (dy < -300) {
+ dy += 360
+ }
- distX += deltaX
- distY += deltaY
- absDistX = abs(distX)
- absDistY = abs(distY)
- }
- })
- document.addEventListener("touchend", function(e){
- e.preventDefault()
- if (e.touches.length == 0) {
- touching = directionLocked = false
- var timestamp = Date.now()
- var duration = startTime - timestamp
- if (duration < 300) {
- }
- }
- })
+ destRotationX = MX.toRad(dx)
+ destRotationY += MX.toRad(dy)
},
update: function () {
+ var drx, dry
+
+ dry = (destRotationY - rotationY) / 6
+ drx = (destRotationX - rotationX) / 6
+ rotationY += dry
+ rotationX += drx
+ cam.rotationY = pos.rotationY += dry
+ cam.rotationX = pos.rotationX += drx
+
if (distX || distY) {
var oldDistY = absDistY, oldDistX = absDistX
absDistY = avg(absDistY, 0, 5)
@@ -77,8 +190,7 @@ MX.MobileMovements = function (cam) {
pos.x -= dy * Math.cos(pos.rotationY + Math.PI / 2)
pos.z -= dy * Math.sin(pos.rotationY + Math.PI / 2)
- pos.rotationY += dx / (window.innerWidth) * Math.PI / 2
- cam.rotationY = pos.rotationY
+ cam.rotationY = pos.rotationY += dx / (window.innerWidth) * Math.PI / 2
app.tube("move", pos)
}
@@ -93,6 +205,7 @@ MX.MobileMovements = function (cam) {
jumpVelocity: function(n){ jumpV = clamp(n, 1, 50) },
}
+ return exports
}
diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js
index 5f2db0f..8531244 100644
--- a/public/assets/javascripts/ui/reader/ReaderView.js
+++ b/public/assets/javascripts/ui/reader/ReaderView.js
@@ -33,6 +33,8 @@ var ReaderView = View.extend({
data.media && Scenery.deserialize(data.media)
data.startPosition && scene.camera.move(data.startPosition)
+ cam.y = window.viewHeight = data.viewHeight || app.defaults.viewHeight
+
var colors = data.colors || app.defaults.colors
var modes = [ "wall", "outline", "floor", "ceiling" ]
modes.forEach(function(mode){