Adjust the scrolling speed when scrolling by dragging - javascript

I have a page on a website i am working on, that includes many images in a div in a grid (map). I made the div show a scroll bar at overflow and used jquery to enable scrolling via dragging and it works as intented with only a hundred or so showing at a time.
My only issue is, that since there are thousands of small images, moving the mouse only a bit will already result in blowing past a lot of objects.
My question now is, how can i modify my code, so that moving the mouse over the screen once will only scroll about one tenth of the div's width. So basically i want to reduce the scrolling speed.
I am super new to javascript etc. so please be patient.
<div id="map" class="center unselectable overflow">
lots of images here in a grid</div>
<script>
var clicked = false, clickY, clickX;
var map = document.getElementById('map');
$(document).on({
'mousemove': function(e) {
clicked && updateScrollPos(e);
},
'mousedown': function(e) {
clicked = true;
clickY = e.pageY;
clickX = e.pageX;
},
'mouseup': function() {
clicked = false;
$('html').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$('html').css('cursor', 'row-resize');
$(map).scrollTop($(map).scrollTop() + (clickY - e.pageY));
$(map).scrollLeft($(map).scrollLeft() + (clickX - e.pageX));
}
</script>
TLDR: how to I reduce the drag to scroll speed in jQuery?

A little more elabouration from my comment: it seems like you are trying to dampen the scrolling speed. Mathematically, this means all you need is to reduce the value you feed to the .scrollTop() and .scrollLeft() functions. This can be done by dividing them by a set, arbitrarily determined factor, so that the transformation is linear. An example will be, if you want to dampen your scrolling speed by a factor of 10×, then you simply divide the values by 10:
var updateScrollPos = function(e) {
var scrollTop = $(map).scrollTop() + (clickY - e.pageY);
var scrollLeft = $(map).scrollLeft() + (clickX - e.pageX);
$('html').css('cursor', 'row-resize');
$(map).scrollTop(scrollTop / 10);
$(map).scrollLeft(scrollLeft / 10);
}
Pro-tip: since you are accessing $(map) several times, you can (micro)optimize your code by caching it:
var updateScrollPos = function(e) {
var $map = $(map);
var scrollTop = $map.scrollTop() + (clickY - e.pageY);
var scrollLeft = $map.scrollLeft() + (clickX - e.pageX);
$('html').css('cursor', 'row-resize');
$map.scrollTop(scrollTop / 10);
$map.scrollLeft(scrollLeft / 10);
}

Related

How do I animate opacity change inside a waypoint function based on scroll position?

I am working on a project, here: https://github.com/erinreiss/spaceship1/tree/ministory1
And I am looking to make a div#landing to go from opacity:1 to opacity:0 within 200 pixels of scrolling, based on scroll position. I was able to do it successfully like this:
var target = $('#landing');
var targetHeight = 200;
$(document).scroll(function(e){
var scrollPercent = (targetHeight - window.scrollY) / targetHeight;
if(scrollPercent >= 0){
target.css('opacity', scrollPercent);
}
});
Now, I want to use waypoints to trigger this same effect but at a different time. I want instead of it firing as the div#landing moves out of the viewport, it instead fires as a defined Waypoint (in this case, a different div#intro1) is scrolled past.
This is my attempt:
var target = $('#landing');
var targetHeight = 200;
var intro1 = $('#intro1').waypoint(function (direction) {
console.log('bam!');
$(document).scroll(function(e){
var scrollPercent = (targetHeight - window.scrollY) / targetHeight;
if(scrollPercent >= 0){
target.css('opacity', scrollPercent);
}
})
}, {offset: 200});
The waypoint fires, but (alas) the scrolling opacity changer does not work...
Any advice? Thank you!!
ps - The other thread with this question is answered with code no longer available :(
How do I animate on scroll inside a waypoint function?
I didn't solve this problem, but I did hack something together close to what I wanted... It allows me to use the scroll position of an overflow element to trigger and define the level of opacity on another element.
See solution here:
https://github.com/erinreiss/spaceship1/tree/ministory1
var target = $('#intro1inner');
$('#intro1inner').scroll(function(){
//define a variable that will be how much the target has scrolled from its original position
var changeA = target.scrollTop()
console.log('changeA:' + changeA)
// I want my change in opacity (from 0-1 to take place over 250px)
var scrollPercent = changeA / 250;
console.log('scrollPercent:' + scrollPercent)
});

Super Smooth Scrolling

I've been trying to create smooth scrolling and trying to get it as smooth as http://lookbook.quechua.com/spring-summer-2016/en/hiking when you scroll down through the products but finding it hard to replicate / find anything else that could help.
At the minute Im using TweenMax and the Scroll To Plugin however this acts differently in Firefox and Chrome and it scrolls a set distance which I really don't want to have to do instead of it feeling like the user has full control of the distance.
What would the best way to replicate this be or how to get the page to scroll that smooth?
Demo
var $window = $(window);
var scrollTime = 1.2;
var scrollDistance = 135;
$window.on("mousewheel DOMMouseScroll", function(event){
event.preventDefault();
var delta = event.originalEvent.wheelDelta/40 || -event.originalEvent.detail/3
var scrollTop = $window.scrollTop();
var finalScroll = scrollTop - parseInt(delta*scrollDistance);
TweenMax.to($window, scrollTime, {
scrollTo : { y: finalScroll, autoKill:true },
ease: Power1.easeOut, // Quart.easeInOut
overwrite: 5
});
});

Scroll On Mouse Hover

I'm an interface designer new to development, and I've run into a snag with a side project I'm working on. I'd like to create a long, horizontally-scolling parallax scene. Users can use their mousewheel to scroll the view horizontally. (I'm currently using this JQuery plugin to help me accomplish this: http://www.pixxelfactory.net/jInvertScroll/)
Additionally, I'd like to ability for users to hover over a 20px gap on the left or right edge of their browser window to scroll the view in that direction for as long as they hover there. (As a reference, this interaction is based on a lot of MOBA games like LoL, Dota 2, or HOTS, where users can hold their cursors over an edge of the screen to pan around the map.)
I've found a sample script (shown below), but it doesn't accomplish exactly what I'm trying to do. In this example, the screen is divided in half vertically, and hovering in the top or bottom section scrolls the view up or down. As I mentioned above, I only want a 20px wide by 100% height of the screen area which a user can hover to scroll their view.
My current source:
$(document).mousemove(function(e) {
$("html, body").scrollTop(function(i, v) {
var h = $(window).height();
var y = e.clientY - h / 2;
return v + y * 0.1;
});
});
Any suggestions would be amazing!
First make 2 divs, one for the left and one for the right. Set their position to fixed in CSS and make them scroll the page while hovering over them.
This is what my JS test code looks like:
var offset = 0;
$(document).ready(function(){
$('.left').bind('mouseenter', function() {
var self = $(this);
this.iid = setInterval(function() {
offset += 300;
$('html, body').animate({
scrollTop: offset
}, 1);
}, 10);
}).bind('mouseleave', function(){
this.iid && clearInterval(this.iid);
});
$('.right').bind('mouseenter', function() {
var self = $(this);
this.iid = setInterval(function() {
offset -= 300;
$('html, body').animate({
scrollTop: offset
}, 1);
}, 10);
}).bind('mouseleave', function(){
this.iid && clearInterval(this.iid);
});
});
Here is the full example:
https://jsfiddle.net/h596y5rs/1/

Covering the first element or block of the page when scrolling downwards

I wanted to achieve an effect like this http://www.offset.com/
as you can see when it scrolls it slowly covering the carousel rather than scrolling with it.
I've tried using background fixed but the problem is the elements inside it will not stay in its position
Maybe there is a good technique in achieving this, Thanks
this is called parallax scrolling here is an example of how to do this using Jquery :
Live Demo
// Y axis scroll speed
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.container').each(function() {
var $element = $(this);
// subtract some from the height b/c of the padding
var height = $element.height()-18;
$(this).css('backgroundPosition', '50% ' + Math.round((height - pos) * velocity) + 'px');
});
};
$(window).bind('scroll', update);
an other example it might help DEMO

synchronising two divs scroll is not smooth in iOS

--> Please goto Edit part of this Question
I want to synchronise scroll bar of two divs and this is how I am doing it
var div1 = document.getElementById('element1'),
div2 = document.getElementById('element2');
div1.addEventListener('touchmove', scrolled, false);
div2.addEventListener('touchmove', scrolled, false);
function getscrollTop(node) {
return node.pageYOffset || node.scrollTop;
}
function scrolled() {
var node = this, scrollTop = getscrollTop(node);
var percentage = scrollTop / (node.scrollHeight - node.clientHeight);
var other = document.getElementById({
"element1": "element2",
"element2": "element1"
}[node.id]);
other.scrollTop = percentage * (other.scrollHeight - other.clientHeight);
};
Fiddle -> used scroll instead touchmove
But the problem is it is flickering in low end devices and would like to make it smooth in event low end devices.
Edit
I have used below code to smoothen the scrolling
var children = document.querySelectorAll('.scrolldiv');
var getscrollTop = function(node) {
return node.pageYOffset || node.scrollTop;
}, toInt = function(n) {
return Math.round(Number(n));
};
window.setInterval(function() {
var scrollTop = getscrollTop(children[0]);
var percentage = scrollTop / (children[0].scrollHeight - children[0].clientHeight);
var oscrollTop = percentage * (children[1].scrollHeight - children[1].clientHeight);
// console.log(1);
children[1].scrollTop = toInt(oscrollTop);
}, 2);
It is smoother in Desktop browsers but in iOS browser, when setting second DIv's scroll it is jerking, jerking in the sense setting scrollTop once scrolling is completed, not while scrolling.
If you round your scroll value numbers to integers then this problem goes away :
http://jsfiddle.net/2Cj4S/15/
I just used a rounding function :
function toInt(n){ return Math.round(Number(n)); };
and this seems to have fixed it. Double values really confused GUI widgets like scrollbars, and 2D drawing.
I don't see why you have to calculate a new percentage here, value which you hand over to the second scroll.. that's probably the reason for the jerking.. instead you could simply take the scroll value from the first scroll and assign it directly to the other scroll.. This will remove the jerky-ness in the other scroll.. and synchronising them..
I just added the following line to the bottom of your scrolled function..
other.scrollTop = getscrollTop(node);
The modified function:-
function scrolled() {
var node = this,
scrollTop = getscrollTop(node);
var id = node.id;
var percentage = getscrollTop(node) / (node.scrollHeight - node.clientHeight);
var other = document.getElementById({
"element1": "element2",
"element2": "element1"
}[id]);
var oscrollTop = percentage * (other.scrollHeight - other.clientHeight)
//other.scrollTop = oscrollTop;
//Please note that I have commented out the above line.. and added the following line
other.scrollTop = getscrollTop(node);
};
I hope this the behaviour you were hoping for, i tested it out on jsfiddle, both scrolls are well synchronised.

Categories