BB: Panel View
by kyllle
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.css">
<header class="main-header">
<button class="js-action--show">Show</button>
<button class="js-action--hide">Hide</button>
</header>
<script type="text/template" class="tmpl-scroller">
<div class="scroller__content js-region--scroll"></div>
</script>
<script type="text/template" class="tmpl-content">
<h1>Card content</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa quisquam, harum animi, eius recusandae quos fuga, quibusdam nam facilis sit ad repudiandae fugiat nesciunt nostrum sed quaerat laboriosam nihil architecto.</p>
</script>
SCSS
* {
-webkit-font-smoothing: antialiased;
}
html, body {
height: 100%;
}
.scroller {
height: 100%;
width: 100%;
&__content {
-webkit-user-select: none;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
transform: translateZ(0);
height: 100%;
}
}
.anim-slide {
position: absolute;
transition: transform .3s ease;
&--from-top,
&--from-bottom {
&.is-animating {
transform: translateY(0);
}
}
&--from-top {
transform: translateY(-100%);
top: 0;
}
&--from-bottom {
transform: translateY(100%);
bottom: 0;
}
&--from-left,
&--from-right {
top: 0;
&.is-animating {
transform: translateX(0);
}
}
&--from-left {
transform: translateX(-100%);
right: 0;
}
&--from-right {
transform: translateX(100%);
left: 0;
}
&--override {
transition: none;
}
}
.scroller {
background: #eee;
}
.main-header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #ddd;
padding: 6px;
z-index: 10;
}
Babel + JSX
console.clear();
(() => {
const ScrollerView = Backbone.View.extend({
className: 'anim-slide scroller',
stateClasses: {
isAnimating: 'is-animating'
},
template: Handlebars.compile($('.tmpl-scroller').html()),
offsetAllowList: ['top', 'right', 'bottom', 'left'],
initialize(options) {
this.options = options || {};
// Should probably live in a model.
if(this.options.offset && _.contains(this.offsetAllowList, this.options.offset)) {
const offsetClass = ' anim-slide--from-'.concat(this.options.offset);
this.el.className += offsetClass;
} else {
this.el.className += ' anim-slide--from-bottom';
}
this.listenTo(this, 'panel.animate:show.complete', this.onShow);
this.listenTo(this, 'panel.animate:hide.complete', this.onHide);
},
render() {
console.log('ScrollerView.render');
this.$el.html(this.template());
setTimeout(() => {this.afterRender()}, 0);
return this;
},
afterRender() {
console.log('ScrollerView.afterRender');
},
show() {
console.log('ScrollerView.show');
this.$el.addClass(this.stateClasses.isAnimating);
this.$el.one('transitionend', event => this.trigger('panel.animate:show.complete'));
},
hide() {
console.log('ScrollerView.hide');
this.$el.removeClass(this.stateClasses.isAnimating);
this.$el.one('transitionend', event => this.trigger('panel.animate:hide.complete'));
},
onShow() {
console.log('ScrollerView.onShow');
},
onHide() {
console.log('ScrollerView.onHide');
setTimeout(() => {this.dispose()}, 0);
},
dispose() {
console.log('ScrollerView.dispose');
if(this.options.childViews) {
this.options.childViews.forEach(view => view.dispose());
}
return...