Skip to content

Instantly share code, notes, and snippets.

@Qvatra
Created March 30, 2015 09:15
Show Gist options
  • Save Qvatra/7ac1e2c47e87fdf6dbde to your computer and use it in GitHub Desktop.
Save Qvatra/7ac1e2c47e87fdf6dbde to your computer and use it in GitHub Desktop.
Slide Show for famo.us
define(function (require, exports, module) {
'use strict';
var Surface = require('famous/core/Surface');
var StateModifier = require('famous/modifiers/stateModifier');
var Transform = require('famous/core/Transform');
var EventHandler = require('famous/core/EventHandler');
var OptionsManager = require('famous/core/OptionsManager');
var View = require('famous/core/View');
var ContainerSurface = require('famous/surfaces/ContainerSurface');
var Utility = require('famous/utilities/Utility');
function Slidershow(options) {
this.options = Object.create(Slidershow.DEFAULT_OPTIONS);
this._optionsManager = new OptionsManager(this.options);
if (options) this.setOptions(options);
this.total = this.options.sliders.length;
this.page = 1;
this._sliders = [];
this._rwdDelay = undefined;
this._currentSlideId = 0;
this._navigationSurf = [];
this._eventOutput = new EventHandler();
EventHandler.setOutputHandler(this, this._eventOutput);
_createSlider.call(this);
}
Slidershow.DEFAULT_OPTIONS = {
width: window.innerWidth,
height: 500,
transition: {
duration: 600,
curve: 'easeInOut'
},
navDotRadius: window.innerWidth/100,
navDotGap: window.innerWidth / 75
};
function _createSlider() {
this.container = new ContainerSurface({
size: [(this.options.width === window.innerWidth ? undefined : this.options.width), this.options.height],
properties: {
overflow: 'hidden',
backgroundColor: 'rgb(33, 33, 33)'
}
});
this.sliderContainer = new ContainerSurface({
size: [(this.options.width === window.innerWidth ? undefined : this.options.width), this.options.height],
properties: {
overflow: 'hidden'
}
});
// Create slide items
_createSlideItem.call(this);
// Navigation
if (this.total > 1) _createNavigation.call(this);
this.container.add(this.sliderContainer);
if (this.options.width === window.innerWidth) {
window.addEventListener('resize', function () {
this.options.width = window.innerWidth;
}.bind(this), false);
}
}
function _createNavButton(direction) { // Prev, Next button
var container, surf, mod;
container = new ContainerSurface({
size: [true, undefined],
properties: {
background: 'rgba(33,33,33,0.4)',
padding: '2em'
}
});
surf = new Surface({
size: [true, true],
content: '<i class="fa fa-angle-' + (direction === 'prev' ? 'left' : 'right') + '"></i>',
classes: ['projects-assets-nav-button']
});
mod = new StateModifier({
align: [0.5, 0.5],
origin: [0.5, 0.5]
});
container.add(mod).add(surf);
mod = new StateModifier({
align: [(direction === 'prev' ? 0 : 1), 0.5],
origin: [(direction === 'prev' ? 0 : 1), 0.5]
});
container.on('click', function (e) {
this.slidingPage(direction);
}.bind(this));
this.container.add(mod).add(container);
}
function _createNavBubble(bubble, view) {
var surf, mod;
surf = new Surface({
classes: ['projects-assets-bubble-button'],
properties: {
borderWidth: this.options.navDotRadius + 'px',
borderRadius: bubble === 0 ? 2 * this.options.navDotRadius + 'px' : this.options.navDotRadius + 'px',
padding: bubble === 0 ? this.options.navDotRadius + 'px' : '0px'
}
});
var dist = (bubble != 0) ? bubble * (this.options.navDotRadius * 2 + this.options.navDotGap) - this.options.navDotRadius : -2 * this.options.navDotRadius;
mod = new StateModifier({
size: (bubble === 0 ? [this.options.navDotRadius * 3, this.options.navDotRadius * 3] : [this.options.navDotRadius, this.options.navDotRadius]),
transform: Transform.translate(dist, 0, 0.01),
origin: [0, 0.5]
});
view._add(mod).add(surf);
surf.on('click', function (e) {
this.jumpToSlide(bubble);
}.bind(this));
this._navigationSurf.push({ view: view, surf: surf });
}
function _createNavigation() {
var surf, mod, container, view, i;
_createNavButton.call(this, 'prev');
_createNavButton.call(this, 'next');
container = new ContainerSurface({
size: [(this.total - 1) * (this.options.navDotGap + 2 * this.options.navDotRadius), this.options.navDotRadius]
});
view = new View();
for (i = 0; i < this.total; i++) {
_createNavBubble.call(this, i, view);
}
container.add(view);
mod = new StateModifier({
origin: [0.5, 0.5],
align: [0.5, 0.9]
});
this.container.add(mod).add(container);
}
function _createSlideItem() {
for (var i = (this.total - 1) ; i >= 0; i--) {
var container = new ContainerSurface({ size: [this.options.width, this.options.height] });
if (typeof this.options.sliders[i] === 'object') container.add(this.options.sliders[i]);
var view = new View({});
var dx; // calculate nitial x position of the slide
if (i === 0) { //first item
dx = 0;
} else {
if (i === 1) { //next item
dx = this.options.width;
} else if (i === this.total - 1) { // prev item
dx = -this.options.width;
} else {
dx = -10 * this.options.width; //all other items
}
}
view.add(new StateModifier({
transform: Transform.translate(dx, 0, 0.01)
})).add(container);
this._sliders.push(view);
this.sliderContainer.add(view);
}
}
function _resetNavigation(slideId) {
var activated = {
borderRadius: 2 * this.options.navDotRadius + 'px',
padding: this.options.navDotRadius + 'px'
}
var deactivated = {
borderRadius: this.options.navDotRadius + 'px',
padding: '0px'
}
var nav = this._navigationSurf[this._currentSlideId];
nav.surf.setOptions({ properties: deactivated });
nav.view._node._child[this._currentSlideId].get().setSize([this.options.navDotRadius, this.options.navDotRadius]);
var dist = this._currentSlideId * (this.options.navDotRadius * 2 + this.options.navDotGap) - this.options.navDotRadius;
nav.view._node._child[this._currentSlideId].get().setTransform(Transform.translate(dist, 0, 0.01));
nav.view._node._child[this._currentSlideId].get().setOrigin([0, 0.5]);
nav = this._navigationSurf[slideId];
nav.surf.setOptions({ properties: activated });
nav.view._node._child[slideId].get().setSize([this.options.navDotRadius * 3, this.options.navDotRadius * 3]);
var dist = slideId * (this.options.navDotRadius * 2 + this.options.navDotGap) - 2 * this.options.navDotRadius;
nav.view._node._child[slideId].get().setTransform(Transform.translate(dist, 0, 0.01));
nav.view._node._child[slideId].get().setOrigin([0, 0.5]);
this._currentSlideId = slideId;
}
Slidershow.prototype.getTotal = function getTotal() {
return this.total;
};
Slidershow.prototype.getPage = function getPage() {
return this.page;
};
Slidershow.prototype.jumpToSlide = function jumpToSlide(slide, direction /* only for prev, next */) {
var current = this.total - this.page >= this.total ?
this.total - 1 : this.total - this.page <= 0 ?
0 : this.total - this.page,
next = current - 1 < 0 ? this.total - 1 : current - 1,
prev = current + 1 >= this.total ? 0 : current + 1,
feature = this.total - (slide + 1);
if (current === feature) return true;
var direction = direction || 'feature';
_resetNavigation.call(this, slide);
if (Math.abs(current - feature) !== (this.total - 1)) {
this._sliders[next]._node.get().setTransform(
Transform.translate(this.options.width * -10, 0, 0.01),
undefined
);
this._sliders[prev]._node.get().setTransform(
Transform.translate(this.options.width * -10, 0, 0.01),
undefined
);
}
this._sliders[feature]._node.get().setTransform(
Transform.translate(this.options.width * (current > feature ? 1 : -1), 0, 0.01)
);
this._sliders[feature]._node.get().setTransform(
Transform.translate(0, 0, 0.01),
this.options.transition
);
this._sliders[current]._node.get().setTransform(
Transform.translate(this.options.width * (current > feature ? -1 : 1), 0, 0.01),
this.options.transition
);
if (Math.abs(current - feature) !== (this.total - 1)) {
next = feature - 1 < 0 ? this.total - 1 : feature - 1;
prev = feature + 1 >= this.total ? 0 : feature + 1;
if (current > feature) {
this._sliders[next]._node.get().setTransform(
Transform.translate(this.options.width, 0, 0.01),
undefined
);
} else {
this._sliders[prev]._node.get().setTransform(
Transform.translate(this.options.width * -1, 0, 0.01),
undefined
);
}
}
this.page = slide + 1;
this.page = (this.page > this.total) ? 1 : (this.page < 1) ? this.total : this.page;
this._eventOutput.emit('pageChange', { page: this.page, direction: direction });
};
Slidershow.prototype.slidingPage = function slidingPage(direction) {
if (direction === 'next') {
this.jumpToSlide((this.page >= this.total) ? 0 : this.page, direction);
} else if (direction === 'prev') {
this.jumpToSlide((this.page <= 1) ? this.total - 1 : this.page - 2, direction);
}
};
Slidershow.prototype.setOptions = function setOptions(options) {
if (options.sliders === undefined || options.sliders.length === 0) {
options.sliders = [];
}
if (options.width === undefined || typeof options.width !== 'number') {
options.width = window.innerWidth;
}
if (options.height === undefined || typeof options.height !== 'number') {
options.height = 500;
}
if (options.transition === undefined || typeof options.transition !== 'object') {
options.transition = {
duration: 600,
curve: 'easeInOut'
};
}
this._optionsManager.setOptions(options);
};
Slidershow.prototype.render = function render() {
if (this.total === 0) return null;
return [
{
target: this.container.render()
}
];
};
module.exports = Slidershow;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment