Created
September 18, 2015 20:24
-
-
Save chukcha-wtf/3c042755cc000f9ce61d to your computer and use it in GitHub Desktop.
Example of using liquid-fire and ember-cli-f7 to animate page transitions
This file contains 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
// app/routes/about.js | |
// To be able to animate navbars on ios you'll need to include | |
// F7Route mixin to all your routes with navbars | |
import Ember from 'ember'; | |
import F7Route from 'ember-cli-f7/mixins/f7-route'; | |
export default Ember.Route.extend(F7Route, { | |
}); |
This file contains 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
// config/environment.js | |
/* jshint node: true */ | |
module.exports = function(environment) { | |
var ENV = { | |
// ... some config here | |
framework7: { | |
theme: 'ios', // supported themes 'ios' and 'material' | |
params: { | |
fastClicks: true, | |
cache: false, // turning off as we're not using F7 router | |
materialRipple: false, // turning off as it's slow on some Android devices | |
animatePages: false, // turning off as we're not using F7 router | |
preloadPreviousPage: false, // turning off as we're not using F7 router | |
} | |
} | |
} | |
return ENV; | |
}; |
This file contains 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
// app/routes/about.js | |
// To be able to animate navbars on ios you'll need to include | |
// F7Route mixin to all your routes with navbars | |
// 'sliding' animation from F7 isn't currently supported | |
import Ember from 'ember'; | |
import F7Route from 'ember-cli-f7/mixins/f7-route'; | |
export default Ember.Route.extend(F7Route, { | |
}); |
This file contains 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
// app/components/liquid-versions.js | |
// Here I'm overriding one of liquid-fire components | |
// to be able to add Framework7 specific classes | |
// Hope some day I'll find time to refactor this code | |
import Ember from "ember"; | |
import { containingElement } from "liquid-fire/ember-internals"; | |
var get = Ember.get; | |
var set = Ember.set; | |
export default Ember.Component.extend({ | |
tagName: "", | |
name: 'liquid-versions', | |
transitionMap: Ember.inject.service('liquid-fire-transitions'), | |
getTransitionDirection(versions, firstTime){ | |
let transition = get(this, 'transitionMap').transitionFor({ | |
versions: versions, | |
parentElement: Ember.$(containingElement(this)), | |
use: get(this, 'use'), | |
firstTime: firstTime ? 'yes' : 'no', | |
helperName: get(this, 'name'), | |
outletName: get(this, 'outletName') | |
}); | |
return transition.animation && transition.animation.name || 'to-left'; | |
}, | |
didReceiveAttrs() { | |
this._super(); | |
if (!this.versions || this._lastVersion !== this.getAttr('value')) { | |
this.appendVersion(); | |
this._lastVersion = this.getAttr('value'); | |
} | |
}, | |
appendVersion() { | |
var versions = this.versions; | |
var firstTime = false; | |
var newValue = this.getAttr('value'); | |
var oldValue; | |
if (!versions) { | |
firstTime = true; | |
versions = Ember.A(); | |
} else { | |
oldValue = versions[0]; | |
} | |
if (!firstTime && ((!oldValue && !newValue) || | |
(oldValue === newValue))) { | |
return; | |
} | |
this.notifyContainer('willTransition', versions); | |
var newVersion = { | |
value: newValue, | |
shouldRender: newValue || get(this, 'renderWhenFalse') | |
}; | |
versions.unshiftObject(newVersion); | |
this.direction = this.getTransitionDirection(versions, firstTime); | |
const direction = this.direction; | |
if (versions && versions.length > 1 && direction === 'to-left') { | |
versions.reverse(); | |
} | |
this.firstTime = firstTime; | |
if (firstTime) { | |
set(this, 'versions', versions); | |
} | |
if (!newVersion.shouldRender && !firstTime) { | |
this._transition(); | |
} | |
}, | |
_transition: function() { | |
var versions = get(this, 'versions'); | |
var firstTime = this.firstTime; | |
this.firstTime = false; | |
this.notifyContainer('afterChildInsertion', versions); | |
var inserted = Ember.$(containingElement(this)).find('.liquid-child'); | |
var direction = this.direction; | |
inserted.css('visibility', 'visible'); | |
if (!firstTime) { | |
var oldPageSelector = direction === 'to-left' ? 'first' : 'last'; | |
var newPageSelector = direction === 'to-left' ? 'last' : 'first'; | |
if (inserted.hasClass('navbar-inner')) { | |
this.animateNavbars(oldPageSelector, newPageSelector, versions, inserted, direction); | |
} else { | |
this.animatePages(oldPageSelector, newPageSelector, versions, inserted, direction); | |
} | |
} | |
}, | |
animatePages(oldPageSelector, newPageSelector, versions, inserted, direction) { | |
var removeClasses = 'page-on-center page-on-right page-on-left'; | |
var oldPage = Ember.$(containingElement(this)).find(`.page.liquid-child:${oldPageSelector}`); | |
var newPage = Ember.$(containingElement(this)).find(`.page.liquid-child:${newPageSelector}`); | |
var events = ['webkitAnimationEnd', 'OAnimationEnd', 'MSAnimationEnd', 'animationend']; | |
if (direction === 'to-left') { | |
oldPage.removeClass(removeClasses).addClass('page-from-center-to-left'); | |
newPage.removeClass(removeClasses).addClass('page-from-right-to-center'); | |
} else if (direction === 'to-right') { | |
newPage.removeClass(removeClasses).addClass('page-from-left-to-center'); | |
oldPage.removeClass(removeClasses).addClass('page-from-center-to-right'); | |
} | |
for (var i = events.length - 1; i >= 0; i--) { | |
var e = events[i]; | |
newPage.on(e, () => { | |
this.finalizeVersions(versions, inserted); | |
this.notifyContainer("afterTransition", versions); | |
}); | |
} | |
}, | |
animateNavbars(oldPageSelector, newPageSelector, versions, inserted, direction) { | |
var removeClasses = 'navbar-on-right navbar-on-center navbar-on-left'; | |
var oldNavbarInner = Ember.$(containingElement(this)).find(`.navbar-inner.liquid-child:${oldPageSelector}`); | |
var newNavbarInner = Ember.$(containingElement(this)).find(`.navbar-inner.liquid-child:${newPageSelector}`); | |
if (direction === 'to-left') { | |
newNavbarInner.removeClass(removeClasses).addClass('navbar-from-right-to-center'); | |
oldNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-left'); | |
} else if (direction === 'to-right') { | |
newNavbarInner.removeClass(removeClasses).addClass('navbar-from-left-to-center'); | |
oldNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-right'); | |
} | |
Ember.run.later(()=>{ | |
this.finalizeVersions(versions, inserted); | |
}, 350); | |
}, | |
finalizeVersions: function(versions, inserted) { | |
const toReplace = this.direction === 'to-left' ? 0 : 1; | |
versions.replace(toReplace, versions.length - 1); | |
if (inserted.hasClass('navbar-inner')) { | |
var newNavbarInner = Ember.$(containingElement(this)).find(`.navbar-inner.liquid-child`); | |
newNavbarInner.removeClass('navbar-from-right-to-center navbar-on-left navbar-on-right').addClass('navbar-on-center'); | |
} else { | |
var newPage = Ember.$(containingElement(this)).find(`.page.liquid-child`); | |
var events = ['webkitAnimationEnd', 'OAnimationEnd', 'MSAnimationEnd', 'animationend']; | |
newPage.removeClass('page-from-right-to-center page-from-left-to-center page-on-right page-on-left').addClass('page-on-center'); | |
for (var i = events.length - 1; i >= 0; i--) { | |
var e = events[i]; | |
newPage.off(e); | |
} | |
} | |
}, | |
notifyContainer: function(method, versions) { | |
var target = get(this, 'notify'); | |
if (target) { | |
target.send(method, versions); | |
} | |
}, | |
actions: { | |
childDidRender: function(child) { | |
var version = get(child, 'version'); | |
set(version, 'view', child); | |
this._transition(); | |
} | |
} | |
}); |
This file contains 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
// app/transitions.js | |
// We're defining transitions direction just like it's done in Framework7 | |
// direction 'to-left' for example means that we're sliding new page from the right | |
// (sliding current page to the left) | |
const pageTransitionDirection = 'to-left'; | |
const pageTransitionBack = 'to-right'; | |
const transitionWithReverse = function(route) { | |
this.transition( | |
this.toRoute(route), | |
this.use(pageTransitionDirection), | |
this.reverse(pageTransitionBack) | |
); | |
}; | |
export default function(){ | |
transitionWithReverse.call(this, 'about'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's that basic setup you'll need to successfully animate page transitions on iOS and Material themes