Chris
Chris

Reputation: 59551

jQuery - pause animation

My website has a news section in the format of squares that animate alot like the Metro UI. The square animates once every 5-10 seconds (random) and swaps between the text and picture.

FIDDLE

I now want the animation to immediately switch to the text-stage when the user mouse-overs, and remain there until mouse-out. When the user mouse-outs the animation can either resume with any delay that's left from before the mouse-in, or instantly switch to the picture-stage. I prefer the first, but any solution works.

I tried doing something with .hover but I'm not sure how to best pause/resume animations. Cheers.

HTML

<div class="news-container">
    <div>
        <div class="news-window">
            <div class="date"><span>05</span><div>Sep</div></div>
            <div class="news-tile" id="1">
                <div class="news-pic" style="background-image:url('https://pbs.twimg.com/profile_images/378800000532546226/dbe5f0727b69487016ffd67a6689e75a.jpeg');"></div>
                <div class="news-title"><div>News Title</div></div>
            </div>
        </div>
        <div class="news-window">
            <div class="date"><span>28</span><div>Aug</div></div>
            <div class="news-tile" id="2">
                <div class="news-pic" style="background-image:url('https://www.petfinder.com/wp-content/uploads/2012/11/155293403-cat-adoption-checklist-632x475-e1354290788940.jpg');"></div>
                <div class="news-title"><div>News Title</div></div>
            </div>                          
        </div>
        <div class="news-window">
            <div class="date"><span>17</span><div>Aug</div></div>
            <div class="news-tile" id="3">
                <div class="news-pic" style="background-image:url('https://www.petfinder.com/wp-content/uploads/2012/11/99233806-bringing-home-new-cat-632x475.jpg');"></div>
                <div class="news-title"><div>News Title</div></div>
            </div>
        </div>
    </div>
</div>

CSS

.news-container {
    text-align: center;
    display: inline-block;
    vertical-align: top;

}

.news-window {
    display: inline-block;
    overflow: hidden;
    background: #EFEFEF;
    width: 230px;
    height: 200px;
    margin: 0 15px;
    cursor: pointer;
}

.news-tile {
    width: 230px;
    height: 400px;
    position: relative;
    top: 0px;
}

.news-pic {
    width: 100%;
    height: 200px;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
}

.news-title {
    width: 100%;
    height: 200px;
    background: #5D697B;
    color: orange;
    font-size: 18px;
    display: table;
}

.news-title div {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.news-window .date {
    width: 50px;
    height: 56px;
    background: orange;
    position: absolute;
    z-index: 100;
    opacity: 0.5;
    line-height: 1.25;
    font-size: 14px;
}

.news-window .date span {
    font-size: 28px;
}

JS

$(document).ready(function(){
    move(1);
    move(2);
    move(3);
});

function random(){
    return ((Math.random() * 5000) + 5000);
}

function move(i) {
    $("#" + i + ".news-tile").delay(random()).animate({top: "-200px"}, 600, 'easeOutCirc');
    $("#" + i + ".news-tile").delay(random()).animate({top: "0"}, 600, 'easeOutCirc');
    window.setTimeout(function() {move(i) }, 500);
}

EDIT: Fiddle had a problem. Fixed now.

Upvotes: 1

Views: 770

Answers (1)

Artur Filipiak
Artur Filipiak

Reputation: 9157

Instead of .delay() use setTimeout, which is more appropriate in case of cancelling the animation on hover().

The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.

Reference

Also, it would be more convenient to use classes instead of id attributes in your situation.

I'd make it this way (updated):

$('.news-window').each(function(i, el){
    el.timer = setTimeout(function(){moveUp.call(el)}, random());
}).hover(function(){moveUp.call(this, true)}, moveDown);

function random(){
    return ((Math.random() * 5000) + 5000);
}

function moveUp(x){
    var that = this;
    $('.slide', that).stop().animate({top:"-200px"}, 600, 'swing');
    clearTimeout(that.timer);
    that.timer = x || setTimeout(function(){moveDown.call(that)}, random());
}

function moveDown(){
    var that = this;
    $('.slide', that).stop().animate({top:"0"}, 600, 'swing');
    clearTimeout(that.timer);
    that.timer = setTimeout(function(){moveUp.call(that)}, random());
}

NOTE, I added slide class to each of the news-tile elements (as you have more sections with news-tile class).

JSFiddle

Upvotes: 3

Related Questions