Moving arrow

Animated mouse-over arrow that moves up and down once, then stays up until mouse-out

by doug65536

HTML

<div class="goup">/\</div><br>

<label><input type="checkbox" id="logenabled" checked/>Log Enabled</label>
<div id="log"></div>

CSS

.goup {
    margin-top: 16px;
    position: relative;
    padding: 32px;
    border: solid black 1px;
    border-radius: 8px;
    display: inline-block;
    /*
    -moz-transition:all 0.25s ease;
    -webkit-transition:all 0.25s ease;
    -o-transition:all 0.25s ease;
    transition:all 0.25s ease;
    */
}
.goup:hover {
    background-color: #ddd;
}
input {
    margin-top: 16px;
}

JavaScript

$(function () {
    var log = $('#log');
    
    var logenabled = !!$('#logenabled').is(':checked');
    
    $('#logenabled').on('click', function() {
        logenabled = !!$('#logenabled').is(':checked');
    });
    
    var animating = false;
    var moused_over = false;
    var distance = 20;
    var goup = $('.goup');
    
    var set_css = function(item, settings) {
        item.animate(settings, { queue: true, duration: 250 });
        
        if (logenabled) {
            for (var i in settings) {
                log.append($("<p>").text(i + ": " + settings[i]));
            }
        }
    };

    var defer_css = function (item, settings) {
        return function () {
            set_css(item, settings);
        };
    };

    var last_anim = function () {
        set_css(goup, {
            top: 0 + 'px'
        });
        setTimeout(function () {
            animating = false;
        }, 250);
    };

    var final_tick = function () {
        if (!moused_over) {
            last_anim();
        } else {
            animating = false;
        }
    };

    var goup_hover_start = function () {
        var i, base;
        moused_over = true;
        if (!animating) {
            log.empty();
            animating = true;
            setTimeout(defer_css(goup, {
                top: -distance + 'px'
            }), 0);
            setTimeout(defer_css(goup, {
                top: 0 + 'px'
            }), 250);
            setTimeout(defer_css(goup, {
                top: -distance + 'px'
            }), 500);
            setTimeout(final_tick, 750);
        }
    };

    var goup_hover_stop = function () {
        moused_over = false;
        if (!animating) {
            last_anim();
        }
    };

    goup.hover(goup_hover_start, goup_hover_stop);
});