patternjavascriptMinor
Responsive horizontal scroll on mouse position
Viewed 0 times
scrollpositionresponsivehorizontalmouse
Problem
I am making a responsive horizontal scroll UI. The horizontal scroll position is calculated according to the mouse horizontal position:
This works pretty well in the browsers I tested. And other than general performance enhancement I am concerned about this issue:
When the mouse comes out of the window and back in, the images snap to the new position. I tried to make that snap smoother with
$(document).ready(function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth,
$images = $('#imgs');
$(window).on('resize', function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth;
})
$(document).on('mousemove', function(e) {
var mouseX = e.pageX,
percentMouse = mouseX * 100 / docWidth,
offset = percentMouse / 100 slidesWidth - percentMouse / 200 docWidth;
$images.css({
'-webkit-transform': 'translate3d(' + -offset + 'px,0,0)',
'transform': 'translate3d(' + -offset + 'px,0,0)'
});
});
})
body,html {
margin: 0;
overflow: hidden;
height: 100%;
}
#imgs {
position: absolute;
top: 0; left: 0;
width: 150%; height: 100%;
display: flex;
justify-content: space-around;
align-items: center;
margin: 0 25%;
/ transition: transform .1s; /
}
#imgs > div {
max-width: 9%;
perspective: 500px;
z-index: 1;
}
#imgs img {
display: block;
max-width: 100%;
height: auto;
}
This works pretty well in the browsers I tested. And other than general performance enhancement I am concerned about this issue:
When the mouse comes out of the window and back in, the images snap to the new position. I tried to make that snap smoother with
transition:transform .1s on the #imgs element (commented out in the CSS) but:- in chrome, it is a little janky
- in Firefox and edge it is very janky even on small mouse moves
Solution
Your project is looking great! But I have a few thoughts on how to improve the clarity of your javascript code:
Unused code
Your
Or just remove it to prevent confusion if the widths aren't affected by resizing.
You also don't end up using
More straightforward calculation
I think you could simplify the way you calculate the offset in your
This way you don't multiply by 100 and then divide by it right after, and you also have fewer variables to worry about.
Unnecessary functionality
You don't use the 3d aspect of translate so why not just use the 2d version:
More concise and direct jquery syntax
Another option would be to use jquery's built in methods for creating events instead of using
Once again, great work so far! I wish I could have helped more with the snapping issue. I have a few ideas--
Unused code
Your
window.resize handler doesn't end up doing anything. Functions create a new scope for variables, so since you're redeclaring docWidth and slidesWidth with var, you don't actually affect the initially declared variables. The reason why all your code still works is that the body's width and the slide's width don't actually change when the window is resized. I'm not sure if this is different on mobile or even why the widths aren't changing (maybe it has something to do with your css) but you ought to either change the handler to something like:$(window).on('resize', function() {
docWidth = $('body').width();
slidesWidth = $images.width(); // stay consistent with this variable
rangeX = slidesWidth - docWidth;
})Or just remove it to prevent confusion if the widths aren't affected by resizing.
You also don't end up using
rangeX in your code. Consider removing it.More straightforward calculation
I think you could simplify the way you calculate the offset in your
document.mousemove handler by eliminating the mousePercent variable:$(document).on('mousemove', function(e) {
var mouseX = e.pageX,
offset = mouseX / docWidth * slidesWidth - mouseX / 2;
$images.css({
'-webkit-transform': 'translate3d(' + -offset + 'px,0,0)',
'transform': 'translate3d(' + -offset + 'px,0,0)'
});
});This way you don't multiply by 100 and then divide by it right after, and you also have fewer variables to worry about.
Unnecessary functionality
You don't use the 3d aspect of translate so why not just use the 2d version:
$images.css({
'-o-transform': 'translate(' + -offset + 'px, 0)', // opera 11.5
'-ms-transform': 'translate(' + -offset + 'px, 0)', // IE9
'-moz-transform': 'translate(' + -offset + 'px, 0)', // firefox 3.5-15
'-webkit-transform': 'translate(' + -offset + 'px, 0)',
'transform': 'translate(' + -offset + 'px,0)'
});More concise and direct jquery syntax
Another option would be to use jquery's built in methods for creating events instead of using
on:$(document).ready(function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth,
$images = $('#imgs');
$(window).resize(function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth;
})
$(document).mousemove(function(e) {
var mouseX = e.pageX,
percentMouse = mouseX * 100 / docWidth,
offset = percentMouse / 100 * slidesWidth - percentMouse / 200 * docWidth;
$images.css({
'-webkit-transform': 'translate3d(' + -offset + 'px,0,0)',
'transform': 'translate3d(' + -offset + 'px,0,0)'
});
});
});Once again, great work so far! I wish I could have helped more with the snapping issue. I have a few ideas--
mouseenter, jquery.stop().animate()--but none that are fully developed. Good luck figuring it out!Code Snippets
$(window).on('resize', function() {
docWidth = $('body').width();
slidesWidth = $images.width(); // stay consistent with this variable
rangeX = slidesWidth - docWidth;
})$(document).on('mousemove', function(e) {
var mouseX = e.pageX,
offset = mouseX / docWidth * slidesWidth - mouseX / 2;
$images.css({
'-webkit-transform': 'translate3d(' + -offset + 'px,0,0)',
'transform': 'translate3d(' + -offset + 'px,0,0)'
});
});$images.css({
'-o-transform': 'translate(' + -offset + 'px, 0)', // opera 11.5
'-ms-transform': 'translate(' + -offset + 'px, 0)', // IE9
'-moz-transform': 'translate(' + -offset + 'px, 0)', // firefox 3.5-15
'-webkit-transform': 'translate(' + -offset + 'px, 0)',
'transform': 'translate(' + -offset + 'px,0)'
});$(document).ready(function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth,
$images = $('#imgs');
$(window).resize(function() {
var docWidth = $('body').width(),
slidesWidth = $('#imgs').width(),
rangeX = slidesWidth - docWidth;
})
$(document).mousemove(function(e) {
var mouseX = e.pageX,
percentMouse = mouseX * 100 / docWidth,
offset = percentMouse / 100 * slidesWidth - percentMouse / 200 * docWidth;
$images.css({
'-webkit-transform': 'translate3d(' + -offset + 'px,0,0)',
'transform': 'translate3d(' + -offset + 'px,0,0)'
});
});
});Context
StackExchange Code Review Q#128834, answer score: 4
Revisions (0)
No revisions yet.