The current code in question translates the element by an absolute number of pixels, which may result in a space between the mouse pointer and the actual position of the image if the element is already positioned at an offset from (0,0) of the document due to extra elements or margins/paddings.
To address this issue, it's important to first determine the original position of the element and then calculate the translation values relative to that position. Below is a snippet demonstrating this:
-
$(document).ready(function() {
var image = $('li').find('.image-container');
var position = image.offset();
$(document).mousemove(function(e) {
image.css({
transform: 'translateX(' + (e.pageX - position.left) + 'px) translateY(' + (e.pageY - position.top) + 'px)'
})
});
})
ul {
list-style-type: none;
}
img {
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<img class='image-container' src='http://lorempixel.com/200/200/nature/1' />
</li>
</ul>
The use of vertical-align:top;
on the img
tag is crucial in the above code snippet because by default it is set to baseline
. This setting affects the positioning in relation to the baseline rather than the actual top of the image itself.
In terms of browser compatibility, the problem mentioned earlier seems to be specific to Chrome only.
A working demo showcasing the proper functionality even when there are additional elements in the DOM preceding the image can be seen below:
-
$(window).load(function() {
var image = $('li').find('.image-container');
var position = image.offset();
$(document).mousemove(function(e) {
image.css({
transform: 'translateX(' + (e.pageX - position.left) + 'px) translateY(' + (e.pageY - position.top) + 'px)'
})
});
})
ul {
list-style-type: none;
}
img {
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Some content before the image</div>
<p>Some other content before the image</p>
<ul>
<li>
<img class='image-container' src='http://lorempixel.com/200/200/nature/1' />
</li>
</ul>
It's worth noting that when dealing with multiple images prior to the current element, calculating offsets after those images are fully loaded ensures accurate positioning based on the actual image height rather than just the line height of the element.
The corrected version considering image loading timing is displayed below:
-
$(window).load(function() {
var image = $('li').find('.image-container');
var position = image.position();
$(document).mousemove(function(e) {
image.css({
transform: 'translateX(' + (e.pageX - position.left) + 'px) translateY(' + (e.pageY - position.top) + 'px)'
})
});
})
ul {
list-style-type: none;
}
img {
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Some content before the image</div>
<p>Some other content before the image</p>
<img src='http://lorempixel.com/100/100/nature/1' />
<ul>
<li>
<img class='image-container' src='http://lorempixel.com/200/200/nature/1' />
</li>
</ul>
All code snippets have been tested for compatibility across various browsers including Chrome, Opera, Firefox, IE, and Edge.