summaryrefslogtreecommitdiff
path: root/client/assets/javascripts/mx/extensions/mx.rotationControl.js
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2014-06-03 16:24:10 -0400
committerJules Laplace <jules@okfoc.us>2014-06-03 16:24:28 -0400
commit607f69c67a5b4dc72d2754192e3cdf67d0ad11d0 (patch)
tree6556e7922c5bedb274bb1650e5dd100643a7895d /client/assets/javascripts/mx/extensions/mx.rotationControl.js
parentd31259291d807c851de4396921e0c26b6dd8dce2 (diff)
partitioning client and serveR
Diffstat (limited to 'client/assets/javascripts/mx/extensions/mx.rotationControl.js')
-rw-r--r--client/assets/javascripts/mx/extensions/mx.rotationControl.js265
1 files changed, 265 insertions, 0 deletions
diff --git a/client/assets/javascripts/mx/extensions/mx.rotationControl.js b/client/assets/javascripts/mx/extensions/mx.rotationControl.js
new file mode 100644
index 0000000..9adb627
--- /dev/null
+++ b/client/assets/javascripts/mx/extensions/mx.rotationControl.js
@@ -0,0 +1,265 @@
+// Usage:
+//
+// var control = new MX.RotationControl()
+// control.init( object{MX.Object3D} [, listener{HTMLElement}] )
+//
+// In animation loop:
+//
+// control.update()
+//
+// The above code will register handler functions on `listener`
+// and will be updating `object`s rotationX and rotationY
+// If no `listener` is provided, will default to `object`s el.
+
+MX.RotationControl = function () {
+
+ var object,
+ locked = false
+
+ var down = false,
+ active = false,
+ lastX,
+ lastY
+
+ var pointerLockPrefix =
+ 'pointerLockElement' in document ? '' :
+ 'mozPointerLockElement' in document ? 'moz' :
+ 'webkitPointerLockElement' in document ? 'webkit' : null,
+ hasPointerLock = !(pointerLockPrefix === null)
+ pointerLockEnabled = false
+
+ var pub = {
+
+ sensitivity : .5,
+ ease : 10,
+ drag : true,
+
+ inverseX : false,
+ inverseY : false,
+
+ disableX : false,
+ disableY : false,
+
+ rotationX : 0,
+ rotationY : 0,
+
+ upperBoundX : undefined,
+ lowerBoundX : undefined,
+
+ upperBoundY : undefined,
+ lowerBoundY : undefined,
+
+ usePreset: function (name) {
+ var ops = presets[name]
+ if (ops) {
+ if (currentPreset && presets[currentPreset].teardown) {
+ presets[currentPreset].teardown()
+ }
+ for (var op in ops) {
+ if (op !== 'setup' && op !== 'teardown') {
+ pub[op] = ops[op]
+ }
+ }
+ if (op.setup) ops.setup()
+ }
+ }
+ }
+
+ var currentPreset
+ var presets = {
+ firstPerson: {
+ drag: false,
+ ease: 2,
+ sensitivity: .18,
+ inverseX: true,
+ inverseY: true,
+ upperBoundX: MX.rotationUnit === 'deg' ? 90 : Math.PI / 2,
+ lowerBoundX: MX.rotationUnit === 'deg' ? -90 : -Math.PI / 2
+ },
+ skybox: {
+ sensitivity: .18,
+ inverseX: true,
+ inverseY: true,
+ upperBoundX: MX.rotationUnit === 'deg' ? 90 : Math.PI / 2,
+ lowerBoundX: MX.rotationUnit === 'deg' ? -90 : -Math.PI / 2
+ }
+ }
+
+ function init (obj, lis) {
+ if (active) return
+
+ object = obj
+ pub.rotationX = object.rotationX
+ pub.rotationY = object.rotationY
+
+ if (lis instanceof HTMLElement) {
+ listener = lis
+ } else if (lis instanceof MX.Object3D) {
+ listener = lis.el
+ } else {
+ listener = window.document
+ }
+
+ listener.addEventListener('mousedown', onDown)
+ listener.addEventListener('mousemove', onMove)
+ listener.addEventListener('mouseup', onUp)
+ listener.addEventListener('touchstart', onDown)
+ listener.addEventListener('touchmove', onMove)
+ listener.addEventListener('touchend', onUp)
+
+ active = true
+ }
+
+ function changeObject (obj) {
+ object = obj
+ pub.rotationX = object.rotationX
+ pub.rotationY = object.rotationY
+ }
+
+ function changeListener (lis) {
+ remove()
+ active = false
+ init(object, lis)
+ if (pointerLockEnabled) {
+ initPointerLock()
+ }
+ }
+
+ function remove () {
+ if (!active) return
+ listener.removeEventListener('mousedown', onDown)
+ listener.removeEventListener('mousemove', onMove)
+ listener.removeEventListener('mouseup', onUp)
+ listener.removeEventListener('touchstart', onDown)
+ listener.removeEventListener('touchmove', onMove)
+ listener.removeEventListener('touchend', onUp)
+
+ if (hasPointerLock) {
+ document.removeEventListener(pointerLockPrefix + 'pointerlockchange', onPointerLockChange)
+ document.removeEventListener('mousemove', onPointerLockMove)
+ document.body[pointerLockPrefix + (pointerLockPrefix ? 'E' : 'e') + 'xitPointerLock']()
+ }
+ active = false
+ }
+
+ function onDown (e) {
+ e = normalizeEvent(e)
+ if (!e) return
+ down = true
+ lastX = e.pageX
+ lastY = e.pageY
+ }
+
+ function onMove (e) {
+ if (e.type = 'touchmove') {
+ e.preventDefault()
+ }
+ if (pub.drag && !down) return
+ e = normalizeEvent(e)
+ if (!e) return
+ lastX = lastX || e.pageX
+ lastY = lastY || e.pageY
+ var dx = e.pageX - lastX,
+ dy = e.pageY - lastY
+ lastX = e.pageX
+ lastY = e.pageY
+ updateTarget(dx, dy)
+ }
+
+ function onUp () {
+ down = false
+ }
+
+ function initPointerLock () {
+
+ if (pointerLockEnabled) return
+
+ document.addEventListener(pointerLockPrefix + 'pointerlockchange', onPointerLockChange)
+ document.addEventListener('mousemove', onPointerLockMove)
+
+ document.body[pointerLockPrefix + (pointerLockPrefix ? 'R' : 'r') + 'equestPointerLock']()
+ }
+
+ function onPointerLockChange () {
+ var el = document.body
+ if (document[pointerLockPrefix + (pointerLockPrefix ? 'P' : 'p') + 'ointerLockElement'] === el) {
+ pointerLockEnabled = true
+ } else {
+ pointerLockEnabled = false
+ }
+ }
+
+ function onPointerLockMove (e) {
+ if (!pointerLockEnabled) return
+ var dx = e[pointerLockPrefix + (pointerLockPrefix ? 'M' : 'm') + 'ovementX'],
+ dy = e[pointerLockPrefix + (pointerLockPrefix ? 'M' : 'm') + 'ovementY']
+ updateTarget(dx, dy)
+ }
+
+ function normalizeEvent (e) {
+ if (e.touches) {
+ return e.touches.length > 1 ? false : e.touches[0]
+ } else {
+ return e
+ }
+ }
+
+ function updateTarget (dx, dy) {
+ if (pub.inverseX) dx = -dx
+ if (pub.inverseY) dy = -dy
+ if (MX.rotationUnit !== 'deg') {
+ dx = MX.toRad(dx)
+ dy = MX.toRad(dy)
+ }
+
+ if (!pub.disableX) {
+ pub.rotationX -= dy * pub.sensitivity
+ if (pub.upperBoundX) pub.rotationX = Math.min(pub.rotationX, pub.upperBoundX)
+ if (pub.lowerBoundX) pub.rotationX = Math.max(pub.rotationX, pub.lowerBoundX)
+ }
+
+ if (!pub.disableY) {
+ pub.rotationY += dx * pub.sensitivity
+ if (pub.upperBoundY) pub.rotationY = Math.min(pub.rotationY, pub.upperBoundY)
+ if (pub.lowerBoundY) pub.rotationY = Math.max(pub.rotationY, pub.lowerBoundY)
+ }
+ }
+
+ function update () {
+ if (!object || locked) return
+ var dx = pub.rotationX - object.rotationX,
+ dy = pub.rotationY - object.rotationY
+ if (Math.abs(dx) < 0.0001) {
+ object.rotationX = pub.rotationX
+ } else {
+ object.rotationX += dx / pub.ease
+ }
+ if (Math.abs(dy) < 0.0001) {
+ object.rotationY = pub.rotationY
+ } else {
+ object.rotationY += dy / pub.ease
+ }
+ }
+
+ function lock () {
+ locked = true
+ }
+
+ function unlock () {
+ pub.rotationX = object.rotationX
+ pub.rotationY = object.rotationY
+ locked = false
+ }
+
+ pub.init = init
+ pub.remove = remove
+ pub.update = update
+ pub.lock = lock
+ pub.unlock = unlock
+ pub.initPointerLock = initPointerLock
+ pub.changeObject = changeObject
+ pub.changeListener = changeListener
+
+ return pub
+
+} \ No newline at end of file