Last active
December 24, 2015 08:39
-
-
Save nicoburns/6772469 to your computer and use it in GitHub Desktop.
Example of a "RegionGroup" Backbone view, which can be used to easily animate between two views.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class='regiongroup'> | |
| <div class='region'>Initial RegionGroup content</div> | |
| <div class='region region-hidden'></div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| define(function(require, exports, module) { | |
| var View = require("./view"); | |
| var _ = require("lodash"); | |
| var ViewCache = require("core/viewcache"); | |
| var renderloop = require("core/renderloop"); | |
| var RegionGroup = View.extend({ | |
| initialize: function (options) { | |
| this.regions = []; | |
| this.createRegions(); | |
| }, | |
| update: function (params) { | |
| var regiongroup = this; | |
| // startTransition is passed the return value from createTransition | |
| return this.prepareNextRegion(params.view) | |
| .then(function () { | |
| return regiongroup.createTransition(params.view, params.transition); | |
| }) | |
| .then(function (transition) { | |
| return regiongroup.startTransition(transition); | |
| }); | |
| }, | |
| // Create Region views from the immediate children of 'el' | |
| createRegions: function () { | |
| _.each(this.el.children, function (regionElement) { | |
| // Create region from element | |
| var region = new View({"el": regionElement}); | |
| // Push region to regions array | |
| this.regions.push(region); | |
| if (!/region\-hidden/.test(regionElement.className)) { | |
| this.activeRegion = region; | |
| } | |
| }, this); | |
| }, | |
| prepareNextRegion: function (view) { | |
| return this.prepareRegion(1, view); | |
| }, | |
| prepareRegion: function (index, view) { | |
| var region = this.regions[index]; | |
| // Update the region's content view | |
| return $.when( region.updateRegion(view) ) | |
| .then(function () { | |
| // If view is already rendered, append it's 'el' | |
| if (view.isCacheRender) { | |
| region.el.appendChild(view.el); | |
| } | |
| // Else render the view | |
| else { | |
| return view.render().promise(); | |
| } | |
| }); | |
| }, | |
| createTransition: function (view, transitionParams) { | |
| var transitionOptions = _.extend({}, transitionParams, { | |
| type: null, | |
| view: view, | |
| id: _.uniqueId(), | |
| regions: this.regions | |
| }); | |
| var Transition = transitionParams.type; | |
| return new Transition(transitionOptions); | |
| }, | |
| startTransition: function (transition) { | |
| // Create progress promise | |
| transition.progress = $.Deferred(); | |
| // Call 'animationStart' callback | |
| transition.animationStart(); | |
| // Show the incoming region | |
| transition.newRegion.el.style.display = "block"; | |
| // Run the '_runTransition' function | |
| renderloop.addPersistentTask("transition" + transition.id, this._runTransition, this, [transition]); | |
| return transition.progress; | |
| }, | |
| _runTransition: function (transition, timestamp) { | |
| // Hack because timestamp passed in requestAnimationFrame is inconsistent between browsers | |
| if (!transition.startTime) { | |
| transition.startTime = timestamp; | |
| return; | |
| } | |
| // Calcuate percentDone | |
| transition.percentDone = Math.min(1, ((timestamp - transition.startTime) / transition.options.duration)); | |
| // Call 'animationFrame' callback | |
| transition.animationFrame.call(transition); | |
| // If transition is 100% done, stop running this function and call '_endTransition' | |
| if (transition.percentDone === 1) { | |
| renderloop.removePersistentTask("transition" + transition.id); | |
| this._endTransition(transition); | |
| } | |
| }, | |
| _endTransition: function (transition) { | |
| // Call the 'animationEnd' callback | |
| transition.animationEnd(); | |
| // Hide the old region | |
| transition.activeRegion.el.style.display = "none"; | |
| // Remove the contents of old region | |
| var oldViews = transition.activeRegion.getViews(); | |
| oldViews.each(function (view) { | |
| if (view.cacheName) { | |
| ViewCache.cacheView(view); | |
| } | |
| else { | |
| view.remove(); | |
| } | |
| }); | |
| // Swap active region reference | |
| this.regions.push( this.regions.shift() ); | |
| // Call view callback | |
| if (transition.view) { | |
| transition.view.trigger("afterAnimation"); | |
| if (transition.view.afterAnimation) transition.view.afterAnimation(); | |
| } | |
| transition.progress.resolve(); | |
| } | |
| }); | |
| module.exports = RegionGroup; | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .regiongroup { | |
| position: relative; | |
| } | |
| .region { | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| width: 100%; | |
| -webkit-transform: translate3d(0, 0, 0); | |
| -webkit-backface-visibility: hidden; | |
| //-webkit-perspective: 1000; | |
| > * { | |
| -webkit-transform: translate3d(0, 0, 0); | |
| } | |
| } | |
| .region-hidden { | |
| display: none; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment