user2298943
user2298943

Reputation: 632

Javascript animate on scroll position

I am trying to get a scrolling animation like here (notice the circle figure fading in when you scroll down): http://demo.atticthemes.com/skoty/

This is what I have sofar, but it keeps hanging somehow: http://jsfiddle.net/v4zjgwL6/

var timer;
var triggerHeight = $("#bar").offset().top;
var headerAvatar = $(".header-avatar-wrapper");

$(window).scroll(function() {
    if(timer) {
        window.clearTimeout(timer);
    }

    timer = window.setTimeout(function() {
        var y = $(window).scrollTop();

        if(y > triggerHeight - 220) {
            headerAvatar.css("visibility", "visible");
            headerAvatar.animate({opacity: 1}, 200);
        } else {
            headerAvatar.animate({opacity: 0}, 200);
            headerAvatar.css("visibility", "hidden");
        }

    }, 10);
});

Upvotes: 1

Views: 99

Answers (2)

Praxis Ashelin
Praxis Ashelin

Reputation: 5227

You don't need to use a timer, the way you have implemented it causes performance drops.
I would suggest to use css classes instead:

var triggerHeight = $("#bar").offset().top;
var headerAvatar = $(".header-avatar-wrapper");

$(window).scroll(function() {
    var y = $(window).scrollTop();

    if (y > triggerHeight - 220 && !headerAvatar.hasClass("visible")) {
        headerAvatar.addClass("visible");
    } else if(y <= triggerHeight - 220 && headerAvatar.hasClass("visible")) {
        headerAvatar.removeClass("visible");
    }
});

I have also added this class in CSS:

.header-avatar-wrapper.visible{
    opacity: 1;
    visibility: visible;
}

JSFiddle demo


Or alternatively, use jQuery's .fadeIn() and fadeOut() functions:

var triggerHeight = $("#bar").offset().top;
var headerAvatar = $(".header-avatar-wrapper");

$(window).scroll(function() {
    var y = $(window).scrollTop();

    if (y > triggerHeight - 220 && headerAvatar.css("display") == "none") {
        headerAvatar.fadeIn();
    } else if(y <= triggerHeight - 220 && headerAvatar.css("display") == "block") {
        headerAvatar.fadeOut();
    }
});

In CSS I removed the opacity and visibility properties from .header-avatar-wrapper and added display: none; instead.

JSFiddle demo

Upvotes: 2

bvaughn
bvaughn

Reputation: 13497

Looks like you're only handling the cases where you need to change state (shown or hide the element) and not the cases where nothing should change. This causes you to continuously re-show (re-animate) the thing, which makes it flicker.

It's early and I have not yet had coffee, but something like this should fix you up. :)

var timer;
var triggerHeight = $("#bar").offset().top;
var headerAvatar = $(".header-avatar-wrapper");
var shown; // NEW

$(window).scroll(function() {
    if(timer) {
        window.clearTimeout(timer);
    }

    timer = window.setTimeout(function() {
        var y = $(window).scrollTop();
        var shouldShow = y > triggerHeight - 220; // CHANGED

        if(!shown && shouldShow) { // CHANGED
            shown = true; // NEW
            headerAvatar.css("visibility", "visible");
            headerAvatar.animate({opacity: 1}, 200);
        } else if (shown && !shouldShow) { // CHANGED
            shown = false; // NEW
            headerAvatar.animate({opacity: 0}, 200);
            headerAvatar.css("visibility", "hidden");
        }

    }, 10); });

Proof: http://jsfiddle.net/bvaughn/oL85oj41/

Upvotes: 2

Related Questions