0

I'm hoping to have the page scroll up to a certain point, and gradually slow as it approaches that point.

I'd like to use the top answer to this question below (code included), though I don't think a simple factor would have the same decelerating effect I'm trying to achieve: Changing the interval of SetInterval while it's running

function setDeceleratingTimeout( callback, factor, times )
{
  var internalCallback = function( t, counter )
  {
    return function()
    {
      if ( --t > 0 )
      {
        window.setTimeout( internalCallback, ++counter * factor );
        callback();
      }
    }
  }( times, 0 );

  window.setTimeout( internalCallback, factor );
};

Here's the string of functions that I've got working on my site, though it doesn't work in jsfiddle.com, I'm assuming because it's not being triggered by a page load:

function Scroll_01()
{
    window.scrollTo(0,100)
    setTimeout('Scroll_02()',25)
}
function Scroll_02()
{
    window.scrollTo(0,136)
    setTimeout('Scroll_03()',25)
}
function Scroll_03()
{
    window.scrollTo(0,169)
    setTimeout('Scroll_04()',25)
}
function Scroll_04()
{
    window.scrollTo(0,188)
    setTimeout('Scroll_05()',25)
}
function Scroll_05()
{
    window.scrollTo(0,207)
    setTimeout('Scroll_06()',25)
}
function Scroll_06()
{
    window.scrollTo(0,221)
    setTimeout('Scroll_07()',25)
}
function Scroll_07()
{
    window.scrollTo(0,235)
    setTimeout('Scroll_08()',25)
}
function Scroll_08()
{
    window.scrollTo(0,245)
    setTimeout('Scroll_09()',25)
}
function Scroll_09()
{
    window.scrollTo(0,255)
    setTimeout('Scroll_10()',25)
}
function Scroll_10()
{
    window.scrollTo(0,262)
    setTimeout('Scroll_11()',25)
}
function Scroll_11()
{
    window.scrollTo(0,270)
    setTimeout('Scroll_12()',25)
}
function Scroll_12()
{
    window.scrollTo(0,277)
    setTimeout('Scroll_13()',25)
}
function Scroll_13()
{
    window.scrollTo(0,285)
    setTimeout('Scroll_14()',25)
}
function Scroll_14()
{
    window.scrollTo(0,288)
    setTimeout('Scroll_15()',25)
}
function Scroll_15()
{
    window.scrollTo(0,292)
    setTimeout('Scroll_16()',25)
}
function Scroll_16()
{
    window.scrollTo(0,294)
    setTimeout('Scroll_17()',25)
}
function Scroll_17()
{
    window.scrollTo(0,296)
    setTimeout('Scroll_18()',25)
}
function Scroll_18()
{
    window.scrollTo(0,298)
    setTimeout('Scroll_19()',25)
}
function Scroll_19()
{
    window.scrollTo(0,300)
}

http://jsfiddle.net/8S3CL/

I came up with the scrollTo Y access numbers by plotting them on a chart, with values from 100-300 trying to achieve a smooth curve, which has worked out well, but is obviously not pretty code.

Would anyone know what JavaScript code and equation might work to replace the 19 daisy-chained functions?

Community
  • 1
  • 1

1 Answers1

0

Your can achieve your goal with a recursive call using setTimeout, adjusting your scroll step according to the distance between current and target positions.

I have created a fiddle to demonstrate it here.

Key parts are recursive call:

function smoothScrollTo(targetY, step, intervalMs) {
    ...
    setTimeout(function() { smoothScrollTo(targetY, step, intervalMs); }, intervalMs); 
}

And calculating the scroll step:

var sgn = Math.sign(targetY-currentY);
var distance = Math.abs(currentY-targetY);
var step1 = (distance < 100) ? Math.max(step*distance/50,1) : step;
window.scrollTo(0, currentY+sgn*step1);

You should refine this method though to count with some issues:

  1. Validate the given target position.
  2. Introduce an optional callback which would be called when scrolling has reached its target.
  3. What if user scrolls during this smooth scrolling? With the current approach, the javascript will not stop, and will want to scroll to its target even if user scrolls away during.
Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93
  • Thanks, I love the code example, though I figured I'd need to use sign, I'm not quite getting how this all works or goes together. I tried the code by calling it like this: onload="smoothScrollTo(300, 20, 25);", jump to 300px, in 20 steps, with an interval of 25ms each. I added the four calculation lines of code into the function where the three dots are, which didn't scroll the page, what do you think I'm doing wrong? – user3092711 Mar 26 '14 at 20:04
  • Check out the jsfiddle link I provided before the code snippets. There you have the full code which you can test there, probably you've missed that. By the way "step" refers to the pixels which the scrolling jump with each cycle, not the total cycle count. – Zoltán Tamási Mar 26 '14 at 20:40