0

I am encountering a strange situation with Safari on iPad. I do have a spritesheet-based animation sequence that you can play in a "ping-pong" manner: you click once, it plays forward until its last frame, you click back, it plays backwards again until it reaches frame 1.

The JS I use for that looks like:

$('.pingpong').each(function(){

    var step = parseInt($(this).width(), 10);
    var frames = parseInt($(this).data('frames'), 10);
    var img = $(this).find('img');
    var running = false;
    $(this).data('playForward', true);

    $(this).bind(interaction, function(){ //interaction is tap on mobiles and click on desktops

        if (!running){

            running = true;
            var lastExecution = new Date().getTime();
            var counter = 1;

            function pingpong(){

                var now = new Date().getTime();

                if (now - lastExecution >= (1000 / config.fps)){ //animation is supposed to run at 12fps

                    img.css('margin-left', $(this).data('playForward') ? '+=' + step + 'px' : '-=' + step + 'px');
                    counter++;
                    lastExecution = new Date().getTime();

                }

                if (counter != frames){

                    requestAnimationFrame(pingpong);

                } else {

                    $(this).data('playForward', !($(this).data('playForward'))); //this change of direction is triggered on iOS as well strangely enough
                    running = false;

                }

            }

            pingpong();

        }

    });

});

This works perfectly fine in all desktop browsers, yet Safari on the iPad won't stop requesting animation frames, the animation will "overflow" until the image is long gone (via its margin), but when I log the number or requestAnimationFrame calls (I am using the Paul Irish shim btw - yet it makes no difference if I use webkitRequestAnimationFrame) I can see that the recursive pingpong calls never stop in iOS (on the desktop they do). Also, trying to cancelAnimationFrame the id of my calls makes no difference.

Is my understanding of requestAnimationFrame flawed or am I missing something different here? Is there a difference in the new Date().getTime() behavior on the iPad? I am currently with a setInterval based solution, but I am really completely ridiculed by this behavior so I thought someone might now where I am wrong here?

4

1 回答 1

0

尝试以下操作:

$('.pingpong').each(function(){

var step = parseInt($(this).width(), 10);
var frames = parseInt($(this).data('frames'), 10);
var img = $(this).find('img');
var running = false;
$(this).data('playForward', true);

$(this).bind(interaction, function(){ //interaction is tap on mobiles and click on desktops

    if (!running){

        running = true;
        var lastExecution = new Date().getTime();
        var counter = 1;

        function pingpong(){

            var now = new Date().getTime();

            if (now - lastExecution >= (1000 / config.fps)){ //animation is supposed to run at 12fps

                img.css('margin-left', $(this).data('playForward') ? '+=' + step + 'px' : '-=' + step + 'px');
                counter++;
                lastExecution = new Date().getTime();

            }

            if (counter < frames){
                requestAnimationFrame(pingpong);
            } else {
                $(this).data('playForward', !($(this).data('playForward'))); //this change of direction is triggered on iOS as well strangely enough
                running = false;
            }

        }

        pingpong();

    }

});

});

于 2012-11-16T10:42:25.823 回答