Changeset 12797

Show
Ignore:
Timestamp:
02/29/08 19:49:11 (9 months ago)
Author:
alex
Message:

Updates to the animation system and a new convenience method. Fixes #5985. !strict

This checkin provides:

  • a simpler syntax for dojo.animateProperty() property specifications when only the end value is wanted
  • a new dojo.anim() method which simplifies animating a single node immensely
  • changes the default animation period to 350ms (down from 1000ms). A full second feels like forever in most transitions.
  • updating tests for animations and expanding to cover dojo.anim()
  • adding an anim() method on dojo.NodeList? objects via the dojo.NodeList?-fx extension
  • Adding tests for dojo.NodeList?-fx

All tested on IE 6, Firefox, and Safari

Location:
dojo/trunk
Files:
1 added
4 modified

Legend:

Unmodified
Added
Removed
  • dojo/trunk/NodeList-fx.js

    r11695 r12797  
    1010dojo.extend(dojo.NodeList, { 
    1111        _anim: function(obj, method, args){ 
    12                 var anims = []; 
    1312                args = args||{}; 
    14                 this.forEach(function(item){ 
    15                         var tmpArgs = { node: item }; 
    16                         dojo.mixin(tmpArgs, args); 
    17                         anims.push(obj[method](tmpArgs)); 
    18                 }); 
    19                 return dojo.fx.combine(anims); // dojo._Animation 
     13                return dojo.fx.combine( 
     14                        this.map(function(item){ 
     15                                var tmpArgs = { node: item }; 
     16                                dojo.mixin(tmpArgs, args); 
     17                                return obj[method](tmpArgs); 
     18                        }) 
     19                ); // dojo._Animation 
    2020        }, 
    2121 
     
    8888                //      |       }).play(); 
    8989                return this._anim(dojo, "animateProperty", args); // dojo._Animation 
     90        }, 
     91 
     92        anim: function( /*Object*/                      properties,  
     93                                        /*Integer?*/            duration,  
     94                                        /*Function?*/           easing,  
     95                                        /*Function?*/           onEnd, 
     96                                        /*Integer?*/            delay){ 
     97                //      summary: 
     98                //              Animate one or more CSS properties for all nodes in this list. 
     99                //              The returned animation object will already be playing when it 
     100                //              is returned. See the docs for `dojo.anim` for full details. 
     101                //      properties: Object 
     102                //              the properties to animate 
     103                //      duration: Integer? 
     104                //              Optional. The time to run the animations for 
     105                //      easing: Function? 
     106                //              Optional. The easing function to use. 
     107                //      onEnd: Function? 
     108                //              A function to be called when the animation ends 
     109                //      delay: 
     110                //              how long to delay playing the returned animation 
     111                //      example: 
     112                //              Another way to fade out: 
     113                //      |       dojo.query(".thinger").anim({ opacity: 0 }); 
     114                //      example: 
     115                //              animate all elements with the "thigner" class to a width of 500 
     116                //              pixels over half a second 
     117                //      |       dojo.query(".thinger").anim({ width: 500 }, 700); 
     118                var canim = dojo.fx.combine( 
     119                        this.map(function(item){ 
     120                                return dojo.animateProperty({ 
     121                                        node: item, 
     122                                        properties: properties, 
     123                                        duration: duration||350, 
     124                                        easing: easing 
     125                                }); 
     126                        }) 
     127                );  
     128                if(onEnd){ 
     129                        dojo.connect(canim, "onEnd", onEnd); 
     130                } 
     131                return canim.play(delay||0); // dojo._Animation 
    90132        } 
    91133}); 
  • dojo/trunk/tests/fx.js

    r9915 r12797  
    22if(dojo.isBrowser){ 
    33        doh.registerUrl("tests.fx", dojo.moduleUrl("tests", "fx.html")); 
     4        doh.registerUrl("tests.NodeList-fx", dojo.moduleUrl("tests", "NodeList-fx.html")); 
    45} 
  • dojo/trunk/tests/_base/fx.html

    r9379 r12797  
    1010                <script type="text/javascript" src="../../_base/fx.js"></script> 
    1111                <script type="text/javascript"> 
    12                         var duration = 1000; 
     12                        var duration = 500; 
     13                        var timeout = 750; 
    1314                        dojo.require("doh.runner"); 
    1415                        dojo.addOnLoad(function(){ 
     
    1718                                                { 
    1819                                                        name: "fadeOut", 
    19                                                         timeout: 1500, 
    20                                                         runTest: function(t){ 
     20                                                        timeout: timeout, 
     21                                                        runTest: function(){ 
    2122                                                                var opacity = dojo.style('foo', 'opacity'); 
    22                                                                 t.is(1, opacity); 
     23                                                                doh.is(1, opacity); 
    2324                                                                var anim = dojo.fadeOut({ node: 'foo', duration: duration }); 
    2425                                                                var d = new doh.Deferred(); 
    25                                                                 dojo.connect(anim, "onEnd", null, function(){ 
     26                                                                dojo.connect(anim, "onEnd", function(){ 
    2627                                                                        var opacity = dojo.style('foo', 'opacity'); 
    27                                                                         // console.debug(anim._start); 
    2828                                                                        var elapsed = (new Date()) - anim._start; 
    29                                                                         t.is(0, opacity); 
    30                                                                         t.assertTrue(elapsed >= duration); 
     29                                                                        doh.is(0, opacity); 
     30                                                                        doh.t(elapsed >= duration); 
    3131                                                                        d.callback(true); 
    3232                                                                }); 
     
    3838                                                { 
    3939                                                        name: "fadeIn", 
    40                                                         timeout: 1500, 
    41                                                         runTest: function(t){ 
     40                                                        timeout: timeout, 
     41                                                        runTest: function(){ 
    4242                                                                var opacity = dojo.style('foo', 'opacity'); 
    43                                                                 t.is(0, opacity); 
     43                                                                doh.is(0, opacity); 
    4444                                                                var anim = dojo.fadeIn({ node: 'foo', duration: duration }); 
    4545                                                                var d = new doh.Deferred(); 
    46                                                                 dojo.connect(anim, "onEnd", null, function(){ 
     46                                                                dojo.connect(anim, "onEnd", function(){ 
    4747                                                                        var opacity = dojo.style('foo', 'opacity'); 
    48                                                                         // console.debug(anim._start); 
    4948                                                                        var elapsed = (new Date()) - anim._start; 
    50                                                                         t.is(1, opacity); 
    51                                                                         t.assertTrue(elapsed >= duration); 
     49                                                                        doh.is(1, opacity); 
     50                                                                        doh.t(elapsed >= duration); 
    5251                                                                        d.callback(true); 
    5352                                                                }); 
     
    5958                                                { 
    6059                                                        name: "animateColor", 
    61                                                         timeout: 1500, 
    62                                                         runTest: function(t){ 
     60                                                        timeout: timeout, 
     61                                                        runTest: function(){ 
    6362                                                                var d = new doh.Deferred(); 
    6463                                                                var anim = dojo.animateProperty({  
     
    7978                                                { 
    8079                                                        name: "animateColorBack", 
    81                                                         timeout: 1500, 
    82                                                         runTest: function(t){ 
     80                                                        timeout: timeout, 
     81                                                        runTest: function(){ 
    8382                                                                var d = new doh.Deferred(); 
    8483                                                                var anim = dojo.animateProperty({  
     
    10099                                                { 
    101100                                                        name: "animateHeight", 
    102                                                         timeout: 1500, 
     101                                                        timeout: timeout, 
    103102                                                        runTest: function(t){ 
     103                                                                dojo.byId("foo").style.height = ""; 
    104104                                                                var startHeight = dojo.marginBox("foo").h;  
    105105                                                                var endHeight = Math.round(startHeight / 2); 
     
    115115                                                                dojo.connect(anim, "onEnd", anim, function(){ 
    116116                                                                        var elapsed = (new Date().valueOf()) - anim._startTime; 
    117                                                                         t.assertTrue(elapsed >= duration); 
     117                                                                        doh.t(elapsed >= duration); 
    118118                                                                        var height = dojo.marginBox("foo").h;  
    119                                                                         t.is(height, endHeight); 
    120                                                                         d.callback(true); 
    121                                                                 }); 
    122                                                                  
    123                                                                 anim.play(); 
     119                                                                        doh.is(height, endHeight); 
     120                                                                        d.callback(true); 
     121                                                                }); 
     122                                                                 
     123                                                                anim.play(); 
     124                                                                return d; 
     125                                                        } 
     126                                                }, 
     127                                                { 
     128                                                        name: "animateHeight_defaults_syntax", 
     129                                                        timeout: timeout, 
     130                                                        runTest: function(){ 
     131                                                                dojo.byId("foo").style.height = ""; 
     132                                                                var startHeight = dojo.marginBox("foo").h;  
     133                                                                var endHeight = Math.round(startHeight / 2); 
     134                                                                 
     135                                                                var anim = dojo.animateProperty({ 
     136                                                                        node: "foo", 
     137                                                                        properties: { height: endHeight }, 
     138                                                                        duration: duration 
     139                                                                }); 
     140 
     141                                                                var d = new doh.Deferred(); 
     142 
     143                                                                dojo.connect(anim, "onEnd", anim, function(){ 
     144                                                                        var elapsed = (new Date().valueOf()) - anim._startTime; 
     145                                                                        doh.t(elapsed >= duration); 
     146                                                                        var height = dojo.marginBox("foo").h;  
     147                                                                        doh.is(height, endHeight); 
     148                                                                        d.callback(true); 
     149                                                                }); 
     150                                                                 
     151                                                                anim.play(); 
     152                                                                return d; 
     153                                                        } 
     154                                                }, 
     155                                                { 
     156                                                        name: "inlineWidth", 
     157                                                        timeout: timeout, 
     158                                                        runTest: function(){ 
     159                                                                dojo.style("foo", "display", "none"); 
     160                                                                dojo.style("bar", "display", ""); 
     161                                                                var startWidth = dojo.marginBox("bar").w;  
     162                                                                var endWidth = Math.round(startWidth / 2); 
     163                                                                 
     164                                                                var anim = dojo.animateProperty({ 
     165                                                                        node: "bar", 
     166                                                                        properties: { width: endWidth }, 
     167                                                                        duration: duration 
     168                                                                }); 
     169 
     170                                                                var d = new doh.Deferred(); 
     171 
     172                                                                dojo.connect(anim, "onEnd", anim, function(){ 
     173                                                                        var elapsed = (new Date().valueOf()) - anim._startTime; 
     174                                                                        doh.t(elapsed >= duration); 
     175                                                                        doh.is(dojo.marginBox("bar").w, endWidth); 
     176                                                                        d.callback(true); 
     177                                                                }); 
     178                                                                 
     179                                                                anim.play(); 
     180                                                                return d; 
     181                                                        } 
     182                                                }, 
     183                                                { 
     184                                                        name: "anim", 
     185                                                        timeout: timeout+500, 
     186                                                        runTest: function(){ 
     187                                                                var id = "baz"; 
     188                                                                dojo.style("bar", "display", "none"); 
     189                                                                dojo.style(id, "display", ""); 
     190                                                                var kickoff = new Date().valueOf(); 
     191                                                                var startWidth = dojo.marginBox(id).w;  
     192                                                                var endWidth = Math.round(startWidth / 2); 
     193 
     194                                                                var d = new doh.Deferred(); 
     195                                                                var anim = dojo.anim( 
     196                                                                        id,  
     197                                                                        {  
     198                                                                                width: endWidth, 
     199                                                                                opacity: 0 
     200                                                                        },  
     201                                                                        duration,  
     202                                                                        null,  
     203                                                                        function(){ 
     204                                                                                var elapsed = (new Date().valueOf()) - anim._startTime; 
     205                                                                                doh.t(elapsed >= duration); 
     206                                                                                doh.t((new Date().valueOf()) >= (kickoff+duration+500)); 
     207                                                                                doh.is(dojo.marginBox(id).w, endWidth); 
     208                                                                                doh.is(dojo.style(id, "opacity"), 0); 
     209                                                                                d.callback(true); 
     210                                                                        }, 
     211                                                                        500 
     212                                                                ); 
     213                                                                return d; 
     214                                                        } 
     215                                                }, 
     216                                                { 
     217                                                        name: "anim_defaults", 
     218                                                        timeout: 1000, 
     219                                                        runTest: function(){ 
     220                                                                var id = "thud"; 
     221                                                                dojo.style("baz", "display", "none"); 
     222                                                                dojo.style(id, "display", ""); 
     223                                                                var startWidth = dojo.marginBox(id).w;  
     224                                                                var endWidth = Math.round(startWidth / 2); 
     225 
     226                                                                var d = new doh.Deferred(); 
     227                                                                var anim = dojo.anim(id, { width: endWidth }); 
     228                                                                dojo.connect(anim, "onEnd", function(){ 
     229                                                                        var elapsed = (new Date().valueOf()) - anim._startTime; 
     230                                                                        doh.t(elapsed >= dojo._Animation.prototype.duration); // the default 
     231                                                                        doh.is(dojo.marginBox(id).w, endWidth); 
     232                                                                        d.callback(true); 
     233                                                                }); 
    124234                                                                return d; 
    125235                                                        } 
     
    192302                        </p> 
    193303                </div> 
     304                <p id="bar" style="display: none;"> 
     305                Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean semper 
     306                sagittis velit. Cras in mi. Duis porta mauris ut ligula.  Proin porta 
     307                rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi. 
     308                Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis. 
     309                Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae 
     310                risus. 
     311                </p> 
     312                <p id="baz" style="display: none;"> 
     313                Aliquam vitae enim. Duis scelerisque metus auctor est venenatis 
     314                imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem 
     315                nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in 
     316                massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In 
     317                pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra 
     318                quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia, 
     319                felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut 
     320                quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla 
     321                rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut 
     322                semper velit ante id metus. Praesent massa dolor, porttitor sed, 
     323                pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit 
     324                tortor pharetra congue.  Suspendisse pulvinar. 
     325                </p> 
     326                <p id="thud" style="display: none;"> 
     327                Aliquam vitae enim. Duis scelerisque metus auctor est venenatis 
     328                imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem 
     329                nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in 
     330                massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In 
     331                pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra 
     332                quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia, 
     333                felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut 
     334                quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla 
     335                rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut 
     336                semper velit ante id metus. Praesent massa dolor, porttitor sed, 
     337                pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit 
     338                tortor pharetra congue.  Suspendisse pulvinar. 
     339                </p> 
    194340        </body> 
    195341</html> 
  • dojo/trunk/_base/fx.js

    r12699 r12797  
    5050                // duration: Integer 
    5151                //      The time in milliseonds the animation will take to run 
    52                 duration: 1000, 
     52                duration: 350, 
    5353         
    5454        /*===== 
     
    121121                        //      args: 
    122122                        //              The arguments to pass to the event. 
    123                         if(this[evt]){ 
    124                                 this[evt].apply(this, args||[]); 
     123                        try{ 
     124                                if(this[evt]){ 
     125                                        this[evt].apply(this, args||[]); 
     126                                } 
     127                        }catch(e){ 
     128                                // squelch and log because we shouldn't allow exceptions in 
     129                                // synthetic event handlers to cause the internal timer to run 
     130                                // amuck, potentially pegging the CPU. I'm not a fan of this 
     131                                // squelch, but hopefully logging will make it clear what's 
     132                                // going on 
     133                                console.error("exception in animation handler for:", evt); 
     134                                console.error(e); 
    125135                        } 
    126136                        return this; // dojo._Animation 
     
    290300                this._timer = null; 
    291301                ctr--; 
    292                 if(!ctr){ 
     302                if(ctr <= 0){ 
    293303                        clearInterval(timer); 
    294304                        timer = null; 
     305                        ctr = 0; 
    295306                } 
    296307        }; 
     
    324335                var props = (fArgs.properties.opacity = {}); 
    325336                props.start = !("start" in fArgs) ? 
    326                         function(){ return Number(d.style(fArgs.node, "opacity")); } : fArgs.start; 
     337                        function(){  
     338                                return Number(d.style(fArgs.node, "opacity"));  
     339                        } : fArgs.start; 
    327340                props.end = fArgs.end; 
    328341 
     
    339352                //      duration: Integer? 
    340353                //              Duration of the animation in milliseconds. 
    341                 // easing: Function? 
     354                //      easing: Function? 
    342355                //              An easing function. 
    343356                this.node = node; 
     
    367380 
    368381        var PropLine = function(properties){ 
     382                // PropLine is an internal class which is used to model the values of 
     383                // an a group of CSS properties across an animation lifecycle. In 
     384                // particular, the "getValue" function handles getting interpolated 
     385                // values between start and end for a particular CSS value. 
    369386                this._properties = properties; 
    370387                for(var p in properties){ 
     
    402419                //              duration. 
    403420                //       
    404                 //              args.node can be a String or a DomNode reference 
     421                //              args.node can be a String or a DOMNode reference