Skip to content

Commit

Permalink
Test file
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyHeleine committed Sep 7, 2015
1 parent ccc9832 commit a14ab52
Show file tree
Hide file tree
Showing 3 changed files with 495 additions and 0 deletions.
361 changes: 361 additions & 0 deletions src/sphoords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,361 @@
/*
* Sphoords v0.1
* http://jeremyheleine.me
*
* Copyright (c) 2015 Jérémy Heleine
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* Sphoords class allowing to retrieve the current orientation of a device supporting the Orientation API.
* @class
**/

var Sphoords = function() {
/**
* Detects the used browser engine.
* @private
* @return {void}
**/

var detectBrowserEngine = function() {
// User-Agent
var ua = navigator.userAgent;

// Gecko
if (/Gecko\/[0-9.]+/.test(ua))
return 'Gecko';

// Blink
if (/Chrome\/[0-9.]+/.test(ua))
return 'Blink';

// WebKit
if (/AppleWebKit\/[0-9.]+/.test(ua))
return 'WebKit';

// Trident
if (/Trident\/[0-9.]+/.test(ua))
return 'Trident';

// Presto
if (/Opera\/[0-9.]+/.test(ua))
return 'Presto';

// No engine detected, Gecko by default
return 'Gecko';
};

/**
* Returns the principal angle in degrees.
* @private
* @param {number} angle - The initial angle
* @return {number} The principal angle
**/

var getPrincipalAngle = function(angle) {
return angle - Math.floor(angle / 360.0) * 360.0;
};

/**
* Attaches the DeviceOrientation event to the window and starts the record, only if Device Orientation is supported.
* @public
* @return {boolean} `true` if event is attached, `false` otherwise
**/

this.start = function() {
if (Sphoords.isDeviceOrientationSupported) {
window.addEventListener('deviceorientation', onDeviceOrientation, false);

recording = true;
return true;
}

else {
console.log('Device Orientation API not supported');
return false;
}
};

/**
* Stops the record by removing the event handler.
* @public
* @return {void}
**/

this.stop = function() {
// Is there something to remove?
if (recording) {
window.removeEventListener('deviceorientation', onDeviceOrientation, false);

recording = false;
}
};

/**
* Toggles the recording state.
* @public
* @return {void}
**/

this.toggle = function() {
if (recording)
this.stop();

else
this.start();
};

/**
* Determines whether Device Orientation Event is attached.
* @public
* @return {boolean} `true` if event is attached, `false` otherwise
**/

this.isEventAttached = function() {
return recording;
};

/**
* Records the current orientation
* @private
* @param {Event} evt - The event
* @return {void}
**/

var onDeviceOrientation = function(evt) {
// Current screen orientation
orientation = Sphoords.getScreenOrientation();

// Coordinates depend on the orientation
var theta = 0, phi = 0;

switch (orientation) {
// Portrait mode
case 'portrait-primary':
theta = evt.alpha + evt.gamma;
phi = evt.beta - 90;

break;

// Landscape mode
case 'landscape-primary':
// If "-90" is not present for theta, origin won't be the same than for portrait mode
theta = evt.alpha + evt.beta - 90;
phi = -evt.gamma - 90;

// The user looks to the top while phi "looks" to the bottom
if (Math.abs(evt.beta) > 90) {
// Here browser engines have different behaviors
// Hope we have a really respected standard soon

switch (engine) {
case 'Blink':
phi += 180;
break;

case 'Gecko':
default:
phi = -phi;
break;
}
}

break;

// Landscape mode (inversed)
case 'landscape-secondary':
// Still the same reason for "+90"
theta = evt.alpha - evt.beta + 90;
phi = evt.gamma - 90;

// The user looks to the top while phi "looks" to the bottom
if (Math.abs(evt.beta) > 90) {
// Here again, some different behaviors…

switch (engine) {
case 'Blink':
phi += 180;
break;

case 'Gecko':
default:
phi = -phi;
break;
}
}

break;

// Portrait mode (inversed)
case 'portrait-secondary':
theta = evt.alpha - evt.gamma;
phi = 180 - (evt.beta - 90);
phi = 270 - evt.beta;

break;
}

// First, we want phi to be between -π and π
phi = getPrincipalAngle(phi);

if (phi >= 180)
phi -= 360;

// We store the right values
long_deg = getPrincipalAngle(theta);
lat_deg = Math.max(-90, Math.min(90, phi));

long = long_deg * DEG_TO_RAD;
lat = lat_deg * DEG_TO_RAD;

// We execute the wanted functions
executeListeners();
};

/**
* Returns the current coordinates.
* @public
* @return {object} Longitude/latitude couple
**/

this.getCoordinates = function() {
return {
longitude: long,
latitude: lat
};
};

/**
* Returns the current coordinates in degrees.
* @return {object} Longitude/latitude couple
**/

this.getCoordinatesInDegrees = function() {
return {
longitude: long_deg,
latitude: lat_deg
};
};

/**
* Returns the current screen orientation.
* @return {string|null} The screen orientation (portrait-primary, portrait-secondary, landscape-primary, landscape-secondary) or `null` if not supported
**/

this.getScreenOrientation = function() {
return orientation;
};

/**
* Adds a function to execute when device orientation changes.
* @public
* @param {function} f - The handler function
* @return {void}
**/

this.addListener = function(f) {
listeners.push(f);
};

/**
* Executes all the wanted functions for the main event.
* @private
* @return {void}
**/

var executeListeners = function() {
if (!!listeners.length) {
for (var i = 0, l = listeners.length; i < l; ++i) {
listeners[i]({
longitude: long,
latitude: lat
});
}
}
};

// Current state
var recording = false;

// Coordinates in degrees
var long_deg = 0, lat_deg = 0;

// Coordinates in radians
var long = 0, lat = 0;

// What a useful constant!
var DEG_TO_RAD = Math.PI / 180;

// Screen orientation
var orientation = Sphoords.getScreenOrientation();

// Browser engine
var engine = detectBrowserEngine();

// Listeners
var listeners = [];
};

/**
* Retrieves the current screen orientation.
* @static
* @return {string|null} Current screen orientation, `null` if not supported
**/

Sphoords.getScreenOrientation = function() {
var screen_orientation = null;

if (!!screen.orientation)
screen_orientation = screen.orientation;

else if (!!screen.mozOrientation)
screen_orientation = screen.mozOrientation;

else if (!!screen.msOrientation)
screen_orientation = screen.msOrientation;

// Are the specs respected?
return (screen_orientation !== null && (typeof screen_orientation == 'object')) ? screen_orientation.type : screen_orientation;
};

/**
* A boolean to know if device orientation is supported (`true` if it is, `false` otherwise).
* @static
**/

Sphoords.isDeviceOrientationSupported = false;

// Just testing if window.DeviceOrientationEvent is defined is not enough
// In fact, it can return false positives with some desktop browsers which run in computers that don't have the dedicated hardware
(function() {
// We attach the right event
// If it is fired, the API is really supported so we can indicate true :)
if (!!window.DeviceOrientationEvent && Sphoords.getScreenOrientation() !== null) {
function testDeviceOrientation(evt) {
if (evt !== null && evt.alpha !== null) {
Sphoords.isDeviceOrientationSupported = true;
window.removeEventListener('deviceorientation', testDeviceOrientation);
}
}

window.addEventListener('deviceorientation', testDeviceOrientation);
}
})();
Loading

0 comments on commit a14ab52

Please sign in to comment.