From 67997a7fa02ed1732dddfdffb1ba8f9a20950122 Mon Sep 17 00:00:00 2001 From: Zach Holman Date: Mon, 3 Dec 2012 13:26:02 +1000 Subject: [PATCH 1/2] Add gyroscopic support This removes a lot of spaghetti code surrounding how we handled accelerometer support in Plax in favor of using the iPhone's gyroscope instead. This means we get a clean range-of-motion effect, much as if you were looking through a window at the object. Kind of. Sort of. This probably removes support for desktop (which I think is a good thing, since people tend not to move their laptops around), and potentially support for Android and weird devices like that. We can add that back in later. In general, though, I think this greatly increases the readability of the project and gives it an effect that makes a lot more sense. --- js/plax.js | 152 ++++++++--------------------------------------------- 1 file changed, 23 insertions(+), 129 deletions(-) diff --git a/js/plax.js b/js/plax.js index aebf67a..77fa1cf 100644 --- a/js/plax.js +++ b/js/plax.js @@ -30,23 +30,12 @@ lastRender = new Date().getTime(), layers = [], plaxActivityTarget = $(window), - motionEnabled = false, motionMax = 1, - motionAllowance = .05, - movementCycles = 0, - motionLowPassFilter= 0.05, - motionLastX = 1, - motionLastY = 1, - motionData = { - "xArray" : [0,0,0,0,0], - "yArray" : [0,0,0,0,0], - "xMotion" : 0, - "yMotion" : 0 - } + motionStartX = null, + motionStartY = null // Public Methods $.fn.plaxify = function (params){ - return this.each(function () { var layerExistsAt = -1 var layer = { @@ -111,103 +100,29 @@ }) } - - // Get minimum value of an array - // - // arr - array to be tested - // - // returns the smallest value in the array - - function getMin(arr){ - return Math.min.apply({}, arr) - } - - - // Get maximum value of an array - // - // arr - array to be tested - // - // returns the largest value in the array - - function getMax(arr){ - return Math.max.apply({}, arr) - } - - // Determine if the device has an accelerometer // // returns true if the browser has window.DeviceMotionEvent (mobile) - function moveable(){ return window.DeviceMotionEvent != undefined } - - // Determine if the device is actually moving. If it is, enable motion based parallaxing. - // Otherwise, use the mouse to parallax - // - // Parameters - // - // e - devicemotion event + // The values pulled from the gyroscope of a motion device. // - // returns nothing - - function detectMotion(e){ - if (new Date().getTime() < lastRender + delay) return - - if(moveable()){ - var accel= e.accelerationIncludingGravity, - x = accel.x, - y = accel.y - - x = (x * motionLowPassFilter) + (motionLastX * (1.0 - motionLowPassFilter)); - y = (y * motionLowPassFilter) + (motionLastY * (1.0 - motionLowPassFilter)); - - motionLastX = x; - motionLastY = y; - - if(motionData.xArray.length >= 5){ - motionData.xArray.shift() - } - if(motionData.yArray.length >= 5){ - motionData.yArray.shift() - } - motionData.xArray.push(x) - motionData.yArray.push(y) - - motionData.xMotion = Math.round((getMax(motionData.xArray) - getMin(motionData.xArray))*1000)/1000 - motionData.yMotion = Math.round((getMax(motionData.yArray) - getMin(motionData.yArray))*1000)/1000 - - if((motionData.xMotion > 1.5 || motionData.yMotion > 1.5)) { - if(motionMax!=10){ - motionMax = 10 - } - } - - // test for sustained motion - if(motionData.xMotion > motionAllowance || motionData.yMotion > motionAllowance){ - movementCycles++; - } else { - movementCycles = 0; - } + // Returns an object literal with x and y as options. + function valuesFromMotion(e) { + x = e.gamma + y = e.beta - if(movementCycles >= 5){ - motionEnabled = true - $(document).unbind('mousemove.plax') - //window.ondevicemotion = function(e){plaxifier(e)} + motionStartX = (motionStartX == null) ? x : motionStartX + motionStartY = (motionStartY == null) ? y : motionStartY - $(window).bind('devicemotion', plaxifier(e)) - } else { - motionEnabled = false - $(window).unbind('devicemotion') - $(document).bind('mousemove.plax', function (e) { - plaxifier(e) - }) - } + return { + x: x - motionStartX, + y: y - motionStartY } } - // Move the elements in the `layers` array within their ranges, // based on mouse or motion input // @@ -216,12 +131,11 @@ // e - mousemove or devicemotion event // // returns nothing - function plaxifier(e) { if (new Date().getTime() < lastRender + delay) return lastRender = new Date().getTime() var leftOffset = (plaxActivityTarget.offset() != null) ? plaxActivityTarget.offset().left : 0, - topOffset = (plaxActivityTarget.offset() != null) ? plaxActivityTarget.offset().top : 0, + topOffset = (plaxActivityTarget.offset() != null) ? plaxActivityTarget.offset().top : 0, x = e.pageX-leftOffset, y = e.pageY-topOffset if ( @@ -229,37 +143,18 @@ y < 0 || y > plaxActivityTarget.height() ) return + if(moveable()){ + values = valuesFromMotion(e) - if(motionEnabled == true){ - // portrait(%2==0) or landscape - var i = window.orientation ? (window.orientation + 180) % 360 / 90 : 2, - accel= e.accelerationIncludingGravity, - tmp_x = i%2==0 ? -accel.x : accel.y, - tmp_y = i%2==0 ? accel.y : accel.x - // facing up(>=2) or down - x = i>=2 ? tmp_x : -tmp_x - y = i>=2 ? tmp_y : -tmp_y - - // change value from a range of -x to x => 0 to 1 - x = (x+motionMax)/2 - y = (y+motionMax)/2 + // Admittedly fuzzy measurements + x = values.x / 30 + y = values.y / 30 - // keep values within range - if(x < 0 ){ - x = 0 - } else if( x > motionMax ) { - x = motionMax - } - - if(y < 0 ){ - y = 0 - } else if( y > motionMax ) { - y = motionMax - } + console.log(x) } - var hRatio = x/((motionEnabled == true) ? motionMax : plaxActivityTarget.width()), - vRatio = y/((motionEnabled == true) ? motionMax : plaxActivityTarget.height()), + var hRatio = x/((moveable() == true) ? motionMax : plaxActivityTarget.width()), + vRatio = y/((moveable() == true) ? motionMax : plaxActivityTarget.height()), layer, i for (i = layers.length; i--;) { @@ -277,7 +172,6 @@ } $.plax = { - // Begin parallaxing // // Parameters @@ -300,7 +194,7 @@ }) if(moveable()){ - window.ondevicemotion = function(e){detectMotion(e)} + window.ondeviceorientation = function(e){plaxifier(e)} } }, @@ -315,7 +209,7 @@ // returns nothing disable: function(){ $(document).unbind('mousemove.plax') - window.ondevicemotion = undefined + window.ondeviceorientation = undefined } } From cf06a692feb987874a4a249b6cbf03b59cbf905f Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Sat, 8 Dec 2012 11:28:43 -0800 Subject: [PATCH 2/2] Account for the fact that firefox still fires DeviceOrientationEvent --- js/plax.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/js/plax.js b/js/plax.js index 77fa1cf..fd86c04 100644 --- a/js/plax.js +++ b/js/plax.js @@ -32,7 +32,8 @@ plaxActivityTarget = $(window), motionMax = 1, motionStartX = null, - motionStartY = null + motionStartY = null, + ignoreMoveable = false // Public Methods $.fn.plaxify = function (params){ @@ -104,7 +105,7 @@ // // returns true if the browser has window.DeviceMotionEvent (mobile) function moveable(){ - return window.DeviceMotionEvent != undefined + return (ignoreMoveable==true) ? false : window.DeviceOrientationEvent != undefined } // The values pulled from the gyroscope of a motion device. @@ -144,13 +145,14 @@ ) return if(moveable()){ + if(e.gamma == undefined){ + ignoreMoveable = true + } values = valuesFromMotion(e) // Admittedly fuzzy measurements x = values.x / 30 y = values.y / 30 - - console.log(x) } var hRatio = x/((moveable() == true) ? motionMax : plaxActivityTarget.width()),