diff --git a/addons/website_blog/static/lib/page-transitions/css/styles.css b/addons/website_blog/static/lib/page-transitions/css/styles.css new file mode 100644 index 00000000000..4e446e1dd9f --- /dev/null +++ b/addons/website_blog/static/lib/page-transitions/css/styles.css @@ -0,0 +1,190 @@ +/* line 2, ../scss/_extensions.scss */ +.container, body article.page .content { + max-width: 100%; + margin: 0 auto; +} + +/* line 7, ../scss/_extensions.scss */ +.stretchy-bg, body article.page .big-image { + background-position: center center; + background-repeat: none; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.big-image, body article.page .big-image { + height: 300px; +} +@media only screen and (min-width: 500px) { + .big-image, body article.page .big-image { + height: 420px; + } +} + +/* line 4, ../scss/_mixins.scss */ +::-webkit-scrollbar { + width: 3px; + height: 3px; +} + +/* line 9, ../scss/_mixins.scss */ +::-webkit-scrollbar-thumb { + background: #666666; +} + +/* line 13, ../scss/_mixins.scss */ +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); +} + +/* line 18, ../scss/_mixins.scss */ +body { + scrollbar-face-color: #666666; + scrollbar-track-color: rgba(255, 255, 255, 0.1); +} + +/* line 11, ../scss/styles.scss */ +body { + color: #555; + padding: 20px; + padding: 0; + margin: 0; + -webkit-backface-visibility: hidden; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + line-height: 1.8em; + /* Responsive typography, yay! */ +} +body h1, body h2, body h3, body h4, body h5, body h6 { + color: #333; +} +/* line 36, ../scss/styles.scss */ +body article.page { + -webkit-transform-origin: bottom center; + /* Class applied when when page fades away. */ + /* The large image that accompanies every post. */ + /* The content. */ +} +/* line 39, ../scss/styles.scss */ +body article.page.hidden { + display: none; +} +/* line 42, ../scss/styles.scss */ +body article.page.next .big-image, body article.page.next .big-image { + cursor: pointer; +} +/* line 43, ../scss/styles.scss */ +body article.page.next .big-image .inner, body article.page.next .big-image .inner { + opacity: 1; +} +/* line 47, ../scss/styles.scss */ +body article.page.content-hidden .content { + display: none; +} +/* line 51, ../scss/styles.scss */ +body article.page.fade-up-out { + opacity: 0; + -webkit-transform: scale(0.8) translate3d(0, -10%, 0); + -moz-transform: scale(0.8) translate3d(0, -10%, 0); + -ms-transform: scale(0.8) translate3d(0, -10%, 0); + -o-transform: scale(0.8) translate3d(0, -10%, 0); + transform: scale(0.8) translate3d(0, -10%, 0); + -webkit-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + -moz-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + -o-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); +} +/* line 57, ../scss/styles.scss */ +body article.page.easing-upward { + -webkit-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + -moz-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + -o-transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); + transition: all 450ms cubic-bezier(0.165, 0.84, 0.44, 1); +} +/* line 69, ../scss/styles.scss */ +body article.page .big-image .inner, body article.page .big-image .inner { + position: relative; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); + -webkit-transition: all 0.1s ease; + -moz-transition: all 0.1s ease; + -o-transition: all 0.1s ease; + transition: all 0.1s ease; +} +/* line 78, ../scss/styles.scss */ +body article.page .big-image .inner .fader, body article.page .big-image .inner .fader { + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.3); +} +/* line 83, ../scss/styles.scss */ +body article.page .big-image .inner .fader .text { + position: absolute; + top: 50%; + left: 50%; + width: 80%; + -webkit-transform: translateX(-50%) translateY(-50%); + -moz-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + -o-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); +} +/* line 89, ../scss/styles.scss */ +body article.page .big-image .inner .fader .text a, body article.page .big-image .inner .fader .text h1, body article.page .big-image .inner .fader .text h2 { + color: white; +} +/* line 91, ../scss/styles.scss */ +body article.page .big-image .inner .fader .text a { + color: white; + border-bottom: 1px solid white; + text-decoration: none; + line-height: 1.5em; +} +/* line 99, ../scss/styles.scss */ +body article.page .big-image .inner .fader .text h1 { + margin: 0; + margin-top: 0.1em; + padding-top: 0em; + padding-bottom: 0em; + margin-bottom: 0em; + line-height: 1.1em; +} +/* line 105, ../scss/styles.scss */ +body article.page .big-image .inner .fader .text h2 { + margin: 0; + margin-top: 0.2em; + padding-top: 0em; + padding-bottom: 0em; + margin-bottom: 0em; + line-height: 1.2em; +} +/* line 119, ../scss/styles.scss */ +body article.page .content { + padding: 0 3em; +} +/* line 123, ../scss/styles.scss */ +body article.page .content h3 { + color: #999; + margin-top: 3em; + padding-top: 0em; + padding-bottom: 0em; + margin-bottom: 0.375em; + line-height: 1.5em; +} +/* line 131, ../scss/styles.scss */ +body article.page .content h1 { + margin-top: 0em; + padding-top: 0em; + padding-bottom: 0em; + margin-bottom: 0.24em; + line-height: 1.08em; +} +/* line 140, ../scss/styles.scss */ +body article.page .content p:last-child { + margin-bottom: 3em; +} diff --git a/addons/website_blog/static/lib/page-transitions/js/app.js b/addons/website_blog/static/lib/page-transitions/js/app.js new file mode 100644 index 00000000000..fdca48c2d66 --- /dev/null +++ b/addons/website_blog/static/lib/page-transitions/js/app.js @@ -0,0 +1,217 @@ + +/* + jQuery Setup +************************************************************************/ +jQuery.ajaxSetup({ + cache: false +}) + +/* + ArticleAnimator Object +************************************************************************/ +var ArticleAnimator = ArticleAnimator || { + canScroll: true, + initialLoad: true, + animationDuration: 500, + postCount: 5, + currentPostIndex: 1, + postCache: {}, + pageTemplate: null, +}; + +ArticleAnimator.load = function(){ + this.currentPostIndex = getURLIndex(); + this.makeSelections(); + $body.append( this.$current ) + $body.append( this.$next ) + + var self = this; + this.createPost({ type: 'current' }, function(){ + self.createPost({ type: 'next' }, function(){ + + /* Selections. */ + self.refreshCurrentAndNextSelection(); + + /* Push initial on to stack */ + history.pushState(pageState(), "", "#" + self.currentPostIndex) + + /* Bind to some events. */ + self.bindGotoNextClick(); + self.bindPopstate(); + self.bindWindowScroll(); + }) + }) +} + +ArticleAnimator.makeSelections = function(){ + this.$page = $('.page'); + this.pageTemplate = elementToTemplate( this.$page.clone()); + this.$current = this.currentElementClone(); + this.$next = this.nextElementClone(); +} + +ArticleAnimator.getPost = function(index, callback){ + callback = callback || $.noop; + + if ( this.postCache[index] ){ + callback( this.postCache[index] ); + return; + } + + var self = this; + openerp.jsonRpc("/blog_post/post/", 'call', { + 'blog': index, + }) + .then(function (data) { + if(!data) + return; + self.postCache[index] = data[0]; + callback(data[0]) + }); +} + +ArticleAnimator.nextPostIndex = function(index){ + return (index === this.postCount) ? 1 : index + 1 +} + +ArticleAnimator.createPost = function(opts, callback){ + opts = opts || {}; + var self = this; + var type = opts['type'] || 'next'; + + if ( opts['fromTemplate'] ){ + $body.append( this.nextElementClone() ); + this['$' + type] = $('.' + type) + } + + var index = (type == 'next') ? this.nextPostIndex( this.currentPostIndex) : this.currentPostIndex; + this.getPost(index, function(d){ + self.contentizeElement(self['$' + type], d); + callback && callback(); + }); + +} + +ArticleAnimator.contentizeElement = function($el, d){ + $el.find('.big-image').css({ backgroundImage: "url(" + d.image + ")" }); + $el.find('h1.title').html(d.title); + $el.find('h2.description').html(d.title_secondary); + $el.find('.content .text').html(d.content); + $el.find('h3.byline time').html(d.date); + $el.find('h3.byline .author').html(d.author); +} + +ArticleAnimator.animatePage = function(callback){ + var self = this; + var translationValue = this.$next.get(0).getBoundingClientRect().top; + this.canScroll = false; + + this.$current.addClass('fade-up-out'); + + this.$next.removeClass('content-hidden next') + .addClass('easing-upward') + .css({ "transform": "translate3d(0, -"+ translationValue +"px, 0)" }); + + setTimeout(function(){ + scrollTop(); + self.$next.removeClass('easing-upward') + self.$current.remove(); + + self.$next.css({ "transform": "" }); + self.$current = self.$next.addClass('current'); + + self.canScroll = true; + self.currentPostIndex = self.nextPostIndex( self.currentPostIndex ); + + callback(); + }, self.animationDuration ); +} + +ArticleAnimator.bindGotoNextClick = function(){ + var self = this; + var e = 'ontouchstart' in window ? 'touchstart' : 'click'; + + this.$next.find('.big-image').on(e, function(e){ + e.preventDefault(); + $(this).unbind(e); + + self.animatePage(function(){ + self.createPost({ fromTemplate: true, type: 'next' }); + self.bindGotoNextClick(); + history.pushState( pageState(), '', "#" + self.currentPostIndex); + }); + }); +} + +ArticleAnimator.bindPopstate = function(){ + var self = this; + $window.on('popstate', function(e){ + + if( !history.state || self.initialLoad ){ + self.initialLoad = false; + return; + } + + self.currentPostIndex = history.state.index; + self.$current.replaceWith( history.state.current ); + self.$next.replaceWith( history.state.next ); + + self.refreshCurrentAndNextSelection(); + self.createPost({ type: 'next' }); + self.bindGotoNextClick(); + }); +} + +ArticleAnimator.bindWindowScroll = function(){ + var self = this; + $window.on('mousewheel', function(ev){ + if ( !self.canScroll ) + ev.preventDefault() + }) +} + +ArticleAnimator.refreshCurrentAndNextSelection = function(){ + this.$current = $('.page.current'); + this.$next = $('.page.next'); +} + +ArticleAnimator.nextElementClone = function(){ + return this.$page.clone().removeClass('hidden').addClass('next content-hidden'); +} + +ArticleAnimator.currentElementClone = function(){ + return this.$page.clone().removeClass('hidden').addClass('current'); +} + +/* + Helper Functions. +************************************************************************/ +function elementToTemplate($element){ + return $element.get(0).outerHTML; +} + +function scrollTop(){ + $body.add($html).scrollTop(0); +} + +function pageState(){ + return { index: ArticleAnimator.currentPostIndex, current: elementToTemplate(ArticleAnimator.$current), next: elementToTemplate(ArticleAnimator.$next) } +} + +function getURLIndex(){ + return parseInt( (history.state && history.state.index) ||window.location.hash.replace('#', "") || ArticleAnimator.currentPostIndex ); +} + + +/* + Document ready. +************************************************************************/ +$(document).ready(function(){ + /* A couple of selections. */ + $body = $('main'); + $window = $(window); + $html = $(document.documentElement); + + /* Let's get it started. */ + ArticleAnimator.load(); +})