1

I created a code that it work as a "movie" because the "pellicle" is a long image that contain all iphone movement. For create a sense of movement as movie, this code add 500px on the backgroundPositionY, then it wait 30 ms and restarts this process.

The mechanism is simple but the code is too long especially when will use a function .toggle() that is serves for add an another function, that it create an opposite animation when you do another click.

/*animate*/
screen.toggle(function(e){
    var mov = 0;
    function cicloIphone(){
        if(mov>6000){
            mov=0;
        };
        iphone.css('backgroundPosition', '0 -'+mov+'px');
        mov += 500;

        if(mov<6000){
            window.setTimeout(function(){
                cicloIphone();
            }, 30);
        };
    };
    var timeoutIphone = window.setTimeout(function(){
        cicloIphone();
    },0);
},function(e){
    var mov = 5500;
    function cicloIphone(){
        if(mov>6000){
            mov=0;
        };
        iphone.css('backgroundPosition', '0 -'+mov+'px');
        mov -= 500;

        if(mov<6000){
            window.setTimeout(function(){
                cicloIphone();
            }, 30);
        };
    };
    var timeoutIphone = window.setTimeout(function(){
        cicloIphone();
    },0);
});

I want synthesize with the function animate() but not ricreate my effect because not jump from 500px than 1000px each 30ms, but is too fluid and increase pixel for pixel.

/*animate synthesized*/
screen.toggle(
    function(e){iphone.stop(true,true).animate({
        'backgroundPositionX':'0px',
        'backgroundPositionY':'-5500px'
    },3000)},function(e){iphone.stop(true,true).animate({
        'backgroundPositionX':'0px',
        'backgroundPositionY':'0px'
    },3000);
});
Matteo Gilardoni
  • 311
  • 3
  • 15
  • I'm guessing you are using a CSS sprite to create an animation. The point is to have the image switch instantly to create "frames", and animating the backgrounds position will not work the way I think you intended it to, no matter how you do it, it will just move the background slowly into place and not change the image quickly as it should in an animation. – adeneo Jul 29 '12 at 11:59
  • Then the function animate is useless. – Matteo Gilardoni Jul 29 '12 at 13:04
  • If you're trying to do what I think you're trying to do, yes it is! – adeneo Jul 29 '12 at 13:30
  • You can look in this website http://localhost/yesimove/ however you understood good. I have did of frames for create a pellicle. Are There another method for synthesize the code? then I have a big problem with the variable **mov** because i would that when you click for the second times on the iphone not restart on -5500px but where the iphone were arrived with animation. – Matteo Gilardoni Jul 29 '12 at 13:51
  • Use .css() instead and just change the background position that way. Animate will, just as it says, animate the "travel" between the old and new positions instead of just switching right away, which is what you want for your script. – Tom Jul 29 '12 at 15:29

2 Answers2

1

animate() is quite a complex and flexible function. It does meet your requirements, since you can provide the three pieces of information it needs to operate:

  • the property to animate,
  • the target value,
  • the duration of the animation.

So it knows what to change, where to go and how long it should take to go there, but the actual way of going there does not satisfy your requirements in the default case. There is, however, no problem using animate() in this situation, as long as you provide it a custom easing function:

$.extend($.easing, {
    movie: function(current, elapsed, start, delta, duration) {
        // Returns the completion ratio as a float in the [0..1] range.
        // (elapsed / duration) would be linear, so build discrete steps
        // by "snapping" elapsed to 30 ms intervals.
        return (Math.floor(elapsed / 30) * 30) / duration;
    }
});

Now you can write:

screen.toggle(function() {
    iphone.stop(true, true).animate({
        backgroundPositionY: "-5500px"
    }, 330, "movie");
}, function() {
    iphone.stop(true, true).animate({
        backgroundPositionY: "0px"
    }, 330, "movie");
});

And it should animate the background image by discrete steps every 30 milliseconds for 330 milliseconds, which seems to be the effect you're looking for.

Community
  • 1
  • 1
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • http://www.matteowebdesigner.com/test/yesimove/ Now I am trying, in my case there is a image long **6000px**, where 500px you can already see. I calcolated that before with my function, before of add -500px on the background waited **30ms** then for this new function i must insert **330ms** or **360** as duration. I think that animation should do 11 or 12 step. If I must increment of 500px each 30ms, what is the number that I must to insert on 'return'? – Matteo Gilardoni Jul 30 '12 at 10:48
  • Ah, I indeed read `300` instead of `30` milliseconds, my apologies. If your image is 6000px tall and you want increments of 500px every 30ms, you have to replace `300` with `30` in the easing function and specify a duration of 330 ms for the animation (eleven 500px steps between 0px and -5500px, times 30 milliseconds). – Frédéric Hamidi Jul 30 '12 at 10:58
  • http://www.matteowebdesigner.com/test/yesimove/ Now is perfect :), very cool. Thank you very much. – Matteo Gilardoni Jul 30 '12 at 11:29
0

This trick it useful for a total compatibility with (IE7/9, Firefox 3.6, Opera, Safari Google Chrome). I used this jQuery extension http://bit.ly/bZzOC8 that allows used 2 values on the function .animate() for the propriety backgroundPosition:'(0 -5550)' unfortunately the ie7 and ie8 had a bug and the extension dosen't work so I used the ie condition if($.browser.msie) and I used the value separate backgroundPositionY and backgroundPositionX, if you want use only this rules you must know that dosen't work on Opera and fireFox. So with this code cover all browser.

if($.browser.msie){
    screen.toggle(function(){
            iphone.stop(true,true).animate({
                backgroundPositionY:'-5500',
                backgroundPositionX:'0'
            },330,'movie');
        },function(){
            iphone.stop(true,true).animate({
                backgroundPositionY:'0',
                backgroundPositionX:'0'
            },330,'movie');
        }
    );
}
else{
    screen.toggle(function(){
            iphone.stop(true,true).animate({
                backgroundPosition:'(0 -5500)'
            },330,'movie');
        },function(){
            iphone.stop(true,true).animate({
                backgroundPosition:'(0 0)'
            },330,'movie');
        }
    );
}
Matteo Gilardoni
  • 311
  • 3
  • 15