├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .versions ├── README.md ├── example ├── .gitignore ├── .meteor │ ├── .finished-upgraders │ ├── .gitignore │ ├── .id │ ├── packages │ ├── platforms │ ├── release │ └── versions ├── README.md ├── client │ ├── main.coffee │ ├── main.html │ └── main.less └── router.coffee ├── lib ├── transitioner.coffee ├── transitioner.css └── transitioner.html └── package.js /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | This project is not unmaintained. Please let me know if you'd like to maintain this project. -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | This project is not unmaintained. Please let me know if you'd like to maintain this project. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | .versions -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | application-configuration@1.0.4 2 | base64@1.0.2 3 | binary-heap@1.0.2 4 | blaze@2.0.4 5 | blaze-tools@1.0.2 6 | boilerplate-generator@1.0.2 7 | callback-hook@1.0.2 8 | ccorcos:transitioner@2.0.1 9 | check@1.0.4 10 | coffeescript@1.0.5 11 | ddp@1.0.14 12 | deps@1.0.6 13 | ejson@1.0.5 14 | follower-livedata@1.0.3 15 | geojson-utils@1.0.2 16 | html-tools@1.0.3 17 | htmljs@1.0.3 18 | id-map@1.0.2 19 | iron:controller@1.0.7 20 | iron:core@1.0.7 21 | iron:dynamic-template@1.0.7 22 | iron:layout@1.0.7 23 | iron:location@1.0.7 24 | iron:middleware-stack@1.0.7 25 | iron:router@1.0.7 26 | iron:url@1.0.7 27 | jquery@1.11.3 28 | json@1.0.2 29 | logging@1.0.6 30 | meteor@1.1.4 31 | minifiers@1.1.3 32 | minimongo@1.0.6 33 | mongo@1.0.11 34 | observe-sequence@1.0.4 35 | ordered-dict@1.0.2 36 | random@1.0.2 37 | reactive-dict@1.0.5 38 | reactive-var@1.0.4 39 | retry@1.0.2 40 | routepolicy@1.0.4 41 | spacebars@1.0.5 42 | spacebars-compiler@1.0.4 43 | templating@1.0.11 44 | tracker@1.0.5 45 | ui@1.0.5 46 | underscore@1.0.2 47 | velocityjs:velocityjs@1.2.1 48 | webapp@1.1.6 49 | webapp-hashing@1.0.2 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Iron Router Transitioner [MAINTAINER WANTED] 2 | 3 | Finally, animations between routes! This package is tightly integrated with [Iron Router](https://github.com/EventedMind/iron-router) and [VelocityJS](http://julian.com/research/velocity/). 4 | 5 | Check out the [live demo](http://ccorcos-transitioner.meteor.com). 6 | 7 | ## To Do 8 | 9 | - prevent the flash when force feeding. how does he register his effects? 10 | - Expand the set of animations with Velocity.RegisterEffect 11 | - Create a new demo with a dropdown menu of effects 12 | - Support default animation 13 | - How to handle iron router `waitOn`? 14 | 15 | ## Getting Started 16 | 17 | meteor add ccorcos:transitioner 18 | 19 | First you need to add Iron Router and make some routes. Then you'll need to wrap the `{{>yield}}` in your iron layout with the transitioner block helpers: 20 | 21 | {{#transitioner}} 22 | {{> yield}} 23 | {{/transitioner}} 24 | 25 | Then you can specify transitions between routes using the following: 26 | 27 | Transitioner.transition({ 28 | fromRoute: 'fromRouteName', 29 | toRoute: 'toRouteName', 30 | velocityAnimation: { 31 | in: animation, 32 | out: animation 33 | } 34 | }) 35 | 36 | An `animation` can be one of three things. 37 | 38 | 1. The easiest is to pass a [VelocityJS UI Pack pre-registered effect](http://julian.com/research/velocity/#uiPack) as a string. For example, 'transition.swoopIn', 'transition.whirlOut', 'transition.slideLeftIn', etc. [A you can find a demo of these effects in the dropdown of the "Effects: Pre-Registered" section](http://julian.com/research/velocity/#uiPack). [You can also check out the source to see how to register your own effects](https://github.com/julianshapiro/velocity/blob/master/velocity.ui.js#L299). For example: 39 | 40 | $.Velocity.RegisterEffect 'transition.pushLeftIn', 41 | defaultDuration: 500, 42 | calls: [ 43 | [{translateX: ['0%', '-100%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 44 | ] 45 | 46 | Setting `translateZ` enforces GPU usage and the `opacity: [1, 1]` dummy variable [prevents a flash at the beginning of the animation](https://github.com/julianshapiro/velocity/issues/422#issuecomment-74593585). 47 | 48 | 2. If you want to pass options like easing or duration, you pass an array of velocity arguements. 49 | 50 | 3. You can create custom animations just like you would with `_uihooks.insertElement` and `_uihooks.removeElement`. For example: 51 | 52 | slideRight = 53 | in: (node, next) -> 54 | $node = $(node) 55 | $.Velocity.hook($node, "translateX", "100%"); 56 | $node.insertBefore(next) 57 | .velocity {translateX: ['0%', '100%']}, 58 | duration: 500 59 | easing: 'ease-in-out' 60 | queue: false 61 | out: (node) -> 62 | $node = $(node) 63 | $node.velocity {translateX: '-100%'}, 64 | duration: 500 65 | easing: 'ease-in-out' 66 | queue: false 67 | complete: -> 68 | $node.remove() 69 | 70 | You can also set a default animation between all routes using `Transitioner.defualt`. For example: 71 | 72 | Transitioner.default 73 | in: 'transition.fadeIn' 74 | out: 'transition.fadeOut' 75 | 76 | ## Recommendations 77 | 78 | Build your app such that every page has it's own self-contained style. You'll also need every div up to your transitioner to have a specified height and width, typically 100%. -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | *DS_Store 2 | packages/ -------------------------------------------------------------------------------- /example/.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | -------------------------------------------------------------------------------- /example/.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /example/.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | rcfqee1y4yh383gy17t 8 | -------------------------------------------------------------------------------- /example/.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-platform 8 | autopublish 9 | insecure 10 | coffeescript 11 | iron:router 12 | velocityjs:velocityjs 13 | less 14 | ccorcos:transitioner 15 | -------------------------------------------------------------------------------- /example/.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /example/.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.0.3.1 2 | -------------------------------------------------------------------------------- /example/.meteor/versions: -------------------------------------------------------------------------------- 1 | application-configuration@1.0.4 2 | autopublish@1.0.2 3 | autoupdate@1.1.5 4 | base64@1.0.2 5 | binary-heap@1.0.2 6 | blaze@2.0.4 7 | blaze-tools@1.0.2 8 | boilerplate-generator@1.0.2 9 | callback-hook@1.0.2 10 | ccorcos:transitioner@2.0.1 11 | check@1.0.4 12 | coffeescript@1.0.5 13 | ddp@1.0.14 14 | deps@1.0.6 15 | ejson@1.0.5 16 | fastclick@1.0.2 17 | follower-livedata@1.0.3 18 | geojson-utils@1.0.2 19 | html-tools@1.0.3 20 | htmljs@1.0.3 21 | http@1.0.10 22 | id-map@1.0.2 23 | insecure@1.0.2 24 | iron:controller@1.0.7 25 | iron:core@1.0.7 26 | iron:dynamic-template@1.0.7 27 | iron:layout@1.0.7 28 | iron:location@1.0.7 29 | iron:middleware-stack@1.0.7 30 | iron:router@1.0.7 31 | iron:url@1.0.7 32 | jquery@1.11.3 33 | json@1.0.2 34 | launch-screen@1.0.1 35 | less@1.0.12 36 | livedata@1.0.12 37 | logging@1.0.6 38 | meteor@1.1.4 39 | meteor-platform@1.2.1 40 | minifiers@1.1.3 41 | minimongo@1.0.6 42 | mobile-status-bar@1.0.2 43 | mongo@1.0.11 44 | observe-sequence@1.0.4 45 | ordered-dict@1.0.2 46 | random@1.0.2 47 | reactive-dict@1.0.5 48 | reactive-var@1.0.4 49 | reload@1.1.2 50 | retry@1.0.2 51 | routepolicy@1.0.4 52 | session@1.0.5 53 | spacebars@1.0.5 54 | spacebars-compiler@1.0.4 55 | templating@1.0.11 56 | tracker@1.0.5 57 | ui@1.0.5 58 | underscore@1.0.2 59 | url@1.0.3 60 | velocityjs:velocityjs@1.2.1 61 | webapp@1.1.6 62 | webapp-hashing@1.0.2 63 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Iron Router Transitioner [Demo](http://ccorcos-transitioner.meteor.com) 2 | 3 | This demo shows how to use [`ccorcos:transitioner`](https://github.com/ccorcos/meteor-transitioner) package to transition between Iron Router routes. Its as simple as creating some routes and wiring them together using `Transitioner.transition`. -------------------------------------------------------------------------------- /example/client/main.coffee: -------------------------------------------------------------------------------- 1 | # Flash Error 2 | # http://codepen.io/anon/pen/jELLgN 3 | 4 | $.Velocity.RegisterEffect 'transition.pushRightIn', 5 | defaultDuration: 500, 6 | calls: [ 7 | [{translateX: ['0%', '100%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 8 | ] 9 | 10 | $.Velocity.RegisterEffect 'transition.pushLeftOut', 11 | defaultDuration: 500, 12 | calls: [ 13 | [{translateX: ['-100%', '0%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 14 | ] 15 | 16 | $.Velocity.RegisterEffect 'transition.pushLeftIn', 17 | defaultDuration: 500, 18 | calls: [ 19 | [{translateX: ['0%', '-100%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 20 | ] 21 | 22 | $.Velocity.RegisterEffect 'transition.pushRightOut', 23 | defaultDuration: 500, 24 | calls: [ 25 | [{translateX: ['100%', '0%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 26 | ] 27 | 28 | $.Velocity.RegisterEffect 'transition.pushDownIn', 29 | defaultDuration: 500, 30 | calls: [ 31 | [{translateY: ['0%', '100%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 32 | ] 33 | 34 | $.Velocity.RegisterEffect 'transition.pushUpOut', 35 | defaultDuration: 500, 36 | calls: [ 37 | [{translateY: ['-100%', '0%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 38 | ] 39 | 40 | $.Velocity.RegisterEffect 'transition.pushUpIn', 41 | defaultDuration: 500, 42 | calls: [ 43 | [{translateY: ['0%', '-100%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 44 | ] 45 | 46 | $.Velocity.RegisterEffect 'transition.pushDownOut', 47 | defaultDuration: 500, 48 | calls: [ 49 | [{translateY: ['100%', '0%'], translateZ: 0, easing: "ease-in-out", opacity: [1, 1]}] 50 | ] 51 | 52 | 53 | Transitioner.transition 54 | fromRoute: 'main' 55 | toRoute: 'slideRight' 56 | velocityAnimation: 57 | in: 'transition.slideRightBigIn' 58 | out: 'transition.slideLeftBigOut' 59 | 60 | Transitioner.transition 61 | fromRoute: 'slideRight' 62 | toRoute: 'main' 63 | velocityAnimation: 64 | in: 'transition.slideLeftBigIn' 65 | out: 'transition.slideRightBigOut' 66 | 67 | 68 | Transitioner.transition 69 | fromRoute: 'main' 70 | toRoute: 'slideLeft' 71 | velocityAnimation: 72 | in: 'transition.pushLeftIn' 73 | out: 'transition.pushRightOut' 74 | 75 | Transitioner.transition 76 | fromRoute: 'slideLeft' 77 | toRoute: 'main' 78 | velocityAnimation: 79 | in: 'transition.pushRightIn' 80 | out:'transition.pushLeftOut' 81 | 82 | 83 | Transitioner.transition 84 | fromRoute: 'main' 85 | toRoute: 'slideUp' 86 | velocityAnimation: 87 | in: 'transition.perspectiveUpIn' 88 | out: 'transition.perspectiveDownOut' 89 | 90 | Transitioner.transition 91 | fromRoute: 'slideUp' 92 | toRoute: 'main' 93 | velocityAnimation: 94 | in: ['transition.perspectiveDownIn', {duration: 2000, easing: 'ease-out'}] 95 | out: ['transition.perspectiveUpOut', {duration: 2000, easing: 'ease-out'}] 96 | 97 | Transitioner.transition 98 | fromRoute: 'main' 99 | toRoute: 'slideDown' 100 | velocityAnimation: 101 | in: 'transition.pushDownIn' 102 | out: 'transition.pushUpOut' 103 | 104 | Transitioner.transition 105 | fromRoute: 'slideDown' 106 | toRoute: 'main' 107 | velocityAnimation: 108 | in: 'transition.pushUpIn' 109 | out: 'transition.pushDownOut' 110 | 111 | # RESORT TO DEFAULT 112 | 113 | # Transitioner.transition 114 | # fromRoute: 'main' 115 | # toRoute: 'fade' 116 | # velocityAnimation: 117 | # in: 'transition.fadeIn' 118 | # out: 'transition.fadeOut' 119 | 120 | # Transitioner.transition 121 | # fromRoute: 'fade' 122 | # toRoute: 'main' 123 | # velocityAnimation: 124 | # in: 'transition.fadeIn' 125 | # out: 'transition.fadeOut' 126 | 127 | Transitioner.default 128 | in: 'transition.fadeIn' 129 | out: 'transition.fadeOut' 130 | -------------------------------------------------------------------------------- /example/client/main.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 44 | 45 | -------------------------------------------------------------------------------- /example/client/main.less: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | width: 100%; 4 | margin: 0; 5 | padding: 0; 6 | background-color: #1a40b5; 7 | } 8 | 9 | 10 | 11 | .main { 12 | background-color: #1a40b5; 13 | color: white; 14 | } 15 | 16 | .slideRight { 17 | background-color: #ff4b2f; 18 | } 19 | 20 | .slideLeft { 21 | background-color: #53e562; 22 | } 23 | 24 | .slideUp { 25 | background-color: #b73cbf; 26 | } 27 | 28 | .slideDown { 29 | background-color: #e6e728; 30 | color: black; 31 | } 32 | 33 | .fade { 34 | background-color: white; 35 | color: black; 36 | } 37 | 38 | .reverse { 39 | background-color: black; 40 | color: white; 41 | } 42 | 43 | .buttons { 44 | position: absolute; 45 | width: 140px; 46 | height: 350; // 60 * 5 + 10*5 47 | top: ~"calc(50% - 175px)"; 48 | left: ~"calc(50% - 70px)"; 49 | } 50 | 51 | .button { 52 | width: 140px; 53 | height: 60px; 54 | border-radius: 10px; 55 | text-align: center; 56 | line-height: 60px; 57 | margin-bottom: 10px; 58 | } 59 | 60 | a { 61 | appearance: none; 62 | text-decoration: none; 63 | color: inherit; 64 | } -------------------------------------------------------------------------------- /example/router.coffee: -------------------------------------------------------------------------------- 1 | Router.configure 2 | layoutTemplate: 'layout' 3 | 4 | Router.route 'main', 5 | path: '/' 6 | 7 | Router.route 'slideRight' 8 | Router.route 'slideLeft' 9 | Router.route 'slideUp' 10 | Router.route 'slideDown' 11 | Router.route 'fade' -------------------------------------------------------------------------------- /lib/transitioner.coffee: -------------------------------------------------------------------------------- 1 | class TransitionerClass 2 | constructor: () -> 3 | @transitions = [] 4 | 5 | default: (velocityAnimation) -> 6 | unless velocityAnimation?.in? 7 | console.log 'ERROR: velocityAnimation must contain a velocityAnimation.in' 8 | return 9 | unless velocityAnimation?.out? 10 | console.log 'ERROR: velocityAnimation must contain a velocityAnimation.out' 11 | return 12 | @defaultVelocityAnimation = velocityAnimation 13 | 14 | transition: (obj) -> 15 | unless obj?.fromRoute? 16 | console.log 'ERROR: transition object must contain a fromRoute' 17 | return 18 | unless obj?.toRoute? 19 | console.log 'ERROR: transition object must contain a toRoute' 20 | return 21 | unless obj?.velocityAnimation? 22 | console.log 'ERROR: transition object must contain a velocityAnimation' 23 | return 24 | unless obj?.velocityAnimation?.in? 25 | console.log 'ERROR: transition object must contain a velocityAnimation.in' 26 | return 27 | unless obj?.velocityAnimation?.out? 28 | console.log 'ERROR: transition object must contain a velocityAnimation.out' 29 | return 30 | @transitions.push obj 31 | 32 | getAnimation: (fromRoute, toRoute) -> 33 | transitionObj = _.find @transitions, (transition) -> 34 | transition.fromRoute is fromRoute and transition.toRoute is toRoute 35 | 36 | if transitionObj 37 | return transitionObj.velocityAnimation 38 | else if @defaultVelocityAnimation 39 | return @defaultVelocityAnimation 40 | else 41 | return { 42 | in: (node, next) -> 43 | $(node).insertBefore(next) 44 | out: (node) -> 45 | $(node).remove() 46 | } 47 | if transitionObj?.animationName and transitionObj?.animationName of @animations 48 | return @animations[transitionObj.animationName](transitionObj.duration, transitionObj.easing) 49 | else 50 | return @animations[@default]() 51 | 52 | 53 | # velocityAnimation is: 54 | # { 55 | # in: insertElement function or velocity uipack string or velocity animation arguments 56 | # out: removeElement function or velocity uipack string or velocity animation arguments 57 | # } 58 | 59 | 60 | Transitioner = new TransitionerClass() 61 | 62 | # Make unique transitioner divs. 63 | counter = () -> 64 | count = 0 65 | return () -> count++ 66 | 67 | uniqueIdMaker = counter() 68 | 69 | Template.transitioner.created = -> 70 | @id = uniqueIdMaker() 71 | 72 | Template.transitioner.helpers 73 | id: () -> Template.instance().id 74 | 75 | 76 | fromRoute = null 77 | toRoute = null 78 | 79 | Meteor.startup -> 80 | Tracker.autorun -> 81 | fromRoute = toRoute 82 | toRoute = Router.current()?.route?.getName?() 83 | 84 | Template.transitioner.rendered = -> 85 | 86 | @find("#transitioner-"+@id)?._uihooks = 87 | insertElement: (node, next) -> 88 | animation = Transitioner.getAnimation(fromRoute, toRoute) 89 | if _.isFunction animation?.in 90 | animation.in.apply this, [node, next] 91 | else if _.isString animation?.in 92 | $(node).insertBefore(next) 93 | .velocity animation.in 94 | else if _.isArray animation?.in 95 | $node = $(node) 96 | $node.insertBefore(next) 97 | .velocity.apply($node, animation.in) 98 | else 99 | console.log "ERROR: animation.in not found!!" 100 | $(node).insertBefore(next) 101 | 102 | removeElement: (node) -> 103 | animation = Transitioner.getAnimation(fromRoute, toRoute) 104 | if _.isFunction animation?.out 105 | animation.out.apply this, [node] 106 | else if _.isString animation?.out 107 | $node = $(node) 108 | $node.velocity animation.out, 109 | complete: -> $node.remove() 110 | else if _.isArray animation?.out 111 | $node = $(node) 112 | animation.out.push -> 113 | $node.remove() 114 | $node.velocity.apply($node, animation.out) 115 | else 116 | console.log "ERROR: animation.out not found!!" 117 | $(node).remove() 118 | -------------------------------------------------------------------------------- /lib/transitioner.css: -------------------------------------------------------------------------------- 1 | .transitioner { 2 | height: 100%; 3 | width: 100%; 4 | overflow: hidden; 5 | position: relative; 6 | } 7 | 8 | .transitioner>div { 9 | height: 100%; 10 | width: 100%; 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | } -------------------------------------------------------------------------------- /lib/transitioner.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'ccorcos:transitioner', 3 | summary: 'Page transitions integrated with Iron Router.', 4 | version: '2.0.2', 5 | git: 'https://github.com/ccorcos/meteor-transitioner' 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.versionsFrom('METEOR@1'); 10 | 11 | api.use([ 12 | 'velocityjs:velocityjs@1.2.0', 13 | 'iron:router@1.0.0', 14 | 'coffeescript', 15 | 'templating', 16 | 'underscore' 17 | ], 'client'); 18 | 19 | api.addFiles([ 20 | 'lib/transitioner.css', 21 | 'lib/transitioner.html', 22 | 'lib/transitioner.coffee', 23 | ], 'client'); 24 | 25 | api.export('Transitioner', ['client']); 26 | 27 | }); --------------------------------------------------------------------------------