Jashwant
Jashwant

Reputation: 29005

jQuery Mousewheel event coupled with element animation

Scenario:

I need to create a curve animation (arc shaped), which triggers by mousewheel.

So, I have comeup with some code.

See demo here

var arc = {
    center: [-200, ($(window).height() - 24) / 2],
    // height + padding
    radius: 450,
    start: 0,
    end: 90,
    dir: 1
}

$('.point').each(function () {
    $(this).data('lastEnd', arc.end).animate({
        path: new $.path.arc(arc)
    }, 0);

    arc.start -= 10;
    arc.end -= 8;
});

$('body').mousewheel(function (e, delta, deltaX, deltaY) {
    e.preventDefault();
    var delta = delta * -1;
    $('.point').each(function () {
        var $this = $(this);
        var startPoint = $this.data('lastEnd');
        var arc = {
            center: [-200, ($(window).height() - 24) / 2],
            radius: 450,
            start: startPoint,
            end: (delta * 8) + startPoint,
            dir: delta > 0 ? 1 : -1
        }
        $this.data('lastEnd', arc.end);

        $(this).animate({
            path: new $.path.arc(arc)
        }, 500);
    });
});

I am using jQuery path for curve animation, and

jQuery mousewheel to trigger event on mousewheel.

Problem:

Mousewheel just gives me direction of mousewheel, but not the velocity. So, if user scrolls faster, instead of giving increased delta, it fires mousewheel event multiple times. It would have been worked in simple situations, but I am animating the points. So, multiple mousewheel events trigger, before the animation finishes. ( You can see it by scrolling faster )

What I tried:

  1. I restricted multiple mousewheel events by putting a flag isScrolling, and restrict scrolling, if isScrolling is true. But, that does not give me smooth animation. Until the animation finishes, mousescroll does nothing.

  2. I used setTimeout to hold scrolling for few milliseconds and summing all the deltas fired in that period, but it's also not smooth.

  3. I tried using stop(). But stop() stops the animation in midway and I want atleast one point at the position of marker (not above / below it)

What I want:

Smooth animation with mousewheel ( just like the normal scroll on a page). Faster mousewheel scrolling should scroll more than the normal (one scroll at a time) scrolling.

UPDATE 1:

My progress since yesterday can be seen here

Now, I am using setTimeout to sum up deltas before starting animation and then using a relative duration to animate faster in bigger deltas and slower in smaller ones.

Upvotes: 2

Views: 1733

Answers (1)

yckart
yckart

Reputation: 33408

I would use the css-method from $.path.arc and pass its returned css-object to $.fn.animate. To get the actual css-object now, use the mousewheel-delta to iterate over them:

var path = new $.path.arc(arc);
$this.stop().animate(path.css(delta-1), 500);

http://fiddle.jshell.net/Tfwqu/1/

To make this smoother you should use an easing-function:

$.easing.easeOutQuad = function (x, t, b, c, d) {
    return -c *(t/=d)*(t-2) + b;
};

...

var path = new $.path.arc(arc);
$this.stop().animate(path.css(delta-1), 500, 'easeOutQuad');

http://fiddle.jshell.net/Tfwqu/2/

Upvotes: 1

Related Questions