Reputation: 9
I've looked and asked around for a solution to this problem and have had no luck so far. I hope someone can help me.
I've been working on a parallax effect based on [this][1] tutorial I found a while back. It does what it should, in that all of the elements move left and right depending on where you move the mouse. I would like to adjust it, though, if possible, so that it scrolls smoothly left or right depending on where the mouse is. As it is now, it only moves if the mouse moves. I would prefer to change it so that it scrolls continuously at a set speed for a given width of space either left or right, depending where the mouse is positioned relative to the center.
Here is the code I have so far, which, again, works just like the first section of the tutorial I linked above:
var headerDiv = document.getElementById("header");
var image1Div = document.getElementById("image1");
var image2Div = document.getElementById("image2");
var image3Div = document.getElementById("image3");
var image4Div = document.getElementById("image4");
var headerDivHeight;
var canStartParallax = false;
var canPositionDivsVertically = true;
// Detect if the browser is IE or not.
// If it is not IE, we assume that the browser is NS.
var IE = document.all?true:false
// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE)
// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;
// Temporary variables to hold mouse x-y pos.s
var tempX = 0;
var tempY = 0;
var objectArray = new Array();
window.onload = function()
{
showAllOfTheContent();
headerDivHeight = headerDiv.offsetHeight;
fillObjectArray();
setimage1ToTransparent();
positionDivs();
turnOffPreloaderDotAnimation();
objectAnimation();
}
function showAllOfTheContent()
{
document.getElementById("content").setAttribute("class", "");
}
function fillObjectArray()
{
var image1X = { getX: function() {return 0.5 * windowWidth + 50} };
var image1Y = 10;
var image1Factor = 0.0;
var image1Array = new Array();
image1Array.push(image1Div, image1X, image1Y, image1Factor);
objectArray.push(image1Array);
var image2X = { getX: function() {return 0.5 * windowWidth - 202} }; //position div from half width of the page
var image2Y = 0;
var image2Factor = 0.20; //parallax shift factor, the bigger the value, the more it shift for parallax movement
var image2Array = new Array();
image2Array.push(image2Div, image2X, image2Y, image2Factor);
objectArray.push(image2Array);
var image3X = { getX: function() {return 0.5 * windowWidth - -160} };
var image3Y = 23;
var image3Factor = 0.60;
var image3Array = new Array();
image3Array.push(image3Div, image3X, image3Y, image3Factor);
objectArray.push(image3Array);
var image4X = { getX: function() {return 0.5 * windowWidth + 50} };
var image4Y = 60;
var image4Factor = 1.0;
var image4Array = new Array();
image4Array.push(image4Div, image4X, image4Y, image4Factor);
objectArray.push(image4Array);
var image5Div = document.getElementById("image5");
var image5X = { getX: function() {return 0.5 * windowWidth + 500} };
var image5Y = 400;
var image5Factor = 0.85;
var image5Array = new Array();
image5Array.push(image5Div, image5X, image5Y, image5Factor);
objectArray.push(image5Array);
}
// Main function to retrieve mouse x-y pos.s
function getMouseXY(e)
{
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
moveDiv(tempX, tempY);
return true
}
function moveDiv(tempXsent, tempYsent)
{
if (canStartParallax == true)
{
var tempXreceived = tempXsent;
var tempYreceived = tempYsent;
if (tempYreceived <= headerDivHeight) //limit the mouse over area
{
for (var i=0;i<objectArray.length;i++)
{
var yourDivPositionX = objectArray[i][3] * (0.5 * windowWidth - tempXreceived) + objectArray[i][1].getX();
objectArray[i][0].style.left = yourDivPositionX + 'px';
}
}
}
}
function positionDivs()
{
var verticalParallaxFactorMultiplyNumber = 2; //the bigger this number, the vertical gap between header object animation will be bigger too
for (var i=0;i<objectArray.length;i++)
{
objectArray[i][0].style.left = objectArray[i][1].getX() + "px";
if (canPositionDivsVertically == true)
{
if ((objectArray[i][0] == image2Div) || (objectArray[i][0] == image3Div) || (objectArray[i][0] == image4Div))
{
objectArray[i][0].style.top = objectArray[i][2] - ((1 + (verticalParallaxFactorMultiplyNumber * objectArray[i][3])) * windowHeight) + "px";
}
else if ((objectArray[i][0] == image1Div))
{
objectArray[i][0].style.top = objectArray[i][2] + "px";
}
else
{
objectArray[i][0].style.top = objectArray[i][2] + ((1 + (verticalParallaxFactorMultiplyNumber * objectArray[i][3])) * windowHeight) + "px";
}
}
}
}
function setimage1ToTransparent()
{
image1Div.style.opacity = 0;
image1Div.style.filter = "alpha(opacity=" + 0 + ")";
}
function objectAnimation()
{
var objectAnimationDuration = 2000;
//animate preloader
$(preloaderAndStringContainerDiv).stop().animate({top: (-1 * windowHeight) + "px"}, objectAnimationDuration, function() {hidePreloader()});
for (var i=0;i<objectArray.length;i++)
{
if ((objectArray[i][0] == image1Div))
{
$(objectArray[i][0]).stop().fadeTo(objectAnimationDuration, 1);
}
else
{
if ((navigator.userAgent.match(/iPad/i) != null) || (navigator.userAgent.match(/iPhone/i) != null) || (navigator.userAgent.match(/iPod/i) != null)) //if using safari mobile device, never turn on parallax
{
$(objectArray[i][0]).stop().animate({top: objectArray[i][2] + "px"}, objectAnimationDuration, function() {canPositionDivsVertically = false});
}
else
{
$(objectArray[i][0]).stop().animate({top: objectArray[i][2] + "px"}, objectAnimationDuration, function() {canStartParallax = true; canPositionDivsVertically = false});
}
}
}
}
function resizeHeader()
{
positionDivs();
}
Could anyone advise me, please? I'd really appreciate it. Thanks.
Upvotes: 0
Views: 445
Reputation: 20141
At present the moveDiv routine is called by the mouseXY function, which is set as the handler for mousemove events. So until you move the mouse, nothing is triggering.
Instead, you want to use the mousemove to alter some velocity vector, and use some trigger to enter a continuous loop (I suggest starting with a setInterval) which uses this velocity vector to call moveDiv.
Since you won't want this to happen on hover movement (otherwise it will first spin wildly when you mouseover the box), consider entering the loop on mousedown, and exiting the loop on mouseup and mouseout.
As you are doing animation here, take a look at using requestAnimationFrame, a feature in newer browsers to support smooth animation rendering, to which you supply a function to execute repeatedly:
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
With any of these approaches, I suggest you keep both a vector for the speed (adjusted by mousemove events) and a timestamp variable which is updated every frame. You won't be able to predict the delay between calls to your code, so to keep things consistent you should calculate the distance moved using the delta between now and the last frame timestamp.
Upvotes: 1