10

I'm trying to create a slight parallax effect (I'm not sure if it really constitutes parallax but it's a similar idea). Where there are four layers which all move around at a slightly different rate when the mouse moves.

I have found a great example that offers something similar to what I want:

http://jsfiddle.net/X7UwG/2/

It achieves this by shifting the background position on the #landing-content div when the mouse moves.

$(document).ready(function(){
  $('#landing-content').mousemove(function(e){
    var x = -(e.pageX + this.offsetLeft) / 20;
    var y = -(e.pageY + this.offsetTop) / 20;
    $(this).css('background-position', x + 'px ' + y + 'px');
  });  
});

However, I cannot work out a way to get this to work not on a background-position shift, but on a div position shift. E.g position:relative; and top:x so that the div itself moves around a little.

My reasoning is that the div contains CSS animation elements so it needs to be a div with content inside it, not a background image.

Any solutions for this using the code above?

Community
  • 1
  • 1
Francesca
  • 26,842
  • 28
  • 90
  • 153
  • so you want the whole div to move - the one with bakcground image ? – LorDex Jun 10 '15 at 16:01
  • @LorDex yes, the background div should move but the slide layer should stay static. – Francesca Jun 10 '15 at 16:03
  • @LorDex here is an example with three layers. However they are still background images. I need them to be divs with content instead. http://jsfiddle.net/X7UwG/851/ – Francesca Jun 10 '15 at 16:04
  • Can anybody explain to me why this question is marked "This question does not appear to be about programming" – Francesca Jun 12 '15 at 09:27

1 Answers1

16

How about using jQuery.offSet() instead? You might want to adjust the math/values, but I think it should set you in the right direction.

$(document).ready(function () {
    $('#layer-one').mousemove(function (e) {
        parallax(e, this, 1);
        parallax(e, document.getElementById('layer-two'), 2);
        parallax(e, document.getElementById('layer-three'), 3);
    });
});

function parallax(e, target, layer) {
    var layer_coeff = 10 / layer;
    var x = ($(window).width() - target.offsetWidth) / 2 - (e.pageX - ($(window).width() / 2)) / layer_coeff;
    var y = ($(window).height() - target.offsetHeight) / 2 - (e.pageY - ($(window).height() / 2)) / layer_coeff;
    $(target).offset({ top: y ,left : x });
};

JSFiddle: http://jsfiddle.net/X7UwG/854/

Josh Bilderback
  • 198
  • 1
  • 6
  • I also noticed you wanted the slider to remain static, so I modified the jsfiddle to apply 0 coefficient parallax to that section: http://jsfiddle.net/X7UwG/855/ – Josh Bilderback Jun 11 '15 at 16:09
  • Hi there, thanks for this. It worked excellently. However I'm having a small issue. The `#bottom-layer` seems to be way off in comparison to the `#top-layer` and it does an irritating "snap" and jumps 300 pixels. You can see it here: digitalshowcase.somethingbigdev.co.uk/#contact - when the mouse is centred to the screen the top-layer shows around 0.5px each way. But bottom-layer shows around 250px each way! The values for the offset are 0.1 and 0.3 so it shouldn't jump – Francesca Jun 12 '15 at 09:21
  • It also didn't do that on my test version. I can't work out why bottom-layer is jumping so much? digitalshowcase.somethingbigdev.co.uk/cats-test.html – Francesca Jun 12 '15 at 09:21
  • Here is an example to show the extreme difference. bottom offset is 0.1. top offset is 0.3. Mouse is almost centred in the page. Top layer shows reasonable offset. Bottom layer shows massive offset: http://i.imgur.com/wsPGR5o.png – Francesca Jun 12 '15 at 09:36
  • I'm viewing your contact link in Chrome and it appears to be working nicely (it looks to be nice anyway) except when the mouse is over the form. The mousemove event isn't being triggered. It starts firing again once the mouse leaves that form rectangle and because of the gap on where it last fired and where the mouse now is, it results in a "jump". If it were me I wouldn't have the mousemove on every element with the .para class, but rather one element that covers the entire area you want the parallax to happen. That will end up with better performance at least. – Josh Bilderback Jun 12 '15 at 21:13
  • @JoshBilderback Could you explain for me the way you find x and y in parallax function please? why do we have with window width and offsetwidth and all that stuff. I'm confused. – Huy Le Feb 21 '17 at 10:33
  • @HuyLe To center an element horitonally, you set its X offset to half of the windows width (center of page) minus half of the element's width. From that you need to add or subtract depending on where the mouse is. How much you subtract or add is weighted by a value (mine is called layer_coeff). The elements closer to the user have a bigger effect when the mouse moves. Just apply this method to both X and Y and you get a simple parallax – Josh Bilderback Mar 17 '17 at 15:21