简体   繁体   中英

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);
});

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/

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM