Your code isn't functioning as expected because each time the scroll event is triggered, the image position animation occurs. However, this animation takes 10 milliseconds to complete, and because you specify an increment or decrement based on the current position, the position will be calculated wrongly and eventually break.
Here's a revised version of the code:
var delta = 2; // define the desired delta
var initialImgScrollTop = $("img").offset().top; // get the current top position of the image
var initialImgScrollLeft = $("img").offset().left;
$("#div1").scroll(function (event) {
var st = $(this).scrollTop();
$("img").animate({ top: initialImgScrollTop - st * delta }, 10); // compute the correct position for the image
});
var scrollHeight = $('#div2').prop('scrollHeight') - $('#div2').innerHeight(); // obtain the scroll height
var initialMiddleScroll = scrollHeight / 2; // calculate the middle scroll
$("#div2").scrollTop(initialMiddleScroll); // set the scroll to the middle for left and right movement
$("#div2").scroll(function (event) {
var st = $(this).scrollTop();
$("img").animate({ left: initialImgScrollLeft + (st - initialMiddleScroll) * delta }, 10); // compute the correct position for the image
});
div {
width: 150px;
height:150px;
overflow: scroll;
display: inline-block;
}
img {
position: absolute;
top:400px;
left:150px;
width:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1">This is just some stupid text unworthy of being read, so please don't waste
<br>your time reading this nonesense.
<br>Hey! why are you still reading this garbage?
<br>Stop reading now and start doing something useful, such as getting this leaf to move up
<br>while you scroll this page.
<br>On second thought, maybe just continue reading.
<br>This might be more productive then whatever
<br>it is you were doing before.</div>
<div id="div2">This is just some stupid text unworthy of being read, so please don't waste
<br>your time reading this nonesense.
<br>Hey! why are you still reading this garbage?
<br>Stop reading now and start doing something useful, such as getting this leaf to move up
<br>while you scroll this page.
<br>On second thought, maybe just continue reading.
<br>This might be more productive then whatever
<br>it is you were doing before.</div>
<img src="http://sweetclipart.com/multisite/sweetclipart/files/imagecache/middle/nature_seasons_spring_leaf_green.png">
-----UPDATE-----
To elaborate on what goes wrong in your code:
- You scroll down
- The final scroll position is computed at 10px (incrementing from 10 to 10)
- The scroll triggers the animation
- The animation starts
- The scroll position moves from 0px to 10px
- The animation ends
- You scroll down again, repeating...
This scenario works, but in many cases, you will scroll multiple times during the animation:
- You scroll down
- The final scroll position 1 is computed to be 10px
- The scroll triggers animation 1
- Animation 1 begins
- The scroll position moves from 0px to 3px
- You scroll down again
- The final scroll position 2 is computed at 13px (3 + 10)
- Animation 2 begins
- The scroll position moves from 3px to 10px (the final position of animation 1)
- Animation 1 ends
- The scroll position moves from 10px to 13px (the final position of animation 2)
- Animation 2 ends
After two scroll events, you have 13px as the scroll position instead of the expected 20px.
The solution is not to rely on relative positioning values but on absolute positioning values (based on the div scroll rather than the previous image position).
If you need further clarification, feel free to ask.
PS: I've updated the code snippet to demonstrate how you can handle the left-right animation.