diff options
Diffstat (limited to 'js/mx/mx.followingOrbitCamera.js')
| -rw-r--r-- | js/mx/mx.followingOrbitCamera.js | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/js/mx/mx.followingOrbitCamera.js b/js/mx/mx.followingOrbitCamera.js new file mode 100644 index 0000000..ea7f6a0 --- /dev/null +++ b/js/mx/mx.followingOrbitCamera.js @@ -0,0 +1,148 @@ +MX.FollowingOrbitCamera = function(opt){ + var exports = {}, bound = false, portraitMode = false + var locked = false + exports.opt = opt = defaults(opt, { + el: window, // object to bind events on + camera: scene.camera, // camera object we'll be moving + radius: 100, + radiusRange: [ 10, 1000 ], + rotationX: Math.PI/2, + rotationY: 0, + rotationXRange: [ 0, 1 ], + rotationYRange: [ 0, 1 ], + center: { x: 0, y: 0, z: 0 }, + sensitivity: 10, // moving 1 pixel is like moving N radians + wheelSensitivity: 10, + ease: 10, + }) + opt.rotationXRange[0] *= Math.PI + opt.rotationXRange[1] *= Math.PI + opt.rotationYRange[0] *= Math.PI + opt.rotationYRange[1] *= Math.PI + var rx, ry, radius, px, py, epsilon = 1e-5, dragging = false + exports.init = function(){ + opt.rotationY = ry = ( opt.rotationYRange[0] + opt.rotationYRange[1] ) / 2 + opt.rotationX = rx = ( opt.rotationXRange[0] + opt.rotationXRange[1] ) / 2 + radius = opt.radius + exports.wheel = new wheel({ + el: opt.el, + update: function(e, delta){ + if (locked) return + opt.radius = clamp( opt.radius + delta * opt.wheelSensitivity, opt.radiusRange[0], opt.radiusRange[1] ) + }, + }) + exports.bind() + } + exports.toggle = function(state){ + if (state) exports.bind() + else exports.unbind() + } + exports.lock = function(){ + locked = true + } + exports.unlock = function(){ + locked = false + } + exports.bind = function(){ + if (bound) return; + bound = true + // opt.el.addEventListener("mousedown", down) + if (is_mobile) { + if ('DeviceOrientationEvent' in window) { + window.addEventListener("resize", resize) + window.addEventListener("deviceorientation", deviceorientation) + resize() + } + } + else { + window.addEventListener("mousemove", move) + } + // window.addEventListener("mouseup", up) + exports.wheel.unlock() + } + exports.unbind = function(){ + if (! bound) return; + bound = false + // opt.el.removeEventListener("mousedown", down) + window.removeEventListener("mousemove", move) + // window.removeEventListener("mouseup", up) + exports.wheel.lock() + } + // function down (e) { + // px = e.pageX + // py = e.pageY + // dragging = true + // } + function move (e) { + // if (! dragging) return + // exports.delta(px - e.pageX, py - e.pageY) + if (locked) return + exports.delta( e.pageX, e.pageY) + px = e.pageX + py = e.pageY + } + function resize (e) { + var aspect = window.innerHeight / window.innerWidth; + portraitMode = aspect >= 1; + } + function deviceorientation (e){ + if (e && 'beta' in e && e.beta) { + var b, g + if (portraitMode) { + b = e.beta + g = e.gamma + } else { + b = e.gamma + g = e.beta + } + + // console.log(b, g) + } + } + // function up (e) { + // dragging = false + // } + exports.delta = function(x,y){ + // opt.rotationY += x/window.innerWidth * opt.sensitivity + // opt.rotationX = clamp( opt.rotationX + y/window.innerHeight * opt.sensitivity, 0, Math.PI) + opt.rotationY = lerp( x / window.innerWidth, opt.rotationYRange[0], opt.rotationYRange[1] ) + opt.rotationX = lerp( y / window.innerHeight, opt.rotationXRange[0], opt.rotationXRange[1] ) + } + exports.zoom = function(r){ + opt.radius = r + } + exports.zoomDelta = function(r){ + opt.radius += r + } + exports.move = function(y, x){ + opt.rotationY = y + if (typeof x == "number") { opt.rotationX = x } + } + exports.update = function(){ + if (locked) return + if (Math.abs(ry - opt.rotationY) > epsilon) { + ry = avg(ry, opt.rotationY, opt.ease) + } + else { + ry = opt.rotationY + } + if (Math.abs(rx - opt.rotationX) > epsilon) { + rx = avg(rx, opt.rotationX, opt.ease) + } + else { + rx = opt.rotationX + } + if (Math.abs(radius - opt.radius) > epsilon) { + radius = avg(radius, opt.radius, opt.ease) + } + else { + radius = opt.radius + } + opt.camera.x = opt.center.x + radius * Math.sin(rx) * Math.cos(ry) + opt.camera.z = opt.center.y + radius * Math.sin(rx) * Math.sin(ry) + opt.camera.y = opt.center.z + radius * Math.cos(rx) + opt.camera.rotationX = Math.PI/2 - rx + opt.camera.rotationY = ry + Math.PI/2 + } + return exports +} |
