13

I've created an app that is a set size (around 2,000 px tall) and have a menu that calls FB.Canvas.scrollTo in order to help the user navigate the long page.

Is there any way to add a smooth scrolling effect? Facebook does not offer any solution on its developer blog.

ifaour
  • 38,035
  • 12
  • 72
  • 79
Carson
  • 4,541
  • 9
  • 39
  • 45

4 Answers4

47

Using @Jonny's method, you can do this a little more simply with

function scrollTo(y){
    FB.Canvas.getPageInfo(function(pageInfo){
            $({y: pageInfo.scrollTop}).animate(
                {y: y},
                {duration: 1000, step: function(offset){
                    FB.Canvas.scrollTo(0, offset);
                }
            });
    });
}
sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Dave
  • 11,499
  • 5
  • 34
  • 46
  • $ is most probably jQuery. Use $('#button_id').click(function() { FB.Canvas.scrollTo(0,0); }); – Milan Babuškov Jun 17 '12 at 14:48
  • 1
    Little confusing with using "y" as both your function param and the built-in param for jQuery's "animate" but it does work. Huzzah! – Brade Jun 14 '13 at 16:03
5

Just had the same problem today - I came up with a little bit of javascript which makes use of jQuery's animate method which provides some easing - the scroll is still a touch jerky (I'm guessing that's because of the FB.Canvas.scrollTo proxy). Anyway, here's the snippet:

function scrollToTop() {
    // We must call getPageInfo() async otherwise we will get stale data.
    FB.Canvas.getPageInfo(function (pageInfo) { 

        // The scroll position of your app's iFrame.
        var iFrameScrollY = pageInfo.scrollTop;

        // The y position of the div you want to scroll up to.
        var targetDivY = $('#targetDiv').position().top;

        // Only scroll if the user has scrolled the window beneath the target y position.
        if (iFrameScrollY > targetDivY) {
            var animOptions = {

                // This function will be invoked each 'tick' of the animation.
                step: function () {
                    // As we don't have control over the Facebook iFrame we have to ask the Facebook JS API to 
                    // perform the scroll for us.
                    FB.Canvas.scrollTo(0, this.y);
                },

                // How long you want the animation to last in ms.
                duration: 200
            };

            // Here we are going to animate the 'y' property of the object from the 'iFrameScrollY' (the current 
            // scroll position) to the y position of your target div.
            $({ y: iFrameScrollY }).animate({ y: targetDivY }, animOptions);
        }
    });
}
sakibmoon
  • 2,026
  • 3
  • 22
  • 32
JonnyReeves
  • 6,119
  • 2
  • 26
  • 28
2

I just used Francis' technique and implemented a jQuery version

$('html,body').animate(
  {scrollTop: $(".scroll_to_me").offset().top}, 
  {duration: 1000, step: function(top_offset){
    FB.Canvas.scrollTo(0, top_offset + 30);
  }
});

You need to replace the .scroll_to_me with the selector you want to scroll to. Also I added in the + 30 to the offset as the iframe doesn't start at the top of the page, you may want to tweak this.

sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Paul Mason
  • 1,818
  • 2
  • 20
  • 32
  • Hm. When I implement that it jumps to the top of the page, then scrolls down. In my case the user will not always be at the top of the page when clicking the buttons, so the jumping before the smooth scroll wouldn't quite work. – Carson Oct 25 '11 at 14:58
0

One way of doing it is by getting the current Y position, then getting the to Y position. Run a for loop with a setTimeout that will bring the user to the final Y position.

Francis Pelland
  • 784
  • 4
  • 11