├── .gitignore ├── bower.json ├── component.json ├── NOTES.md ├── package.json ├── test ├── test.js ├── style.css └── index.html ├── CONTRIBUTING.md ├── README.md ├── HISTORY.md └── jquery.transit.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | site 3 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.transit", 3 | "repo": "rstacruz/jquery.transit", 4 | "description": "Smooth CSS3 transitions and transformations for jQuery.", 5 | "version": "0.9.12", 6 | "keywords": [ 7 | "css3", 8 | "animation", 9 | "transition" 10 | ], 11 | "dependencies": { 12 | "jquery": "*" 13 | }, 14 | "development": {}, 15 | "license": "MIT", 16 | "main": "jquery.transit.js" 17 | } 18 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.transit", 3 | "repo": "rstacruz/jquery.transit", 4 | "description": "Smooth CSS3 transitions and transformations for jQuery.", 5 | "version": "0.9.12", 6 | "keywords": [ 7 | "css3", 8 | "animation", 9 | "transition" 10 | ], 11 | "dependencies": { 12 | "component/jquery": "*" 13 | }, 14 | "development": {}, 15 | "license": "MIT", 16 | "scripts": [ 17 | "jquery.transit.js" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | Developer notes 2 | =============== 3 | 4 | Testing: 5 | 6 | open test/index.html 7 | 8 | Making a new release: 9 | 10 | vim HISTORY.md # update changelog 11 | bump *.json *.js # update version number 12 | npm publish # release to npm 13 | git release v1.0.0 # release to github/bower 14 | cd site && make # update the site 15 | 16 | Managing the site 17 | ----------------- 18 | 19 | Make `site/`: 20 | 21 | git clone git@github.com:rstacruz/jquery.transit.git -b gh-pages ./site 22 | 23 | Update: 24 | 25 | cd site 26 | make update # update from files 27 | make # update the site 28 | make dist # make dist/ files (uh, should be deprecated) 29 | 30 | v1.0.0 to do 31 | ------------ 32 | 33 | * .transitionStop() 34 | * use transitionend by default (#184) 35 | * Update bootstrap compatibility (#143, #67) 36 | * Redesign the site 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.transit", 3 | "version": "0.9.12", 4 | "description": "Smooth CSS3 transitions and transformations for jQuery.", 5 | "main": "jquery.transit.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "mocha" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/rstacruz/jquery.transit.git" 15 | }, 16 | "keywords": [ 17 | "css3", 18 | "animation", 19 | "transition" 20 | ], 21 | "author": "Rico Sta. Cruz ", 22 | "license": "MIT", 23 | "peerDependencies": { 24 | "jquery": "*" 25 | }, 26 | "devDependencies": { 27 | "chai": "1.9.1", 28 | "sinon": "1.10.2", 29 | "jsdom": "0.11.0", 30 | "coffee-script": "1.7.1" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/rstacruz/jquery.transit/issues" 34 | }, 35 | "homepage": "http://ricostacruz.com/jquery.transit" 36 | } 37 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | /* Simple test framework of sorts */ 3 | 4 | 5 | function addTestEvents ($test) { 6 | $test.bind('mouseenter play', function() { 7 | var $test = $(this).closest('.test'); 8 | $test.trigger('reset'); 9 | var $box = $test.find('.box:not(.ghost)'); 10 | var $ghost = $box.clone().addClass('ghost').appendTo($test.find('.area')); 11 | 12 | $test.data('code').fn($box, $test); 13 | }); 14 | 15 | $test.bind('mouseleave reset', function() { 16 | var $test = $(this).closest('.test'); 17 | var $ghost = $test.find('.ghost'); 18 | if ($ghost.length) { 19 | $test.find('.box:not(.ghost)').remove(); 20 | $test.find('.ghost').removeClass('ghost'); 21 | } 22 | }); 23 | } 24 | 25 | $(document).ready(function () { 26 | $('.play-all').bind('click', function() { 27 | $('.test').trigger('play'); 28 | }); 29 | }); 30 | 31 | function test(name, fn) { 32 | var i = $('.tests .test').length; 33 | var $test = $('

'); 34 | 35 | var m = fn.toString().match(/\{([\s\S]*)\}$/); 36 | var code = m[1]; 37 | code = code.replace(/^\s*|\s*$/g, ''); 38 | code = code.replace(/\n {4}/g, "\n"); 39 | name = name.replace(/\(.*\)/, function(n) { return ""+n.substr(1,n.length-2)+""; }); 40 | 41 | $test.attr('id', 'test-'+i); 42 | $test.find('h3').html(name); 43 | $test.find('pre').text(code); 44 | $test.data('code', {fn: fn}); 45 | addTestEvents($test); 46 | 47 | $('.tests').append($test); 48 | } 49 | 50 | function group(name) { 51 | $('.tests').append($('

').text(name)); 52 | } 53 | 54 | // Show versions 55 | $(function() { 56 | $('#jquery-version').html( 57 | 'jQuery: v' + $.fn.jquery + '
' + 58 | 'Transit: v' + $.transit.version 59 | ); 60 | }); 61 | 62 | window.group = group; 63 | window.test = test; 64 | 65 | })(jQuery); 66 | -------------------------------------------------------------------------------- /test/style.css: -------------------------------------------------------------------------------- 1 | * { margin: 0; padding: 0; font-size: 1em; } 2 | html { padding: 40px; background: #e3e3e7; } 3 | body, td, input, textarea { font-family: helvetica neue, sans-serif; font-size: 9pt; color: #444; line-height: 1.4; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } 4 | body { padding-top: 50px; } 5 | .use { position: fixed; top: 0; left: 0; right: 0; padding: 20px; border-bottom: solid 1px rgba(0, 0, 0, 0.1); background: rgba(250, 250, 250, 0.9); z-index: 10; } 6 | .test { width: 220px; padding: 20px; float: left; margin: 0 20px 20px 0; background: white; border-radius: 2px; box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.05), -1px 1px 0 rgba(0, 0, 0, 0.05), 0 1px 5px rgba(0, 0, 0, 0.05); } 7 | .test .area { width: auto; height: 100px; margin: 10px 0; position: relative; } 8 | .test:hover { box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.05), -1px 1px 0 rgba(0, 0, 0, 0.05), 0 1px 5px rgba(0, 0, 0, 0.05), 0 0 0 4px rgba(0, 0, 0, 0.15); } 9 | .test h3 { font-size: 1.2em; margin-bottom: 2px; overflow: hidden; line-height: 24px; } 10 | .test h3 em { font-style: normal; font-weight: 200; float: right; color: #37a; font-size: 0.8em; } 11 | .test .box { position: absolute; top: 50%; left: 50%; margin: -16px 0 0 -16px; width: 32px; height: 32px; line-height: 32px; text-align: center; background: #505070; border-radius: 2px; z-index: 2; color: #ddd; } 12 | .test .ghost { background: #ddd; z-index: 1; box-shadow: inset 2px 2px 2px rgba(0, 0, 0, 0.07), inset 0 0 0 1px rgba(0, 0, 0, 0.03); } 13 | .test pre { font-family: menlo, monospace; font-size: 7pt; padding: 10px; background: #eee; margin: 20px -20px -20px -20px; border-top: solid 1px #ddd; white-space: pre-wrap; line-height: 1.5; } 14 | .group-heading { margin: 20px 0 20px 0; padding-bottom: 10px; border-bottom: dotted 1px #ccc; font-size: 1.6em; clear: both; color: #70a0c0; font-weight: 200; } 15 | 16 | .use button { padding: 0 10px; } 17 | .use a, .use button { margin: 0 5px; } 18 | 19 | .description { padding-bottom: 20px; border-bottom: dotted 1px #ccc; } 20 | .description h1 { font-size: 2.5em; font-weight: 200; color: #707090; } 21 | .description p { font-size: 1.2em; color: #707090; width: 500px; } 22 | .description .version { margin-bottom: 20px; font-size: 1.2em; font-weight: bold; } 23 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery Transit tests 6 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | Use: 36 | jQ 2.0.3 37 | jQ 1.9.0b1 38 | jQ 1.8 39 | jQ 1.7 40 | jQ 1.6 41 | jQ 1.5 42 | 43 |
44 | 45 |
46 |

jQuery transit tests

47 |

48 |

Since there's no reliable programmatic way to test for transitions, this 49 | is a simple page set up so you can visually inspect effects 50 | conveniently.

51 |
52 | 53 |
54 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Transit 2 | 3 | Want to get involved? Thanks! There are plenty of ways to help! 4 | 5 | ## Reporting issues 6 | 7 | A bug is a _demonstrable problem_ that is caused by the code in the 8 | repository. 9 | 10 | Please read the following guidelines before you [report an issue][issues]: 11 | 12 | 1. **Use the GitHub issue search** — check if the issue has already been 13 | reported. If it has been, please comment on the existing issue. 14 | 15 | 2. **Check if the issue has been fixed** — the latest `master` or 16 | development branch may already contain a fix. 17 | 18 | 3. **Isolate the demonstrable problem** — make sure that the code in the 19 | project's repository is _definitely_ responsible for the issue. Create a 20 | [reduced test case](http://css-tricks.com/6263-reduced-test-cases/) - an 21 | extremely simple and immediately viewable example of the issue. 22 | 23 | 4. **Include a live example** — provide a link to your reduced test case 24 | when appropriate (e.g. if the issue is related to (front-end technologies). 25 | Please use [jsFiddle](http://jsfiddle.net) to host examples. 26 | 27 | Please try to be as detailed as possible in your report too. What is your 28 | environment? What steps will reproduce the issue? What browser(s) and OS 29 | experience the problem? What would you expect to be the outcome? All these 30 | details will help people to assess and fix any potential bugs. 31 | 32 | ### Example of a good bug report: 33 | 34 | > Short and descriptive title 35 | > 36 | > A summary of the issue and the browser/OS environment in which it occurs. If 37 | > suitable, include the steps required to reproduce the bug. 38 | > 39 | > 1. This is the first step 40 | > 2. This is the second step 41 | > 3. Further steps, etc. 42 | > 43 | > `` (a link to the reduced test case) 44 | > 45 | > Any other information you want to share that is relevant to the issue being 46 | > reported. This might include the lines of code that you have identified as 47 | > causing the bug, and potential solutions (and your opinions on their 48 | > merits). 49 | 50 | A good bug report shouldn't leave people needing to chase you up to get further 51 | information that is required to assess or fix the bug. 52 | 53 | **[File a bug report][issues]** 54 | 55 | ## Responding to issues 56 | 57 | Feel free to respond to other people's issues! Some people may be reporting 58 | issues that can easily be solved even without modification to the project's 59 | code. 60 | 61 | You can also help by verifying issues reported. 62 | 63 | **[View issues][issues]** 64 | 65 | ## The 'help wanted' tag 66 | 67 | Some [issues] are tagged with the 'help wanted' tag. These issues often: 68 | 69 | - are missing an actual implementation, or 70 | - need people's help in verifying and replicating the issue, or 71 | - need test cases. 72 | 73 | If you would like to contribute code and don't have any specific issue you want 74 | to fix, this would be a good place to start looking at! 75 | 76 | **[View issues][issues]** 77 | 78 | ## Pull requests 79 | 80 | Good pull requests — patches, improvements, new features — are a fantastic 81 | help. They should remain focused in scope and avoid containing unrelated 82 | commits. 83 | 84 | If your contribution involves a significant amount of work or substantial 85 | changes to any part of the project, please open an issue to discuss it first. 86 | 87 | Please follow this process; it's the best way to get your work included in the 88 | project: 89 | 90 | 1. [Fork](http://help.github.com/fork-a-repo/) the project. 91 | 92 | 2. Clone your fork (`git clone 93 | https://github.com//html5-boilerplate.git`). 94 | 95 | 3. Add an `upstream` remote (`git remote add upstream 96 | https://github.com/rstacruz/jquery.transit.git`). 97 | 98 | 4. Get the latest changes from upstream (e.g. `git pull upstream 99 | `). 100 | 101 | 5. Create a new topic branch to contain your feature, change, or fix (`git 102 | checkout -b `). 103 | 104 | 6. Make sure that your changes adhere to the current coding conventions used 105 | throughout the project - indentation, accurate comments, etc. Please update 106 | any documentation that is relevant to the change you are making. 107 | 108 | 7. Commit your changes in logical chunks; use git's [interactive 109 | rebase](https://help.github.com/articles/interactive-rebase) feature to tidy 110 | up your commits before making them public. Please adhere to these [git commit 111 | message 112 | guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 113 | or your pull request is unlikely be merged into the main project. 114 | 115 | 8. Locally merge (or rebase) the upstream branch into your topic branch. 116 | 117 | 9. Push your topic branch up to your fork (`git push origin 118 | `). 119 | 120 | 10. [Open a Pull Request](http://help.github.com/send-pull-requests/) with a 121 | clear title and description. Please mention which browsers you tested in. 122 | 123 | ## Acknowledgements 124 | 125 | This contributing guide has been adapted from [HTML5 boilerplate's guide][g]. 126 | 127 | [g]: https://github.com/h5bp/html5-boilerplate/blob/master/CONTRIBUTING.md 128 | [issues]: https://github.com/rstacruz/jquery.transit/issues/ 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [jQuery Transit](http://ricostacruz.com/jquery.transit) 2 | #### Super-smooth CSS3 transformations and transitions for jQuery 3 | 4 | jQuery Transit is a plugin for to help you do CSS transformations and 5 | transitions in jQuery. 6 | 7 | Refer to the [jQuery Transit website](http://ricostacruz.com/jquery.transit) for 8 | examples. 9 | 10 | Usage 11 | ----- 12 | 13 | Just include [jquery.transit.js] after jQuery. Requires jQuery 1.4+. 14 | 15 | ``` html 16 | 17 | 18 | ``` 19 | 20 | It is also available via [bower] and [npm]. 21 | 22 | $ bower install --save jquery.transit 23 | $ npm install --save jquery.transit 24 | 25 | [bower]: http://bower.io/search/?q=jquery.transit 26 | [npm]: http://npmjs.org/package/jquery.transit 27 | [jquery.transit.js]: https://github.com/rstacruz/jquery.transit/blob/master/jquery.transit.js 28 | 29 | Transformations 30 | --------------- 31 | 32 | You can set transformations as you would any CSS property in jQuery. 33 | (Note that you cannot `$.fn.animate()` them, only set them.) 34 | 35 | ``` javascript 36 | $("#box").css({ x: '30px' }); // Move right 37 | $("#box").css({ y: '60px' }); // Move down 38 | $("#box").css({ translate: [60,30] }); // Move right and down 39 | $("#box").css({ rotate: '30deg' }); // Rotate clockwise 40 | $("#box").css({ scale: 2 }); // Scale up 2x (200%) 41 | $("#box").css({ scale: [2, 1.5] }); // Scale horiz and vertical 42 | $("#box").css({ skewX: '30deg' }); // Skew horizontally 43 | $("#box").css({ skewY: '30deg' }); // Skew vertical 44 | $("#box").css({ perspective: 100, rotateX: 30 }); // Webkit 3d rotation 45 | $("#box").css({ rotateY: 30 }); 46 | $("#box").css({ rotate3d: [1, 1, 0, 45] }); 47 | ``` 48 | 49 | Relative values are supported. 50 | 51 | ``` javascript 52 | $("#box").css({ rotate: '+=30' }); // 30 degrees more 53 | $("#box").css({ rotate: '-=30' }); // 30 degrees less 54 | ``` 55 | 56 | All units are optional. 57 | 58 | ``` javascript 59 | $("#box").css({ x: '30px' }); 60 | $("#box").css({ x: 30 }); 61 | ``` 62 | 63 | Multiple arguments can be commas or an array. 64 | 65 | ``` javascript 66 | $("#box").css({ translate: [60,30] }); 67 | $("#box").css({ translate: ['60px','30px'] }); 68 | $("#box").css({ translate: '60px,30px' }); 69 | ``` 70 | 71 | Getters are supported. (Getting properties with multiple arguments returns 72 | arrays.) 73 | 74 | ``` javascript 75 | $("#box").css('rotate'); //=> "30deg" 76 | $("#box").css('translate'); //=> ['60px', '30px'] 77 | ``` 78 | 79 | Animating - `$.fn.transition` 80 | ----------------------------- 81 | 82 | $('...').transition(options, [duration], [easing], [complete]) 83 | 84 | You can animate with CSS3 transitions using `$.fn.transition()`. It works 85 | exactly like `$.fn.animate()`, except it uses CSS3 transitions. 86 | 87 | ``` javascript 88 | $("#box").transition({ opacity: 0.1, scale: 0.3 }); 89 | $("#box").transition({ opacity: 0.1, scale: 0.3 }, 500); // duration 90 | $("#box").transition({ opacity: 0.1, scale: 0.3 }, 'fast'); // easing 91 | $("#box").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in'); // duration+easing 92 | $("#box").transition({ opacity: 0.1, scale: 0.3 }, function() {..}); // callback 93 | $("#box").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in', function() {..}); // everything 94 | ``` 95 | 96 | You can also pass *duration* and *easing* and *complete* as values in `options`, just like in `$.fn.animate()`. 97 | 98 | ``` javascript 99 | $("#box").transition({ 100 | opacity: 0.1, scale: 0.3, 101 | duration: 500, 102 | easing: 'in', 103 | complete: function() { /* ... */ } 104 | }); 105 | ``` 106 | 107 | Tests 108 | ----- 109 | 110 | Transit has a unique test suite. Open `test/index.html` to see it. When 111 | contibuting fixes, be sure to test this out with different jQuery versions and 112 | different browsers. 113 | 114 | Alternatives 115 | ------------ 116 | 117 | __[Velocity.js](https://velocityjs.org)__ (recommended!) 118 | 119 | * Pros: optimized for situations with hundreds of simultaneous transitions. Lots of extra features. 120 | 121 | __[Move.js](https://github.com/visionmedia/move.js)__ 122 | 123 | * Pros: no jQuery dependency, great syntax. 124 | * Cons (at time of writing): no iOS support (doesn't use `translate3d`), some 125 | IE bugs, no 3D transforms, no animation queue. 126 | 127 | __[jQuery animate 128 | enhanced](https://github.com/benbarnett/jQuery-Animate-Enhanced)__ 129 | 130 | * Pros: transparently overrides `$.fn.animate()` to provide CSS transitions 131 | support. 132 | * Cons: transparently overrides `$.fn.animate()`. No transformations support. 133 | 134 | __[jQuery 2D transformations](https://github.com/heygrady/transform/)__ 135 | 136 | * Pros: Tons of transformations. 137 | * Cons: No CSS transition support; animates via `fx.step`. 138 | 139 | __[jQuery CSS3 rotate](http://plugins.jquery.com/project/Rotate)__ 140 | 141 | * Pros: simply provides rotation. 142 | * Cons: simply provides rotation. No transitions support. 143 | 144 | Support 145 | ------- 146 | 147 | __Bugs and requests__: submit them through the project's issues tracker.
148 | [![Issues](http://img.shields.io/github/issues/rstacruz/jquery.transit.svg)]( https://github.com/rstacruz/jquery.transit/issues ) 149 | 150 | __Questions__: ask them at StackOverflow with the tag *jquery-transit*.
151 | [![StackOverflow](http://img.shields.io/badge/stackoverflow-jquery--transit-brightgreen.svg)]( http://stackoverflow.com/questions/tagged/jquery-transit ) 152 | 153 | __Chat__: join us at gitter.im.
154 | [![Chat](http://img.shields.io/badge/gitter-rstacruz / jquery.transit-brightgreen.svg)]( https://gitter.im/rstacruz/jquery.transit ) 155 | 156 | Thanks 157 | ------ 158 | 159 | **jQuery Transit** © 2011-2014+, Rico Sta. Cruz. Released under the [MIT License].
160 | Authored and maintained by Rico Sta. Cruz with help from [contributors]. 161 | 162 | > [ricostacruz.com](http://ricostacruz.com)  ·  163 | > GitHub [@rstacruz](https://github.com/rstacruz)  ·  164 | > Twitter [@rstacruz](https://twitter.com/rstacruz) 165 | 166 | [MIT License]: http://mit-license.org/ 167 | [contributors]: http://github.com/rstacruz/jquery.transit/contributors 168 | 169 | [![npm version](https://img.shields.io/npm/v/jquery.transit.png)](https://npmjs.org/package/jquery.transit "View this project on npm") 170 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | ## v0.9.12 - July 17, 2014 2 | 3 | * Fix browserify builds by using the correct jQuery. ([@dminkovsky], [#201]) 4 | * Fix properties resetting after a transition. ([#204], [#205]) 5 | 6 | ## v0.9.11 - June 23, 2014 7 | 8 | * Add support for `scaleX` and `scaleY`. ([@YousefED], [#192]) 9 | * Add support for npm. 10 | * Add support for RequireJS and CommonJS. 11 | * Fix transitionend support for IE10, Chrome, and many others. ([@wambotron], [#103]) 12 | 13 | Also: 14 | 15 | * Fix `.transition({...}, {queue: false})` not being honored. ([@YousefED], [#192]) 16 | * Remove some redundant code. ([@Bongo], [#165]) 17 | * Docs: Update to support the new docco. ([@francismakes], [#175]) 18 | * Add `easeInCubic` easing. ([@emagnier], [@willblackmore], [#161], [#142]) 19 | * Add test cases for jQuery 2.0+. ([@hankhero], [#155]) 20 | 21 | The version `0.9.10` was not officially released as it was published prematurely 22 | to npm. 23 | 24 | ## v0.9.9 - Dec 14, 2012 25 | 26 | Many, many thanks to the many [contributors] who made this release happen! This 27 | is a pre-release of 1.0. 28 | 29 | ### Fixes and additions: 30 | 31 | * Fix support for jQuery 1.8, IE 10, Firefox 16, Android Jellybean. 32 | ([#48], [#62], [#63], [#69], [#70], [#71], [#72], [#76], [#77], [#80], [#81], [#82], [#85], [#86], [#90], [#92], [#93]) 33 | * Compatibility with Twitter Bootstrap has been fixed. ([#67]) 34 | * Unprefixed CSS properties are now used if your browser supports them. 35 | * Account for prefix-free transition end for Mozilla. ([#97]) 36 | * Callbacks should now be called even if duration is `0`. ([#37]) 37 | * Doing `.css('transition', 'transform 1s')` should now properly vendor-prefix 'transform'. ([#84]) 38 | * Added Penner easing splines. ([#44]) 39 | 40 | ### Internal fixes: 41 | 42 | * New test suite. 43 | * In building the website, use `fl-rocco` instead of `docco`. This removes the dependency. ([#50]) 44 | 45 | ## v0.1.3 - Feb 14, 2012 46 | 47 | ### Fixed: 48 | * Fix JS error with undefined `next` function. ([#21]) 49 | * Using `delay: 0` now works. Closes ([#20]) 50 | * More robust checking of 3D transition support. ([#19]) 51 | * Stop rotateX/rotateY/etc from stopping other transitions when it's not 52 | supported. ([#15]) 53 | 54 | ### Added: 55 | * Support Firefox 10 3D transitions. ([#19]) 56 | 57 | ### Changed: 58 | * Allow disabling using the transitionEnd property. 59 | (`$.transit.useTransitionEnd = true`) 60 | * Use the more reliable timers by default. (`useTransitionEnd` now defaults to 61 | `false`) 62 | 63 | ## v0.1.2 - Jan 24, 2012 64 | 65 | Thanks to code contributors [@ppcano], [@jeduan], [@steckel], [@weotch], and everyone 66 | who reported issues. 67 | 68 | ### Fixed: 69 | * IE8 error about .indexOf. ([#12], [#8]) 70 | * Fix z-layer scaling in Safari. ([#9], [#10]) 71 | * Fix scale elements being unclickable in WebKits. ([#9], [#10]) 72 | * Fix support for `queue: false`. ([#13]) 73 | * Clean up transitions when done. ([#14]) 74 | * Fix disappearing scaled elements in Chrome. ([#11]) 75 | * Fix a bug where the default duration and easing can sometimes not be used. 76 | 77 | ### Changed: 78 | * Make code compatible with jsHint. ([#6]) 79 | 80 | ## v0.1.1 - Nov 18, 2011 81 | 82 | ### Fixed: 83 | * Only animate what is needed (ie, don't use 'transition-property: all'). 84 | 85 | ## v0.1.0 - Nov 14, 2011 86 | 87 | Initial official release. 88 | 89 | [contributors]: https://github.com/rstacruz/jquery.transit/contributors 90 | 91 | [#201]: https://github.com/rstarcuz/jquery.transit/issues/201 92 | [@dminkovsky]: https://github.com/dminkovsky 93 | 94 | [#204]: https://github.com/rstacruz/jquery.transit/issues/204 95 | [#205]: https://github.com/rstacruz/jquery.transit/issues/205 96 | [#192]: https://github.com/rstacruz/jquery.transit/issues/192 97 | [#103]: https://github.com/rstacruz/jquery.transit/issues/103 98 | [#192]: https://github.com/rstacruz/jquery.transit/issues/192 99 | [#165]: https://github.com/rstacruz/jquery.transit/issues/165 100 | [#175]: https://github.com/rstacruz/jquery.transit/issues/175 101 | [#161]: https://github.com/rstacruz/jquery.transit/issues/161 102 | [#142]: https://github.com/rstacruz/jquery.transit/issues/142 103 | [#155]: https://github.com/rstacruz/jquery.transit/issues/155 104 | [#48]: https://github.com/rstacruz/jquery.transit/issues/48 105 | [#62]: https://github.com/rstacruz/jquery.transit/issues/62 106 | [#63]: https://github.com/rstacruz/jquery.transit/issues/63 107 | [#69]: https://github.com/rstacruz/jquery.transit/issues/69 108 | [#70]: https://github.com/rstacruz/jquery.transit/issues/70 109 | [#71]: https://github.com/rstacruz/jquery.transit/issues/71 110 | [#72]: https://github.com/rstacruz/jquery.transit/issues/72 111 | [#76]: https://github.com/rstacruz/jquery.transit/issues/76 112 | [#77]: https://github.com/rstacruz/jquery.transit/issues/77 113 | [#80]: https://github.com/rstacruz/jquery.transit/issues/80 114 | [#81]: https://github.com/rstacruz/jquery.transit/issues/81 115 | [#82]: https://github.com/rstacruz/jquery.transit/issues/82 116 | [#85]: https://github.com/rstacruz/jquery.transit/issues/85 117 | [#86]: https://github.com/rstacruz/jquery.transit/issues/86 118 | [#90]: https://github.com/rstacruz/jquery.transit/issues/90 119 | [#92]: https://github.com/rstacruz/jquery.transit/issues/92 120 | [#93]: https://github.com/rstacruz/jquery.transit/issues/93 121 | [#67]: https://github.com/rstacruz/jquery.transit/issues/67 122 | [#97]: https://github.com/rstacruz/jquery.transit/issues/97 123 | [#37]: https://github.com/rstacruz/jquery.transit/issues/37 124 | [#84]: https://github.com/rstacruz/jquery.transit/issues/84 125 | [#44]: https://github.com/rstacruz/jquery.transit/issues/44 126 | [#50]: https://github.com/rstacruz/jquery.transit/issues/50 127 | [#21]: https://github.com/rstacruz/jquery.transit/issues/21 128 | [#20]: https://github.com/rstacruz/jquery.transit/issues/20 129 | [#19]: https://github.com/rstacruz/jquery.transit/issues/19 130 | [#15]: https://github.com/rstacruz/jquery.transit/issues/15 131 | [#19]: https://github.com/rstacruz/jquery.transit/issues/19 132 | [#12]: https://github.com/rstacruz/jquery.transit/issues/12 133 | [#8]: https://github.com/rstacruz/jquery.transit/issues/8 134 | [#9]: https://github.com/rstacruz/jquery.transit/issues/9 135 | [#10]: https://github.com/rstacruz/jquery.transit/issues/10 136 | [#9]: https://github.com/rstacruz/jquery.transit/issues/9 137 | [#10]: https://github.com/rstacruz/jquery.transit/issues/10 138 | [#13]: https://github.com/rstacruz/jquery.transit/issues/13 139 | [#14]: https://github.com/rstacruz/jquery.transit/issues/14 140 | [#11]: https://github.com/rstacruz/jquery.transit/issues/11 141 | [#6]: https://github.com/rstacruz/jquery.transit/issues/6 142 | [@YousefED]: https://github.com/YousefED 143 | [@wambotron]: https://github.com/wambotron 144 | [@YousefED]: https://github.com/YousefED 145 | [@Bongo]: https://github.com/Bongo 146 | [@francismakes]: https://github.com/francismakes 147 | [@emagnier]: https://github.com/emagnier 148 | [@willblackmore]: https://github.com/willblackmore 149 | [@hankhero]: https://github.com/hankhero 150 | [@ppcano]: https://github.com/ppcano 151 | [@jeduan]: https://github.com/jeduan 152 | [@steckel]: https://github.com/steckel 153 | [@weotch]: https://github.com/weotch 154 | -------------------------------------------------------------------------------- /jquery.transit.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Transit - CSS3 transitions and transformations 3 | * (c) 2011-2014 Rico Sta. Cruz 4 | * MIT Licensed. 5 | * 6 | * http://ricostacruz.com/jquery.transit 7 | * http://github.com/rstacruz/jquery.transit 8 | */ 9 | 10 | /* jshint expr: true */ 11 | 12 | ;(function (root, factory) { 13 | 14 | if (typeof define === 'function' && define.amd) { 15 | define(['jquery'], factory); 16 | } else if (typeof exports === 'object') { 17 | module.exports = factory(require('jquery')); 18 | } else { 19 | factory(root.jQuery); 20 | } 21 | 22 | }(this, function($) { 23 | 24 | $.transit = { 25 | version: "0.9.12", 26 | 27 | // Map of $.css() keys to values for 'transitionProperty'. 28 | // See https://developer.mozilla.org/en/CSS/CSS_transitions#Properties_that_can_be_animated 29 | propertyMap: { 30 | marginLeft : 'margin', 31 | marginRight : 'margin', 32 | marginBottom : 'margin', 33 | marginTop : 'margin', 34 | paddingLeft : 'padding', 35 | paddingRight : 'padding', 36 | paddingBottom : 'padding', 37 | paddingTop : 'padding' 38 | }, 39 | 40 | // Will simply transition "instantly" if false 41 | enabled: true, 42 | 43 | // Set this to false if you don't want to use the transition end property. 44 | useTransitionEnd: false 45 | }; 46 | 47 | var div = document.createElement('div'); 48 | var support = {}; 49 | 50 | // Helper function to get the proper vendor property name. 51 | // (`transition` => `WebkitTransition`) 52 | function getVendorPropertyName(prop) { 53 | // Handle unprefixed versions (FF16+, for example) 54 | if (prop in div.style) return prop; 55 | 56 | var prefixes = ['Moz', 'Webkit', 'O', 'ms']; 57 | var prop_ = prop.charAt(0).toUpperCase() + prop.substr(1); 58 | 59 | for (var i=0; i -1; 74 | 75 | // Check for the browser's transitions support. 76 | support.transition = getVendorPropertyName('transition'); 77 | support.transitionDelay = getVendorPropertyName('transitionDelay'); 78 | support.transform = getVendorPropertyName('transform'); 79 | support.transformOrigin = getVendorPropertyName('transformOrigin'); 80 | support.filter = getVendorPropertyName('Filter'); 81 | support.transform3d = checkTransform3dSupport(); 82 | 83 | var eventNames = { 84 | 'transition': 'transitionend', 85 | 'MozTransition': 'transitionend', 86 | 'OTransition': 'oTransitionEnd', 87 | 'WebkitTransition': 'webkitTransitionEnd', 88 | 'msTransition': 'MSTransitionEnd' 89 | }; 90 | 91 | // Detect the 'transitionend' event needed. 92 | var transitionEnd = support.transitionEnd = eventNames[support.transition] || null; 93 | 94 | // Populate jQuery's `$.support` with the vendor prefixes we know. 95 | // As per [jQuery's cssHooks documentation](http://api.jquery.com/jQuery.cssHooks/), 96 | // we set $.support.transition to a string of the actual property name used. 97 | for (var key in support) { 98 | if (support.hasOwnProperty(key) && typeof $.support[key] === 'undefined') { 99 | $.support[key] = support[key]; 100 | } 101 | } 102 | 103 | // Avoid memory leak in IE. 104 | div = null; 105 | 106 | // ## $.cssEase 107 | // List of easing aliases that you can use with `$.fn.transition`. 108 | $.cssEase = { 109 | '_default': 'ease', 110 | 'in': 'ease-in', 111 | 'out': 'ease-out', 112 | 'in-out': 'ease-in-out', 113 | 'snap': 'cubic-bezier(0,1,.5,1)', 114 | // Penner equations 115 | 'easeInCubic': 'cubic-bezier(.550,.055,.675,.190)', 116 | 'easeOutCubic': 'cubic-bezier(.215,.61,.355,1)', 117 | 'easeInOutCubic': 'cubic-bezier(.645,.045,.355,1)', 118 | 'easeInCirc': 'cubic-bezier(.6,.04,.98,.335)', 119 | 'easeOutCirc': 'cubic-bezier(.075,.82,.165,1)', 120 | 'easeInOutCirc': 'cubic-bezier(.785,.135,.15,.86)', 121 | 'easeInExpo': 'cubic-bezier(.95,.05,.795,.035)', 122 | 'easeOutExpo': 'cubic-bezier(.19,1,.22,1)', 123 | 'easeInOutExpo': 'cubic-bezier(1,0,0,1)', 124 | 'easeInQuad': 'cubic-bezier(.55,.085,.68,.53)', 125 | 'easeOutQuad': 'cubic-bezier(.25,.46,.45,.94)', 126 | 'easeInOutQuad': 'cubic-bezier(.455,.03,.515,.955)', 127 | 'easeInQuart': 'cubic-bezier(.895,.03,.685,.22)', 128 | 'easeOutQuart': 'cubic-bezier(.165,.84,.44,1)', 129 | 'easeInOutQuart': 'cubic-bezier(.77,0,.175,1)', 130 | 'easeInQuint': 'cubic-bezier(.755,.05,.855,.06)', 131 | 'easeOutQuint': 'cubic-bezier(.23,1,.32,1)', 132 | 'easeInOutQuint': 'cubic-bezier(.86,0,.07,1)', 133 | 'easeInSine': 'cubic-bezier(.47,0,.745,.715)', 134 | 'easeOutSine': 'cubic-bezier(.39,.575,.565,1)', 135 | 'easeInOutSine': 'cubic-bezier(.445,.05,.55,.95)', 136 | 'easeInBack': 'cubic-bezier(.6,-.28,.735,.045)', 137 | 'easeOutBack': 'cubic-bezier(.175, .885,.32,1.275)', 138 | 'easeInOutBack': 'cubic-bezier(.68,-.55,.265,1.55)' 139 | }; 140 | 141 | // ## 'transform' CSS hook 142 | // Allows you to use the `transform` property in CSS. 143 | // 144 | // $("#hello").css({ transform: "rotate(90deg)" }); 145 | // 146 | // $("#hello").css('transform'); 147 | // //=> { rotate: '90deg' } 148 | // 149 | $.cssHooks['transit:transform'] = { 150 | // The getter returns a `Transform` object. 151 | get: function(elem) { 152 | return $(elem).data('transform') || new Transform(); 153 | }, 154 | 155 | // The setter accepts a `Transform` object or a string. 156 | set: function(elem, v) { 157 | var value = v; 158 | 159 | if (!(value instanceof Transform)) { 160 | value = new Transform(value); 161 | } 162 | 163 | // We've seen the 3D version of Scale() not work in Chrome when the 164 | // element being scaled extends outside of the viewport. Thus, we're 165 | // forcing Chrome to not use the 3d transforms as well. Not sure if 166 | // translate is affectede, but not risking it. Detection code from 167 | // http://davidwalsh.name/detecting-google-chrome-javascript 168 | if (support.transform === 'WebkitTransform' && !isChrome) { 169 | elem.style[support.transform] = value.toString(true); 170 | } else { 171 | elem.style[support.transform] = value.toString(); 172 | } 173 | 174 | $(elem).data('transform', value); 175 | } 176 | }; 177 | 178 | // Add a CSS hook for `.css({ transform: '...' })`. 179 | // In jQuery 1.8+, this will intentionally override the default `transform` 180 | // CSS hook so it'll play well with Transit. (see issue #62) 181 | $.cssHooks.transform = { 182 | set: $.cssHooks['transit:transform'].set 183 | }; 184 | 185 | // ## 'filter' CSS hook 186 | // Allows you to use the `filter` property in CSS. 187 | // 188 | // $("#hello").css({ filter: 'blur(10px)' }); 189 | // 190 | $.cssHooks.filter = { 191 | get: function(elem) { 192 | return elem.style[support.filter]; 193 | }, 194 | set: function(elem, value) { 195 | elem.style[support.filter] = value; 196 | } 197 | }; 198 | 199 | // jQuery 1.8+ supports prefix-free transitions, so these polyfills will not 200 | // be necessary. 201 | if ($.fn.jquery < "1.8") { 202 | // ## 'transformOrigin' CSS hook 203 | // Allows the use for `transformOrigin` to define where scaling and rotation 204 | // is pivoted. 205 | // 206 | // $("#hello").css({ transformOrigin: '0 0' }); 207 | // 208 | $.cssHooks.transformOrigin = { 209 | get: function(elem) { 210 | return elem.style[support.transformOrigin]; 211 | }, 212 | set: function(elem, value) { 213 | elem.style[support.transformOrigin] = value; 214 | } 215 | }; 216 | 217 | // ## 'transition' CSS hook 218 | // Allows you to use the `transition` property in CSS. 219 | // 220 | // $("#hello").css({ transition: 'all 0 ease 0' }); 221 | // 222 | $.cssHooks.transition = { 223 | get: function(elem) { 224 | return elem.style[support.transition]; 225 | }, 226 | set: function(elem, value) { 227 | elem.style[support.transition] = value; 228 | } 229 | }; 230 | } 231 | 232 | // ## Other CSS hooks 233 | // Allows you to rotate, scale and translate. 234 | registerCssHook('scale'); 235 | registerCssHook('scaleX'); 236 | registerCssHook('scaleY'); 237 | registerCssHook('translate'); 238 | registerCssHook('rotate'); 239 | registerCssHook('rotateX'); 240 | registerCssHook('rotateY'); 241 | registerCssHook('rotate3d'); 242 | registerCssHook('perspective'); 243 | registerCssHook('skewX'); 244 | registerCssHook('skewY'); 245 | registerCssHook('x', true); 246 | registerCssHook('y', true); 247 | 248 | // ## Transform class 249 | // This is the main class of a transformation property that powers 250 | // `$.fn.css({ transform: '...' })`. 251 | // 252 | // This is, in essence, a dictionary object with key/values as `-transform` 253 | // properties. 254 | // 255 | // var t = new Transform("rotate(90) scale(4)"); 256 | // 257 | // t.rotate //=> "90deg" 258 | // t.scale //=> "4,4" 259 | // 260 | // Setters are accounted for. 261 | // 262 | // t.set('rotate', 4) 263 | // t.rotate //=> "4deg" 264 | // 265 | // Convert it to a CSS string using the `toString()` and `toString(true)` (for WebKit) 266 | // functions. 267 | // 268 | // t.toString() //=> "rotate(90deg) scale(4,4)" 269 | // t.toString(true) //=> "rotate(90deg) scale3d(4,4,0)" (WebKit version) 270 | // 271 | function Transform(str) { 272 | if (typeof str === 'string') { this.parse(str); } 273 | return this; 274 | } 275 | 276 | Transform.prototype = { 277 | // ### setFromString() 278 | // Sets a property from a string. 279 | // 280 | // t.setFromString('scale', '2,4'); 281 | // // Same as set('scale', '2', '4'); 282 | // 283 | setFromString: function(prop, val) { 284 | var args = 285 | (typeof val === 'string') ? val.split(',') : 286 | (val.constructor === Array) ? val : 287 | [ val ]; 288 | 289 | args.unshift(prop); 290 | 291 | Transform.prototype.set.apply(this, args); 292 | }, 293 | 294 | // ### set() 295 | // Sets a property. 296 | // 297 | // t.set('scale', 2, 4); 298 | // 299 | set: function(prop) { 300 | var args = Array.prototype.slice.apply(arguments, [1]); 301 | if (this.setter[prop]) { 302 | this.setter[prop].apply(this, args); 303 | } else { 304 | this[prop] = args.join(','); 305 | } 306 | }, 307 | 308 | get: function(prop) { 309 | if (this.getter[prop]) { 310 | return this.getter[prop].apply(this); 311 | } else { 312 | return this[prop] || 0; 313 | } 314 | }, 315 | 316 | setter: { 317 | // ### rotate 318 | // 319 | // .css({ rotate: 30 }) 320 | // .css({ rotate: "30" }) 321 | // .css({ rotate: "30deg" }) 322 | // .css({ rotate: "30deg" }) 323 | // 324 | rotate: function(theta) { 325 | this.rotate = unit(theta, 'deg'); 326 | }, 327 | 328 | rotateX: function(theta) { 329 | this.rotateX = unit(theta, 'deg'); 330 | }, 331 | 332 | rotateY: function(theta) { 333 | this.rotateY = unit(theta, 'deg'); 334 | }, 335 | 336 | // ### scale 337 | // 338 | // .css({ scale: 9 }) //=> "scale(9,9)" 339 | // .css({ scale: '3,2' }) //=> "scale(3,2)" 340 | // 341 | scale: function(x, y) { 342 | if (y === undefined) { y = x; } 343 | this.scale = x + "," + y; 344 | }, 345 | 346 | // ### skewX + skewY 347 | skewX: function(x) { 348 | this.skewX = unit(x, 'deg'); 349 | }, 350 | 351 | skewY: function(y) { 352 | this.skewY = unit(y, 'deg'); 353 | }, 354 | 355 | // ### perspectvie 356 | perspective: function(dist) { 357 | this.perspective = unit(dist, 'px'); 358 | }, 359 | 360 | // ### x / y 361 | // Translations. Notice how this keeps the other value. 362 | // 363 | // .css({ x: 4 }) //=> "translate(4px, 0)" 364 | // .css({ y: 10 }) //=> "translate(4px, 10px)" 365 | // 366 | x: function(x) { 367 | this.set('translate', x, null); 368 | }, 369 | 370 | y: function(y) { 371 | this.set('translate', null, y); 372 | }, 373 | 374 | // ### translate 375 | // Notice how this keeps the other value. 376 | // 377 | // .css({ translate: '2, 5' }) //=> "translate(2px, 5px)" 378 | // 379 | translate: function(x, y) { 380 | if (this._translateX === undefined) { this._translateX = 0; } 381 | if (this._translateY === undefined) { this._translateY = 0; } 382 | 383 | if (x !== null && x !== undefined) { this._translateX = unit(x, 'px'); } 384 | if (y !== null && y !== undefined) { this._translateY = unit(y, 'px'); } 385 | 386 | this.translate = this._translateX + "," + this._translateY; 387 | } 388 | }, 389 | 390 | getter: { 391 | x: function() { 392 | return this._translateX || 0; 393 | }, 394 | 395 | y: function() { 396 | return this._translateY || 0; 397 | }, 398 | 399 | scale: function() { 400 | var s = (this.scale || "1,1").split(','); 401 | if (s[0]) { s[0] = parseFloat(s[0]); } 402 | if (s[1]) { s[1] = parseFloat(s[1]); } 403 | 404 | // "2.5,2.5" => 2.5 405 | // "2.5,1" => [2.5,1] 406 | return (s[0] === s[1]) ? s[0] : s; 407 | }, 408 | 409 | rotate3d: function() { 410 | var s = (this.rotate3d || "0,0,0,0deg").split(','); 411 | for (var i=0; i<=3; ++i) { 412 | if (s[i]) { s[i] = parseFloat(s[i]); } 413 | } 414 | if (s[3]) { s[3] = unit(s[3], 'deg'); } 415 | 416 | return s; 417 | } 418 | }, 419 | 420 | // ### parse() 421 | // Parses from a string. Called on constructor. 422 | parse: function(str) { 423 | var self = this; 424 | str.replace(/([a-zA-Z0-9]+)\((.*?)\)/g, function(x, prop, val) { 425 | self.setFromString(prop, val); 426 | }); 427 | }, 428 | 429 | // ### toString() 430 | // Converts to a `transition` CSS property string. If `use3d` is given, 431 | // it converts to a `-webkit-transition` CSS property string instead. 432 | toString: function(use3d) { 433 | var re = []; 434 | 435 | for (var i in this) { 436 | if (this.hasOwnProperty(i)) { 437 | // Don't use 3D transformations if the browser can't support it. 438 | if ((!support.transform3d) && ( 439 | (i === 'rotateX') || 440 | (i === 'rotateY') || 441 | (i === 'perspective') || 442 | (i === 'transformOrigin'))) { continue; } 443 | 444 | if (i[0] !== '_') { 445 | if (use3d && (i === 'scale')) { 446 | re.push(i + "3d(" + this[i] + ",1)"); 447 | } else if (use3d && (i === 'translate')) { 448 | re.push(i + "3d(" + this[i] + ",0)"); 449 | } else { 450 | re.push(i + "(" + this[i] + ")"); 451 | } 452 | } 453 | } 454 | } 455 | 456 | return re.join(" "); 457 | } 458 | }; 459 | 460 | function callOrQueue(self, queue, fn) { 461 | if (queue === true) { 462 | self.queue(fn); 463 | } else if (queue) { 464 | self.queue(queue, fn); 465 | } else { 466 | self.each(function () { 467 | fn.call(this); 468 | }); 469 | } 470 | } 471 | 472 | // ### getProperties(dict) 473 | // Returns properties (for `transition-property`) for dictionary `props`. The 474 | // value of `props` is what you would expect in `$.css(...)`. 475 | function getProperties(props) { 476 | var re = []; 477 | 478 | $.each(props, function(key) { 479 | key = $.camelCase(key); // Convert "text-align" => "textAlign" 480 | key = $.transit.propertyMap[key] || $.cssProps[key] || key; 481 | key = uncamel(key); // Convert back to dasherized 482 | 483 | // Get vendor specify propertie 484 | if (support[key]) 485 | key = uncamel(support[key]); 486 | 487 | if ($.inArray(key, re) === -1) { re.push(key); } 488 | }); 489 | 490 | return re; 491 | } 492 | 493 | // ### getTransition() 494 | // Returns the transition string to be used for the `transition` CSS property. 495 | // 496 | // Example: 497 | // 498 | // getTransition({ opacity: 1, rotate: 30 }, 500, 'ease'); 499 | // //=> 'opacity 500ms ease, -webkit-transform 500ms ease' 500 | // 501 | function getTransition(properties, duration, easing, delay) { 502 | // Get the CSS properties needed. 503 | var props = getProperties(properties); 504 | 505 | // Account for aliases (`in` => `ease-in`). 506 | if ($.cssEase[easing]) { easing = $.cssEase[easing]; } 507 | 508 | // Build the duration/easing/delay attributes for it. 509 | var attribs = '' + toMS(duration) + ' ' + easing; 510 | if (parseInt(delay, 10) > 0) { attribs += ' ' + toMS(delay); } 511 | 512 | // For more properties, add them this way: 513 | // "margin 200ms ease, padding 200ms ease, ..." 514 | var transitions = []; 515 | $.each(props, function(i, name) { 516 | transitions.push(name + ' ' + attribs); 517 | }); 518 | 519 | return transitions.join(', '); 520 | } 521 | 522 | // ## $.fn.transition 523 | // Works like $.fn.animate(), but uses CSS transitions. 524 | // 525 | // $("...").transition({ opacity: 0.1, scale: 0.3 }); 526 | // 527 | // // Specific duration 528 | // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500); 529 | // 530 | // // With duration and easing 531 | // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in'); 532 | // 533 | // // With callback 534 | // $("...").transition({ opacity: 0.1, scale: 0.3 }, function() { ... }); 535 | // 536 | // // With everything 537 | // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in', function() { ... }); 538 | // 539 | // // Alternate syntax 540 | // $("...").transition({ 541 | // opacity: 0.1, 542 | // duration: 200, 543 | // delay: 40, 544 | // easing: 'in', 545 | // complete: function() { /* ... */ } 546 | // }); 547 | // 548 | $.fn.transition = $.fn.transit = function(properties, duration, easing, callback) { 549 | var self = this; 550 | var delay = 0; 551 | var queue = true; 552 | 553 | var theseProperties = $.extend(true, {}, properties); 554 | 555 | // Account for `.transition(properties, callback)`. 556 | if (typeof duration === 'function') { 557 | callback = duration; 558 | duration = undefined; 559 | } 560 | 561 | // Account for `.transition(properties, options)`. 562 | if (typeof duration === 'object') { 563 | easing = duration.easing; 564 | delay = duration.delay || 0; 565 | queue = typeof duration.queue === "undefined" ? true : duration.queue; 566 | callback = duration.complete; 567 | duration = duration.duration; 568 | } 569 | 570 | // Account for `.transition(properties, duration, callback)`. 571 | if (typeof easing === 'function') { 572 | callback = easing; 573 | easing = undefined; 574 | } 575 | 576 | // Alternate syntax. 577 | if (typeof theseProperties.easing !== 'undefined') { 578 | easing = theseProperties.easing; 579 | delete theseProperties.easing; 580 | } 581 | 582 | if (typeof theseProperties.duration !== 'undefined') { 583 | duration = theseProperties.duration; 584 | delete theseProperties.duration; 585 | } 586 | 587 | if (typeof theseProperties.complete !== 'undefined') { 588 | callback = theseProperties.complete; 589 | delete theseProperties.complete; 590 | } 591 | 592 | if (typeof theseProperties.queue !== 'undefined') { 593 | queue = theseProperties.queue; 594 | delete theseProperties.queue; 595 | } 596 | 597 | if (typeof theseProperties.delay !== 'undefined') { 598 | delay = theseProperties.delay; 599 | delete theseProperties.delay; 600 | } 601 | 602 | // Set defaults. (`400` duration, `ease` easing) 603 | if (typeof duration === 'undefined') { duration = $.fx.speeds._default; } 604 | if (typeof easing === 'undefined') { easing = $.cssEase._default; } 605 | 606 | duration = toMS(duration); 607 | 608 | // Build the `transition` property. 609 | var transitionValue = getTransition(theseProperties, duration, easing, delay); 610 | 611 | // Compute delay until callback. 612 | // If this becomes 0, don't bother setting the transition property. 613 | var work = $.transit.enabled && support.transition; 614 | var i = work ? (parseInt(duration, 10) + parseInt(delay, 10)) : 0; 615 | 616 | // If there's nothing to do... 617 | if (i === 0) { 618 | var fn = function(next) { 619 | self.css(theseProperties); 620 | if (callback) { callback.apply(self); } 621 | if (next) { next(); } 622 | }; 623 | 624 | callOrQueue(self, queue, fn); 625 | return self; 626 | } 627 | 628 | // Save the old transitions of each element so we can restore it later. 629 | var oldTransitions = {}; 630 | 631 | var run = function(nextCall) { 632 | var bound = false; 633 | 634 | // Prepare the callback. 635 | var cb = function() { 636 | if (bound) { self.unbind(transitionEnd, cb); } 637 | 638 | if (i > 0) { 639 | self.each(function() { 640 | this.style[support.transition] = (oldTransitions[this] || null); 641 | }); 642 | } 643 | 644 | if (typeof callback === 'function') { callback.apply(self); } 645 | if (typeof nextCall === 'function') { nextCall(); } 646 | }; 647 | 648 | if ((i > 0) && (transitionEnd) && ($.transit.useTransitionEnd)) { 649 | // Use the 'transitionend' event if it's available. 650 | bound = true; 651 | self.bind(transitionEnd, cb); 652 | } else { 653 | // Fallback to timers if the 'transitionend' event isn't supported. 654 | window.setTimeout(cb, i); 655 | } 656 | 657 | // Apply transitions. 658 | self.each(function() { 659 | if (i > 0) { 660 | this.style[support.transition] = transitionValue; 661 | } 662 | $(this).css(theseProperties); 663 | }); 664 | }; 665 | 666 | // Defer running. This allows the browser to paint any pending CSS it hasn't 667 | // painted yet before doing the transitions. 668 | var deferredRun = function(next) { 669 | this.offsetWidth = this.offsetWidth; // force a repaint 670 | run(next); 671 | }; 672 | 673 | // Use jQuery's fx queue. 674 | callOrQueue(self, queue, deferredRun); 675 | 676 | // Chainability. 677 | return this; 678 | }; 679 | 680 | function registerCssHook(prop, isPixels) { 681 | // For certain properties, the 'px' should not be implied. 682 | if (!isPixels) { $.cssNumber[prop] = true; } 683 | 684 | $.transit.propertyMap[prop] = support.transform; 685 | 686 | $.cssHooks[prop] = { 687 | get: function(elem) { 688 | var t = $(elem).css('transit:transform'); 689 | return t.get(prop); 690 | }, 691 | 692 | set: function(elem, value) { 693 | var t = $(elem).css('transit:transform'); 694 | t.setFromString(prop, value); 695 | 696 | $(elem).css({ 'transit:transform': t }); 697 | } 698 | }; 699 | 700 | } 701 | 702 | // ### uncamel(str) 703 | // Converts a camelcase string to a dasherized string. 704 | // (`marginLeft` => `margin-left`) 705 | function uncamel(str) { 706 | return str.replace(/([A-Z])/g, function(letter) { return '-' + letter.toLowerCase(); }); 707 | } 708 | 709 | // ### unit(number, unit) 710 | // Ensures that number `number` has a unit. If no unit is found, assume the 711 | // default is `unit`. 712 | // 713 | // unit(2, 'px') //=> "2px" 714 | // unit("30deg", 'rad') //=> "30deg" 715 | // 716 | function unit(i, units) { 717 | if ((typeof i === "string") && (!i.match(/^[\-0-9\.]+$/))) { 718 | return i; 719 | } else { 720 | return "" + i + units; 721 | } 722 | } 723 | 724 | // ### toMS(duration) 725 | // Converts given `duration` to a millisecond string. 726 | // 727 | // toMS('fast') => $.fx.speeds[i] => "200ms" 728 | // toMS('normal') //=> $.fx.speeds._default => "400ms" 729 | // toMS(10) //=> '10ms' 730 | // toMS('100ms') //=> '100ms' 731 | // 732 | function toMS(duration) { 733 | var i = duration; 734 | 735 | // Allow string durations like 'fast' and 'slow', without overriding numeric values. 736 | if (typeof i === 'string' && (!i.match(/^[\-0-9\.]+/))) { i = $.fx.speeds[i] || $.fx.speeds._default; } 737 | 738 | return unit(i, 'ms'); 739 | } 740 | 741 | // Export some functions for testable-ness. 742 | $.transit.getTransitionValue = getTransition; 743 | 744 | return $; 745 | })); 746 | --------------------------------------------------------------------------------