Animations Feature

This commit is contained in:
Ghislain Loaec 2015-02-04 18:12:56 +01:00
parent 6c71fab756
commit 5d1991a14e
12 changed files with 2444 additions and 169 deletions

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,18 @@
@import "bootstrap.min.css";
/*@import "bootstrap-theme.min.css";*/
@import "font-awesome.min.css";
@import "animations.css";
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
margin: 0;
}
html, body,
#momo-body,
.momo-page {
height: 100%;
width: 100%;
}
body {
@ -30,7 +39,6 @@ body {
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
font-size:12px;
height:100%;
margin:0px;
padding:0px;
padding-top: 60px;
@ -39,9 +47,27 @@ body {
}
/* Portrait layout (default) */
.momo-page-wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -60px;
}
.momo-footer, .push {
height: 60px;
}
.momo-subnavbar {
margin-bottom: 0px;
}
.momo-container {
top: 60px;
bottom: 0;
left: 0;
right: 0;
height: auto;
position: absolute;
overflow: hidden;
}
.momo-page-content {
padding: 20px 0;
}
@ -52,12 +78,10 @@ body {
.momo-page-content:empty {
padding: 0;
}
.momo-page-content > iframe {
margin: -20px 0;
.momo-page iframe {
width: 100%;
border: 0;
min-height: 80%;
min-height: 100%;
}
.momo-page-pages {
border-radius: 0px;
@ -66,6 +90,40 @@ body {
border-radius: 0px;
}
.momo-pages {
position: relative;
width: 100%;
height: 100%;
perspective: 1200px;
transform-style: preserve-3d;
}
.momo-page {
width: 100%;
height: auto;
position: absolute;
top: 60px;
bottom: 0;
left: 0;
visibility: hidden;
overflow: auto;
backface-visibility: hidden;
transform: translate3d(0, 0, 0);
}
.momo-page-current,
.no-js .pt-page {
visibility: visible;
}
.no-js body {
overflow: auto;
}
.momo-page-ontop {
z-index: 999;
}
/* Landscape layout (with min-width) */
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
}

View File

@ -30,43 +30,92 @@
<title class="momo-title">Loading</title>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top momo-navbar">
<div id="momo-main"></div>
<!-- Main Template -->
<script type="text/x-tmpl" id="momo-main-tmpl">
<div class="momo-page-wrapper">
<!-- Navbar -->
<nav class="navbar navbar-default navbar-fixed-top momo-navbar">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#home">
<span class="momo-icon">
<img src="{%= o.meta.icon %}" width="20" height="20"/>
</span>
<span class="momo-title">{%= o.meta.title %}</span>
</a>
</div>
</div>
</nav>
<!-- Pages List -->
<div id="momo-pages"></div>
</div>
<!-- Footer -->
<footer class="momo-footer">
<div class="container-fluid clearfix">
<p class="navbar-text pull-right">
<a href="mailto:{%= o.contact %}" class="momo-contact">{%= o.meta.contact %}</a>
</p>
</div>
</footer>
</script>
<!-- Page Template -->
<script type="text/x-tmpl" id="momo-page-tmpl">
<nav class="navbar navbar-inverse navbar-static-top momo-subnavbar">
<div class="container-fluid">
<div class="navbar-header">
<span class="navbar-brand">
{%= o.title %}
</span>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#home">
<span class="momo-icon"><i class="fa fa-spinner fa-pulse"></i></span>
<span class="momo-title">Loading...</span>
</a>
<section class="momo-page-content">{%# o.content %}</section>
</div>
{% if(o.url){ %}
<iframe src="{%= o.url %}"></iframe>
{% } %}
{% if(o.pages){ %}
<div class="list-group momo-page-pages">
{% for (var i = 0; i < o.pages.length; i++) { %}
<a href="#{%= o.pages[i] %}" class="list-group-item">{%= app.pages[o.pages[i]].title %}</a>
{% } %}
</div>
</div>
</nav>
<nav class="navbar navbar-inverse navbar-static-top momo-subnavbar">
<div class="container-fluid">
<div class="navbar-header">
<span class="navbar-brand momo-page-title">
</span>
{% } %}
{% if(o.seealso){ %}
<div class="container-fluid">
<div class="panel panel-default">
<div class="panel-heading">
See Also
</div>
<div class="list-group momo-page-pages">
{% for (var i = 0; i < o.seealso.length; i++) { %}
<a href="#{%= o.seealso[i] %}" class="list-group-item">{%= app.pages[o.seealso[i]].title %}</a>
{% } %}
</div>
</div>
</div>
</div>
</nav>
<div class="container-fluid">
{% } %}
<!--h3 class="page-header momo-page-title"></h3-->
</script>
<div class="momo-page-content">
<div class="jumbotron text-center">
<i class="fa fa-spinner fa-pulse fa-2x"></i>
</div>
</div>
<div class="row list-group momo-page-pages"></div>
<div class="panel panel-default">
<div class="panel-heading">See also</div>
<div class="list-group momo-page-seealso"></div>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/tmpl.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();

View File

@ -7,7 +7,7 @@
"assetsUrl": "https://perso.entrouvert.org/~fred/ma-ville-assets.zip?1416471664"
},
"title": "Ma ville",
"content": "<p>Bienvenue !</p>",
"content": "<p>Bienvenue !</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
"pages": [
{"title": "Découvrir la ville",
"pages": [

View File

@ -16,105 +16,232 @@
* specific language governing permissions and limitations
* under the License.
*/
var ANIMATION_OUT_CLASS = 'pt-page-moveToLeftEasing pt-page-ontop';
var ANIMATION_IN_CLASS = 'pt-page-moveFromRight';
var extend = function ( defaults, options ) {
var extended = {};
var prop;
for (prop in defaults) {
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
extended[prop] = defaults[prop];
}
}
for (prop in options) {
if (Object.prototype.hasOwnProperty.call(options, prop)) {
extended[prop] = options[prop];
}
}
return extended;
};
var app = {
pages: {},
meta: {
'title': 'Momo Application',
'contact': 'contact@cadoles.com'
},
current : 0,
isAnimating: false,
endCurrPage: false,
endNextPage: false,
// Application Constructor
initialize: function() {
this.bindEvents();
this.loadManifest();
},
// JSON Manifest loading function
loadManifest: function(){
console.log("Loading Manifest");
var manifest = localStorage.getItem("momo-manifest");
var manifest = localStorage.getItem("momo-manifest");
var manifestUrl = manifest ? manifest['updateUrl'] : 'index.json';
var request = new XMLHttpRequest();
var request = new XMLHttpRequest();
request.open('GET', manifestUrl, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText);
app.registerPage(data, true);
app.render(data);
} else {
alert("Error "+request.status);
}
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText);
app.start(data);
} else {
alert("Error "+request.status);
}
};
request.onerror = function() {
alert("Connexion Error");
alert("Connexion Error");
};
request.send();
},
registerPage: function(data, homepage){
// Application starter
start: function(data){
data.id = 'home';
app.current_page = data.id;
app.registerPage(data);
app.render(data);
//app.navigate(data.id);
},
// Recursive function to index page form json
registerPage: function(data){
if(data instanceof Object){
var id = data.id ? data.id : (homepage ? 'home' : '_' + Math.random().toString(36).substr(2, 9));
app.pages[id] = data;
// Generate a page ID
var id = data.id = data.id ? data.id : (data.title ? app.utils.hyphenate(data.title) : '_' + Math.random().toString(36).substr(2, 9));
// Make sure id is unique
var i = 1;
while(app.pages.hasOwnProperty(data.id)){
data.id = id+'_'+i.toString();
}
// Register page
app.pages[data.id] = data;
// Register page childrens
if(data.pages instanceof Array){
for(var i = 0; i < data.pages.length; i++){
var page = data.pages[i];
app.pages[id].pages[i] = app.registerPage(page, false);
app.pages[data.id].pages[i] = app.registerPage(page, false);
}
}
// Register seealso childrens
if(data.seealso instanceof Array){
for(var i = 0; i < data.seealso.length; i++){
var page = data.seealso[i];
app.pages[id].seealso[i] = app.registerPage(page, false);
app.pages[data.id].seealso[i] = app.registerPage(page, false);
}
}
return id;
return data.id;
} else
if(typeof data === 'string' || data instanceof String || data instanceof Number){
return data;
}
},
// Render Application
render: function(data){
app.utils.updateEl('.momo-title', data.meta.title);
app.utils.updateEl('.momo-icon', '<img src="'+data.meta.icon+'" width="20px" height="20px"/>');
app.renderPage(data);
// Render Main section
var $main = tmpl("momo-main-tmpl", data);
document.getElementById('momo-main').innerHTML = $main;
// Render every page
for(var page in app.pages)
app.renderPage(app.pages[page]);
},
// Render Page
renderPage: function(page){
if(page instanceof Object){
if(page.external){
navigator.app.loadUrl(page.url, { openExternal:true });
return false;
}
app.utils.updateEl('.momo-page-content', '');
app.utils.updateEl('.momo-page-pages', '');
app.utils.updateEl('.momo-page-seealso', '');
app.utils.updateEl('.momo-page-title', page.title);
var $seealso = document.querySelector('.momo-page-seealso');
$seealso.parentElement.style.display = 'none';
if(page.content){
app.utils.updateEl('.momo-page-content', page.content);
} else
if(page.url){
app.utils.updateEl('.momo-page-content', '<iframe src="'+page.url+'"></iframe>');
}
if(page.pages instanceof Array){
app.utils.updateEl('.momo-page-pages', app.utils.renderLinks(page.pages));
}
if(page.seealso instanceof Array){
$seealso.parentElement.style.display = 'block';
app.utils.updateEl('.momo-page-seealso', app.utils.renderLinks(page.seealso));
var $page = document.createElement('div');
$page.id = page.id;
$page.className = "momo-page";
if(page.id == 'home'){
$page.classList.add('momo-page-current');
}
$page.innerHTML = tmpl("momo-page-tmpl", page);
document.getElementById('momo-pages').appendChild($page);
//if(page.external){
// navigator.app.loadUrl(page.url, { openExternal:true });
// return false;
//}
//app.utils.updateEl('.momo-page-content', '');
//app.utils.updateEl('.momo-page-pages', '');
//app.utils.updateEl('.momo-page-seealso', '');
//app.utils.updateEl('.momo-page-title', page.title);
//var $seealso = document.querySelector('.momo-page-seealso');
//$seealso.parentElement.style.display = 'none';
//if(page.content){
// app.utils.updateEl('.momo-page-content', page.content);
//} else
//if(page.url){
// app.utils.updateEl('.momo-page-content', '<div class="momo-container"><iframe src="'+page.url+'"></iframe></div>');
//}
//if(page.pages instanceof Array){
// app.utils.updateEl('.momo-page-pages', app.utils.renderLinks(page.pages));
//}
//if(page.seealso instanceof Array){
// $seealso.parentElement.style.display = 'block';
// app.utils.updateEl('.momo-page-seealso', app.utils.renderLinks(page.seealso));
//}
} else
if(typeof page === 'string' || page instanceof String || page instanceof Number){
console.log('Render page '+page);
window.location.hash = page;
if(app.pages.hasOwnProperty(page)) {
app.renderPage(app.pages[page]);
} else {
alert('Page "'+page+'" doesn\'t exist');
}
//console.log('Render page '+page);
//window.location.hash = page;
//if(app.pages.hasOwnProperty(page)) {
// app.renderPage(app.pages[page]);
//} else {
// alert('Page "'+page+'" doesn\'t exist');
//}
}
},
navigate: function(page){
if(app.isAnimating) {
return false;
}
app.isAnimating = true;
var $outpage = document.getElementById(app.current_page);
var $inpage = document.getElementById(page);
var outCb = function(){
$outpage.removeEventListener('animationend', outCb);
app.endCurrPage = true;
if(app.endNextPage){
app.onAnimationEnd($outpage, $inpage);
}
};
var inCb = function(){
$inpage.removeEventListener('animationend', inCb);
app.endNextPage = true;
if(app.endCurrPage){
app.onAnimationEnd($outpage, $inpage);
}
};
var out_classes = ANIMATION_OUT_CLASS.split(' ');
for(var i = 0; i < out_classes.length; i++)
$outpage.classList.add(out_classes[i]);
$outpage.addEventListener('animationend', outCb, false);
$inpage.classList.add('momo-page-current');
var in_classes = ANIMATION_IN_CLASS.split(' ');
for(var i = 0; i < in_classes.length; i++)
$inpage.classList.add(in_classes[i]);
$inpage.addEventListener('animationend', inCb);
app.current_page = page;
},
onAnimationEnd($outpage, $inpage) {
app.endCurrPage = false;
app.endNextPage = false;
var out_classes = ANIMATION_OUT_CLASS.split(' ');
for(var i = 0; i < out_classes.length; i++)
$outpage.classList.remove(out_classes[i]);
if( $outpage != $inpage)
$outpage.classList.remove('momo-page-current');
var in_classes = ANIMATION_IN_CLASS.split(' ');
for(var i = 0; i < in_classes.length; i++)
$inpage.classList.remove(in_classes[i]);
app.isAnimating = false;
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
window.addEventListener('hashchange', this.onHashChange, false);
@ -122,10 +249,11 @@ var app = {
onHashChange: function(e) {
var page = window.location.hash.slice(1);
if(!page){
page = app.pages['home']
if(!app.pages.hasOwnProperty(page)){
page = 'home';
}
app.renderPage(page);
if(app.current_page != page)
app.navigate(page);
},
onDeviceReady: function() {
@ -137,6 +265,7 @@ var app = {
},
utils: {
updateEl: function(selector, html){
var $el = document.querySelectorAll(selector);
for (var i = 0; i < $el.length; i++)
@ -154,6 +283,65 @@ var app = {
html += '</a>';
}
return html;
},
trim: function(str){
return (str || '').replace(/^\s+|\s+$/g, '');
},
removeNonWord: function(str){
return (str || '').replace(/[^0-9a-zA-Z\xC0-\xFF \-]/g, ''); //remove non-word chars
},
replaceAccents: function(str){
str = str || '';
// verifies if the String has accents and replace them
if (str.search(/[\xC0-\xFF]/g) > -1) {
str = str
.replace(/[\xC0-\xC5]/g, "A")
.replace(/[\xC6]/g, "AE")
.replace(/[\xC7]/g, "C")
.replace(/[\xC8-\xCB]/g, "E")
.replace(/[\xCC-\xCF]/g, "I")
.replace(/[\xD0]/g, "D")
.replace(/[\xD1]/g, "N")
.replace(/[\xD2-\xD6\xD8]/g, "O")
.replace(/[\xD9-\xDC]/g, "U")
.replace(/[\xDD]/g, "Y")
.replace(/[\xDE]/g, "P")
.replace(/[\xE0-\xE5]/g, "a")
.replace(/[\xE6]/g, "ae")
.replace(/[\xE7]/g, "c")
.replace(/[\xE8-\xEB]/g, "e")
.replace(/[\xEC-\xEF]/g, "i")
.replace(/[\xF1]/g, "n")
.replace(/[\xF2-\xF6\xF8]/g, "o")
.replace(/[\xF9-\xFC]/g, "u")
.replace(/[\xFE]/g, "p")
.replace(/[\xFD\xFF]/g, "y");
}
return str;
},
slugify: function(str, delimeter){
if (delimeter == null) {
delimeter = "-";
}
str = app.utils.replaceAccents(str);
str = app.utils.removeNonWord(str);
str = app.utils.trim(str) //should come after removeNonWord
.replace(/ +/g, delimeter) //replace spaces with delimeter
.toLowerCase();
return str;
},
unCamelCase: function(str){
return (str || '').replace(/([a-z\xE0-\xFF])([A-Z\xC0\xDF])/g, '$1 $2').toLowerCase(); //add space between camelCase text
},
hyphenate: function(str){
str = app.utils.unCamelCase(str);
return app.utils.slugify(str, "-");
}
}
};

View File

@ -0,0 +1,398 @@
var PageTransitions = (function() {
var $main = $( '#pt-main' ),
$pages = $main.children( 'div.pt-page' ),
$iterate = $( '#iterateEffects' ),
animcursor = 1,
pagesCount = $pages.length,
current = 0,
isAnimating = false,
endCurrPage = false,
endNextPage = false,
animEndEventNames = {
'WebkitAnimation' : 'webkitAnimationEnd',
'OAnimation' : 'oAnimationEnd',
'msAnimation' : 'MSAnimationEnd',
'animation' : 'animationend'
},
// animation end event name
animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ],
// support css animations
support = Modernizr.cssanimations;
function init() {
$pages.each( function() {
var $page = $( this );
$page.data( 'originalClassList', $page.attr( 'class' ) );
} );
$pages.eq( current ).addClass( 'pt-page-current' );
$( '#dl-menu' ).dlmenu( {
animationClasses : { in : 'dl-animate-in-2', out : 'dl-animate-out-2' },
onLinkClick : function( el, ev ) {
ev.preventDefault();
nextPage( el.data( 'animation' ) );
}
} );
$iterate.on( 'click', function() {
if( isAnimating ) {
return false;
}
if( animcursor > 67 ) {
animcursor = 1;
}
nextPage( animcursor );
++animcursor;
} );
}
function nextPage(options ) {
var animation = (options.animation) ? options.animation : options;
if( isAnimating ) {
return false;
}
isAnimating = true;
var $currPage = $pages.eq( current );
if(options.showPage){
if( options.showPage < pagesCount - 1 ) {
current = options.showPage;
}
else {
current = 0;
}
}
else{
if( current < pagesCount - 1 ) {
++current;
}
else {
current = 0;
}
}
var $nextPage = $pages.eq( current ).addClass( 'pt-page-current' ),
outClass = '', inClass = '';
switch( animation ) {
case 1:
outClass = 'pt-page-moveToLeft';
inClass = 'pt-page-moveFromRight';
break;
case 2:
outClass = 'pt-page-moveToRight';
inClass = 'pt-page-moveFromLeft';
break;
case 3:
outClass = 'pt-page-moveToTop';
inClass = 'pt-page-moveFromBottom';
break;
case 4:
outClass = 'pt-page-moveToBottom';
inClass = 'pt-page-moveFromTop';
break;
case 5:
outClass = 'pt-page-fade';
inClass = 'pt-page-moveFromRight pt-page-ontop';
break;
case 6:
outClass = 'pt-page-fade';
inClass = 'pt-page-moveFromLeft pt-page-ontop';
break;
case 7:
outClass = 'pt-page-fade';
inClass = 'pt-page-moveFromBottom pt-page-ontop';
break;
case 8:
outClass = 'pt-page-fade';
inClass = 'pt-page-moveFromTop pt-page-ontop';
break;
case 9:
outClass = 'pt-page-moveToLeftFade';
inClass = 'pt-page-moveFromRightFade';
break;
case 10:
outClass = 'pt-page-moveToRightFade';
inClass = 'pt-page-moveFromLeftFade';
break;
case 11:
outClass = 'pt-page-moveToTopFade';
inClass = 'pt-page-moveFromBottomFade';
break;
case 12:
outClass = 'pt-page-moveToBottomFade';
inClass = 'pt-page-moveFromTopFade';
break;
case 13:
outClass = 'pt-page-moveToLeftEasing pt-page-ontop';
inClass = 'pt-page-moveFromRight';
break;
case 14:
outClass = 'pt-page-moveToRightEasing pt-page-ontop';
inClass = 'pt-page-moveFromLeft';
break;
case 15:
outClass = 'pt-page-moveToTopEasing pt-page-ontop';
inClass = 'pt-page-moveFromBottom';
break;
case 16:
outClass = 'pt-page-moveToBottomEasing pt-page-ontop';
inClass = 'pt-page-moveFromTop';
break;
case 17:
outClass = 'pt-page-scaleDown';
inClass = 'pt-page-moveFromRight pt-page-ontop';
break;
case 18:
outClass = 'pt-page-scaleDown';
inClass = 'pt-page-moveFromLeft pt-page-ontop';
break;
case 19:
outClass = 'pt-page-scaleDown';
inClass = 'pt-page-moveFromBottom pt-page-ontop';
break;
case 20:
outClass = 'pt-page-scaleDown';
inClass = 'pt-page-moveFromTop pt-page-ontop';
break;
case 21:
outClass = 'pt-page-scaleDown';
inClass = 'pt-page-scaleUpDown pt-page-delay300';
break;
case 22:
outClass = 'pt-page-scaleDownUp';
inClass = 'pt-page-scaleUp pt-page-delay300';
break;
case 23:
outClass = 'pt-page-moveToLeft pt-page-ontop';
inClass = 'pt-page-scaleUp';
break;
case 24:
outClass = 'pt-page-moveToRight pt-page-ontop';
inClass = 'pt-page-scaleUp';
break;
case 25:
outClass = 'pt-page-moveToTop pt-page-ontop';
inClass = 'pt-page-scaleUp';
break;
case 26:
outClass = 'pt-page-moveToBottom pt-page-ontop';
inClass = 'pt-page-scaleUp';
break;
case 27:
outClass = 'pt-page-scaleDownCenter';
inClass = 'pt-page-scaleUpCenter pt-page-delay400';
break;
case 28:
outClass = 'pt-page-rotateRightSideFirst';
inClass = 'pt-page-moveFromRight pt-page-delay200 pt-page-ontop';
break;
case 29:
outClass = 'pt-page-rotateLeftSideFirst';
inClass = 'pt-page-moveFromLeft pt-page-delay200 pt-page-ontop';
break;
case 30:
outClass = 'pt-page-rotateTopSideFirst';
inClass = 'pt-page-moveFromTop pt-page-delay200 pt-page-ontop';
break;
case 31:
outClass = 'pt-page-rotateBottomSideFirst';
inClass = 'pt-page-moveFromBottom pt-page-delay200 pt-page-ontop';
break;
case 32:
outClass = 'pt-page-flipOutRight';
inClass = 'pt-page-flipInLeft pt-page-delay500';
break;
case 33:
outClass = 'pt-page-flipOutLeft';
inClass = 'pt-page-flipInRight pt-page-delay500';
break;
case 34:
outClass = 'pt-page-flipOutTop';
inClass = 'pt-page-flipInBottom pt-page-delay500';
break;
case 35:
outClass = 'pt-page-flipOutBottom';
inClass = 'pt-page-flipInTop pt-page-delay500';
break;
case 36:
outClass = 'pt-page-rotateFall pt-page-ontop';
inClass = 'pt-page-scaleUp';
break;
case 37:
outClass = 'pt-page-rotateOutNewspaper';
inClass = 'pt-page-rotateInNewspaper pt-page-delay500';
break;
case 38:
outClass = 'pt-page-rotatePushLeft';
inClass = 'pt-page-moveFromRight';
break;
case 39:
outClass = 'pt-page-rotatePushRight';
inClass = 'pt-page-moveFromLeft';
break;
case 40:
outClass = 'pt-page-rotatePushTop';
inClass = 'pt-page-moveFromBottom';
break;
case 41:
outClass = 'pt-page-rotatePushBottom';
inClass = 'pt-page-moveFromTop';
break;
case 42:
outClass = 'pt-page-rotatePushLeft';
inClass = 'pt-page-rotatePullRight pt-page-delay180';
break;
case 43:
outClass = 'pt-page-rotatePushRight';
inClass = 'pt-page-rotatePullLeft pt-page-delay180';
break;
case 44:
outClass = 'pt-page-rotatePushTop';
inClass = 'pt-page-rotatePullBottom pt-page-delay180';
break;
case 45:
outClass = 'pt-page-rotatePushBottom';
inClass = 'pt-page-rotatePullTop pt-page-delay180';
break;
case 46:
outClass = 'pt-page-rotateFoldLeft';
inClass = 'pt-page-moveFromRightFade';
break;
case 47:
outClass = 'pt-page-rotateFoldRight';
inClass = 'pt-page-moveFromLeftFade';
break;
case 48:
outClass = 'pt-page-rotateFoldTop';
inClass = 'pt-page-moveFromBottomFade';
break;
case 49:
outClass = 'pt-page-rotateFoldBottom';
inClass = 'pt-page-moveFromTopFade';
break;
case 50:
outClass = 'pt-page-moveToRightFade';
inClass = 'pt-page-rotateUnfoldLeft';
break;
case 51:
outClass = 'pt-page-moveToLeftFade';
inClass = 'pt-page-rotateUnfoldRight';
break;
case 52:
outClass = 'pt-page-moveToBottomFade';
inClass = 'pt-page-rotateUnfoldTop';
break;
case 53:
outClass = 'pt-page-moveToTopFade';
inClass = 'pt-page-rotateUnfoldBottom';
break;
case 54:
outClass = 'pt-page-rotateRoomLeftOut pt-page-ontop';
inClass = 'pt-page-rotateRoomLeftIn';
break;
case 55:
outClass = 'pt-page-rotateRoomRightOut pt-page-ontop';
inClass = 'pt-page-rotateRoomRightIn';
break;
case 56:
outClass = 'pt-page-rotateRoomTopOut pt-page-ontop';
inClass = 'pt-page-rotateRoomTopIn';
break;
case 57:
outClass = 'pt-page-rotateRoomBottomOut pt-page-ontop';
inClass = 'pt-page-rotateRoomBottomIn';
break;
case 58:
outClass = 'pt-page-rotateCubeLeftOut pt-page-ontop';
inClass = 'pt-page-rotateCubeLeftIn';
break;
case 59:
outClass = 'pt-page-rotateCubeRightOut pt-page-ontop';
inClass = 'pt-page-rotateCubeRightIn';
break;
case 60:
outClass = 'pt-page-rotateCubeTopOut pt-page-ontop';
inClass = 'pt-page-rotateCubeTopIn';
break;
case 61:
outClass = 'pt-page-rotateCubeBottomOut pt-page-ontop';
inClass = 'pt-page-rotateCubeBottomIn';
break;
case 62:
outClass = 'pt-page-rotateCarouselLeftOut pt-page-ontop';
inClass = 'pt-page-rotateCarouselLeftIn';
break;
case 63:
outClass = 'pt-page-rotateCarouselRightOut pt-page-ontop';
inClass = 'pt-page-rotateCarouselRightIn';
break;
case 64:
outClass = 'pt-page-rotateCarouselTopOut pt-page-ontop';
inClass = 'pt-page-rotateCarouselTopIn';
break;
case 65:
outClass = 'pt-page-rotateCarouselBottomOut pt-page-ontop';
inClass = 'pt-page-rotateCarouselBottomIn';
break;
case 66:
outClass = 'pt-page-rotateSidesOut';
inClass = 'pt-page-rotateSidesIn pt-page-delay200';
break;
case 67:
outClass = 'pt-page-rotateSlideOut';
inClass = 'pt-page-rotateSlideIn';
break;
}
$currPage.addClass( outClass ).on( animEndEventName, function() {
$currPage.off( animEndEventName );
endCurrPage = true;
if( endNextPage ) {
onEndAnimation( $currPage, $nextPage );
}
} );
$nextPage.addClass( inClass ).on( animEndEventName, function() {
$nextPage.off( animEndEventName );
endNextPage = true;
if( endCurrPage ) {
onEndAnimation( $currPage, $nextPage );
}
} );
if( !support ) {
onEndAnimation( $currPage, $nextPage );
}
}
function onEndAnimation( $outpage, $inpage ) {
endCurrPage = false;
endNextPage = false;
resetPage( $outpage, $inpage );
isAnimating = false;
}
function resetPage( $outpage, $inpage ) {
$outpage.attr( 'class', $outpage.data( 'originalClassList' ) );
$inpage.attr( 'class', $inpage.data( 'originalClassList' ) + ' pt-page-current' );
}
init();
return {
init : init,
nextPage : nextPage,
};
})();

View File

@ -0,0 +1 @@
!function(a){"use strict";var b=function(a,c){var d=/[^\w\-\.:]/.test(a)?new Function(b.arg+",tmpl","var _e=tmpl.encode"+b.helper+",_s='"+a.replace(b.regexp,b.func)+"';return _s;"):b.cache[a]=b.cache[a]||b(b.load(a));return c?d(c,b):function(a){return d(a,b)}};b.cache={},b.load=function(a){return document.getElementById(a).innerHTML},b.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,b.func=function(a,b,c,d,e,f){return b?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[b]||"\\"+b:c?"="===c?"'+_e("+d+")+'":"'+("+d+"==null?'':"+d+")+'":e?"';":f?"_s+='":void 0},b.encReg=/[<>&"'\x00]/g,b.encMap={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#39;"},b.encode=function(a){return(null==a?"":""+a).replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return b}):a.tmpl=b}(this);

View File

@ -1294,4 +1294,4 @@
.pt-page-delay1000 {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
}

View File

@ -24,6 +24,14 @@
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
margin: 0;
}
html, body,
#momo-body,
.momo-page {
height: 100%;
width: 100%;
}
body {
@ -31,7 +39,6 @@ body {
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
font-size:12px;
height:100%;
margin:0px;
padding:0px;
padding-top: 60px;
@ -40,6 +47,15 @@ body {
}
/* Portrait layout (default) */
.momo-page-wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -60px;
}
.momo-footer, .push {
height: 60px;
}
.momo-subnavbar {
margin-bottom: 0px;
}
@ -62,11 +78,10 @@ body {
.momo-page-content:empty {
padding: 0;
}
.momo-page-content iframe {
.momo-page iframe {
width: 100%;
border: 0;
min-height: 100%;
}
.momo-page-pages {
border-radius: 0px;
@ -75,6 +90,40 @@ body {
border-radius: 0px;
}
.momo-pages {
position: relative;
width: 100%;
height: 100%;
perspective: 1200px;
transform-style: preserve-3d;
}
.momo-page {
width: 100%;
height: auto;
position: absolute;
top: 60px;
bottom: 0;
left: 0;
visibility: hidden;
overflow: auto;
backface-visibility: hidden;
transform: translate3d(0, 0, 0);
}
.momo-page-current,
.no-js .pt-page {
visibility: visible;
}
.no-js body {
overflow: auto;
}
.momo-page-ontop {
z-index: 999;
}
/* Landscape layout (with min-width) */
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
}

View File

@ -31,45 +31,91 @@
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top momo-navbar">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#home">
<span class="momo-icon"><i class="fa fa-spinner fa-pulse"></i></span>
<span class="momo-title">Loading...</span>
</a>
</div>
<div id="momo-main"></div>
<!-- Main Template -->
<script type="text/x-tmpl" id="momo-main-tmpl">
<div class="momo-page-wrapper">
<!-- Navbar -->
<nav class="navbar navbar-default navbar-fixed-top momo-navbar">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#home">
<span class="momo-icon">
<img src="{%= o.meta.icon %}" width="20" height="20"/>
</span>
<span class="momo-title">{%= o.meta.title %}</span>
</a>
</div>
</div>
</nav>
<!-- Pages List -->
<div id="momo-pages"></div>
</div>
</nav>
<!-- Footer -->
<footer class="momo-footer">
<div class="container-fluid clearfix">
<p class="navbar-text pull-right">
<a href="mailto:{%= o.contact %}" class="momo-contact">{%= o.meta.contact %}</a>
</p>
</div>
</footer>
<div class="container-fluid momo-container">
</script>
<nav class="navbar navbar-inverse navbar-static-top row momo-subnavbar">
<!-- Page Template -->
<script type="text/x-tmpl" id="momo-page-tmpl">
<nav class="navbar navbar-inverse navbar-static-top momo-subnavbar">
<div class="container-fluid">
<div class="navbar-header">
<span class="navbar-brand momo-page-title">
<span class="navbar-brand">
{%= o.title %}
</span>
</div>
</div>
</nav>
</nav>
<!--h3 class="page-header momo-page-title"></h3-->
<div class="container-fluid">
<section class="momo-page-content">{%# o.content %}</section>
</div>
<div class="momo-page-content">
<div class="jumbotron text-center">
<i class="fa fa-spinner fa-pulse fa-2x"></i>
{% if(o.url){ %}
<iframe src="{%= o.url %}"></iframe>
{% } %}
{% if(o.pages){ %}
<div class="list-group momo-page-pages">
{% for (var i = 0; i < o.pages.length; i++) { %}
<a href="#{%= o.pages[i] %}" class="list-group-item">{%= app.pages[o.pages[i]].title %}</a>
{% } %}
</div>
</div>
{% } %}
<div class="row list-group momo-page-pages"></div>
{% if(o.seealso){ %}
<div class="container-fluid">
<div class="panel panel-default">
<div class="panel-heading">
See Also
</div>
<div class="list-group momo-page-pages">
{% for (var i = 0; i < o.seealso.length; i++) { %}
<a href="#{%= o.seealso[i] %}" class="list-group-item">{%= app.pages[o.seealso[i]].title %}</a>
{% } %}
</div>
</div>
</div>
{% } %}
<div class="panel panel-default">
<div class="panel-heading">See also</div>
<div class="list-group momo-page-seealso"></div>
</div>
</script>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/tmpl.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();

View File

@ -16,105 +16,232 @@
* specific language governing permissions and limitations
* under the License.
*/
var ANIMATION_OUT_CLASS = 'pt-page-moveToLeftEasing pt-page-ontop';
var ANIMATION_IN_CLASS = 'pt-page-moveFromRight';
var extend = function ( defaults, options ) {
var extended = {};
var prop;
for (prop in defaults) {
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
extended[prop] = defaults[prop];
}
}
for (prop in options) {
if (Object.prototype.hasOwnProperty.call(options, prop)) {
extended[prop] = options[prop];
}
}
return extended;
};
var app = {
pages: {},
meta: {
'title': 'Momo Application',
'contact': 'contact@cadoles.com'
},
current : 0,
isAnimating: false,
endCurrPage: false,
endNextPage: false,
// Application Constructor
initialize: function() {
this.bindEvents();
this.loadManifest();
},
// JSON Manifest loading function
loadManifest: function(){
console.log("Loading Manifest");
var manifest = localStorage.getItem("momo-manifest");
var manifest = localStorage.getItem("momo-manifest");
var manifestUrl = manifest ? manifest['updateUrl'] : 'index.json';
var request = new XMLHttpRequest();
var request = new XMLHttpRequest();
request.open('GET', manifestUrl, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText);
app.registerPage(data, true);
app.render(data);
} else {
alert("Error "+request.status);
}
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText);
app.start(data);
} else {
alert("Error "+request.status);
}
};
request.onerror = function() {
alert("Connexion Error");
alert("Connexion Error");
};
request.send();
},
registerPage: function(data, homepage){
// Application starter
start: function(data){
data.id = 'home';
app.current_page = data.id;
app.registerPage(data);
app.render(data);
//app.navigate(data.id);
},
// Recursive function to index page form json
registerPage: function(data){
if(data instanceof Object){
var id = data.id ? data.id : (homepage ? 'home' : '_' + Math.random().toString(36).substr(2, 9));
app.pages[id] = data;
// Generate a page ID
var id = data.id = data.id ? data.id : (data.title ? app.utils.hyphenate(data.title) : '_' + Math.random().toString(36).substr(2, 9));
// Make sure id is unique
var i = 1;
while(app.pages.hasOwnProperty(data.id)){
data.id = id+'_'+i.toString();
}
// Register page
app.pages[data.id] = data;
// Register page childrens
if(data.pages instanceof Array){
for(var i = 0; i < data.pages.length; i++){
var page = data.pages[i];
app.pages[id].pages[i] = app.registerPage(page, false);
app.pages[data.id].pages[i] = app.registerPage(page, false);
}
}
// Register seealso childrens
if(data.seealso instanceof Array){
for(var i = 0; i < data.seealso.length; i++){
var page = data.seealso[i];
app.pages[id].seealso[i] = app.registerPage(page, false);
app.pages[data.id].seealso[i] = app.registerPage(page, false);
}
}
return id;
return data.id;
} else
if(typeof data === 'string' || data instanceof String || data instanceof Number){
return data;
}
},
// Render Application
render: function(data){
app.utils.updateEl('.momo-title', data.meta.title);
app.utils.updateEl('.momo-icon', '<img src="'+data.meta.icon+'" width="20px" height="20px"/>');
app.renderPage(data);
// Render Main section
var $main = tmpl("momo-main-tmpl", data);
document.getElementById('momo-main').innerHTML = $main;
// Render every page
for(var page in app.pages)
app.renderPage(app.pages[page]);
},
// Render Page
renderPage: function(page){
if(page instanceof Object){
if(page.external){
navigator.app.loadUrl(page.url, { openExternal:true });
return false;
}
app.utils.updateEl('.momo-page-content', '');
app.utils.updateEl('.momo-page-pages', '');
app.utils.updateEl('.momo-page-seealso', '');
app.utils.updateEl('.momo-page-title', page.title);
var $seealso = document.querySelector('.momo-page-seealso');
$seealso.parentElement.style.display = 'none';
if(page.content){
app.utils.updateEl('.momo-page-content', page.content);
} else
if(page.url){
app.utils.updateEl('.momo-page-content', '<div class="momo-container"><iframe src="'+page.url+'"></iframe></div>');
}
if(page.pages instanceof Array){
app.utils.updateEl('.momo-page-pages', app.utils.renderLinks(page.pages));
}
if(page.seealso instanceof Array){
$seealso.parentElement.style.display = 'block';
app.utils.updateEl('.momo-page-seealso', app.utils.renderLinks(page.seealso));
var $page = document.createElement('div');
$page.id = page.id;
$page.className = "momo-page";
if(page.id == 'home'){
$page.classList.add('momo-page-current');
}
$page.innerHTML = tmpl("momo-page-tmpl", page);
document.getElementById('momo-pages').appendChild($page);
//if(page.external){
// navigator.app.loadUrl(page.url, { openExternal:true });
// return false;
//}
//app.utils.updateEl('.momo-page-content', '');
//app.utils.updateEl('.momo-page-pages', '');
//app.utils.updateEl('.momo-page-seealso', '');
//app.utils.updateEl('.momo-page-title', page.title);
//var $seealso = document.querySelector('.momo-page-seealso');
//$seealso.parentElement.style.display = 'none';
//if(page.content){
// app.utils.updateEl('.momo-page-content', page.content);
//} else
//if(page.url){
// app.utils.updateEl('.momo-page-content', '<div class="momo-container"><iframe src="'+page.url+'"></iframe></div>');
//}
//if(page.pages instanceof Array){
// app.utils.updateEl('.momo-page-pages', app.utils.renderLinks(page.pages));
//}
//if(page.seealso instanceof Array){
// $seealso.parentElement.style.display = 'block';
// app.utils.updateEl('.momo-page-seealso', app.utils.renderLinks(page.seealso));
//}
} else
if(typeof page === 'string' || page instanceof String || page instanceof Number){
console.log('Render page '+page);
window.location.hash = page;
if(app.pages.hasOwnProperty(page)) {
app.renderPage(app.pages[page]);
} else {
alert('Page "'+page+'" doesn\'t exist');
}
//console.log('Render page '+page);
//window.location.hash = page;
//if(app.pages.hasOwnProperty(page)) {
// app.renderPage(app.pages[page]);
//} else {
// alert('Page "'+page+'" doesn\'t exist');
//}
}
},
navigate: function(page){
if(app.isAnimating) {
return false;
}
app.isAnimating = true;
var $outpage = document.getElementById(app.current_page);
var $inpage = document.getElementById(page);
var outCb = function(){
$outpage.removeEventListener('animationend', outCb);
app.endCurrPage = true;
if(app.endNextPage){
app.onAnimationEnd($outpage, $inpage);
}
};
var inCb = function(){
$inpage.removeEventListener('animationend', inCb);
app.endNextPage = true;
if(app.endCurrPage){
app.onAnimationEnd($outpage, $inpage);
}
};
var out_classes = ANIMATION_OUT_CLASS.split(' ');
for(var i = 0; i < out_classes.length; i++)
$outpage.classList.add(out_classes[i]);
$outpage.addEventListener('animationend', outCb, false);
$inpage.classList.add('momo-page-current');
var in_classes = ANIMATION_IN_CLASS.split(' ');
for(var i = 0; i < in_classes.length; i++)
$inpage.classList.add(in_classes[i]);
$inpage.addEventListener('animationend', inCb);
app.current_page = page;
},
onAnimationEnd($outpage, $inpage) {
app.endCurrPage = false;
app.endNextPage = false;
var out_classes = ANIMATION_OUT_CLASS.split(' ');
for(var i = 0; i < out_classes.length; i++)
$outpage.classList.remove(out_classes[i]);
if( $outpage != $inpage)
$outpage.classList.remove('momo-page-current');
var in_classes = ANIMATION_IN_CLASS.split(' ');
for(var i = 0; i < in_classes.length; i++)
$inpage.classList.remove(in_classes[i]);
app.isAnimating = false;
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
window.addEventListener('hashchange', this.onHashChange, false);
@ -122,10 +249,11 @@ var app = {
onHashChange: function(e) {
var page = window.location.hash.slice(1);
if(!page){
page = app.pages['home']
if(!app.pages.hasOwnProperty(page)){
page = 'home';
}
app.renderPage(page);
if(app.current_page != page)
app.navigate(page);
},
onDeviceReady: function() {
@ -137,6 +265,7 @@ var app = {
},
utils: {
updateEl: function(selector, html){
var $el = document.querySelectorAll(selector);
for (var i = 0; i < $el.length; i++)
@ -154,6 +283,65 @@ var app = {
html += '</a>';
}
return html;
},
trim: function(str){
return (str || '').replace(/^\s+|\s+$/g, '');
},
removeNonWord: function(str){
return (str || '').replace(/[^0-9a-zA-Z\xC0-\xFF \-]/g, ''); //remove non-word chars
},
replaceAccents: function(str){
str = str || '';
// verifies if the String has accents and replace them
if (str.search(/[\xC0-\xFF]/g) > -1) {
str = str
.replace(/[\xC0-\xC5]/g, "A")
.replace(/[\xC6]/g, "AE")
.replace(/[\xC7]/g, "C")
.replace(/[\xC8-\xCB]/g, "E")
.replace(/[\xCC-\xCF]/g, "I")
.replace(/[\xD0]/g, "D")
.replace(/[\xD1]/g, "N")
.replace(/[\xD2-\xD6\xD8]/g, "O")
.replace(/[\xD9-\xDC]/g, "U")
.replace(/[\xDD]/g, "Y")
.replace(/[\xDE]/g, "P")
.replace(/[\xE0-\xE5]/g, "a")
.replace(/[\xE6]/g, "ae")
.replace(/[\xE7]/g, "c")
.replace(/[\xE8-\xEB]/g, "e")
.replace(/[\xEC-\xEF]/g, "i")
.replace(/[\xF1]/g, "n")
.replace(/[\xF2-\xF6\xF8]/g, "o")
.replace(/[\xF9-\xFC]/g, "u")
.replace(/[\xFE]/g, "p")
.replace(/[\xFD\xFF]/g, "y");
}
return str;
},
slugify: function(str, delimeter){
if (delimeter == null) {
delimeter = "-";
}
str = app.utils.replaceAccents(str);
str = app.utils.removeNonWord(str);
str = app.utils.trim(str) //should come after removeNonWord
.replace(/ +/g, delimeter) //replace spaces with delimeter
.toLowerCase();
return str;
},
unCamelCase: function(str){
return (str || '').replace(/([a-z\xE0-\xFF])([A-Z\xC0\xDF])/g, '$1 $2').toLowerCase(); //add space between camelCase text
},
hyphenate: function(str){
str = app.utils.unCamelCase(str);
return app.utils.slugify(str, "-");
}
}
};

1
www/js/tmpl.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(a){"use strict";var b=function(a,c){var d=/[^\w\-\.:]/.test(a)?new Function(b.arg+",tmpl","var _e=tmpl.encode"+b.helper+",_s='"+a.replace(b.regexp,b.func)+"';return _s;"):b.cache[a]=b.cache[a]||b(b.load(a));return c?d(c,b):function(a){return d(a,b)}};b.cache={},b.load=function(a){return document.getElementById(a).innerHTML},b.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,b.func=function(a,b,c,d,e,f){return b?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[b]||"\\"+b:c?"="===c?"'+_e("+d+")+'":"'+("+d+"==null?'':"+d+")+'":e?"';":f?"_s+='":void 0},b.encReg=/[<>&"'\x00]/g,b.encMap={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#39;"},b.encode=function(a){return(null==a?"":""+a).replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return b}):a.tmpl=b}(this);