Current File : /home/users/barii/public_html/finansenl.com.pl/wodki/js/slidr.js |
/*!
* slidr v0.5.0 - A Javascript library for adding slide effects.
* bchanx.com/slidr
* MIT licensed
*
* Copyright (c) 2014 Brian Chan (bchanx.com)
*/
(function(root, factory) {
// CommonJS
if (typeof exports === 'object') module['exports'] = factory();
// AMD module
else if (typeof define === 'function' && define['amd']) define(factory);
// Browser globals
else root['slidr'] = factory();
} (this, function() {
'use strict';
// Traverse [keys] in {object} to lookup a value, or null if nothing found.
function lookup(obj, keys) {
var result = obj;
for (var k in keys) {
if (!result || !result.hasOwnProperty(keys[k])) return null;
result = result[keys[k]];
}
return (result === obj) ? null : result;
}
// Merge all properties from {arguments} and return the new {object}.
function extend(/* arg1, arg2.. */) {
var newobj = {};
for (var i = 0, arg; arg = arguments[i]; i++) for (var a in arg) newobj[a] = arg[a];
return newobj;
}
// Check whether node a contains node b.
function contains(a, b) {
return (a.contains) ? a.contains(b) : (a.compareDocumentPosition) ? a.compareDocumentPosition(b) & 16 : 0;
}
// Returns the tag name, normalized.
function tagName(el) {
return (el.tagName) ? el.tagName.toLowerCase() : null;
}
// Simple indexOf polyfill for IE8.
function indexOf(list, val) {
if (Array.prototype.indexOf) return list.indexOf(val);
for (var i = 0, len = list.length; i < len; i++) if (list[i] === val) return i;
return -1;
}
// Simple trim polyfill for IE8.
function trim(str) {
return ("".trim) ? str.trim() : str.replace(/^\s+|\s+$/g, '');
}
// Creates a document element, and sets any properties passed in.
function createEl(tag, props) {
var el = document.createElement(tag);
for (var p in props) el[p] = props[p];
return el;
}
// Add/rm class(es) on an element.
function classname(el, type /* class1, class2... */) {
var clsnames = trim(el.className);
clsnames = (clsnames) ? clsnames.split(/\s+/) : [];
for (var a = 2, cls, idx; cls = arguments[a]; a++) {
idx = indexOf(clsnames, cls);
if (type === 'add' && idx < 0) clsnames.push(cls);
if (type === 'rm' && idx >= 0) clsnames.splice(idx, 1);
}
el.className = clsnames.join(' ');
return el;
}
// Normalize a string. Strip spaces, single, and double quotes then return in alphabetical order.
function normalize(str) {
return str.replace(/[\s'"]/gi, '').split('').sort().join('');
}
// Set name:value attribute for an element.
function setattr(el, name, value) {
if (el && el.setAttribute) el.setAttribute(name, value);
return el;
}
// Get attribute from an element.
function getattr(el, name) {
return (el && el.getAttribute) ? el.getAttribute(name) : null;
}
// If `prop` is a string, do a CSS lookup. Otherwise, add CSS styles to `el`.
function css(el, prop) {
if (typeof prop === 'string') {
var view = (document.defaultView) ? document.defaultView.getComputedStyle(el) : el.currentStyle;
var style = view[browser.fix(prop)];
if (!style && prop === 'opacity') style = (view.filter) ? view.filter.split('=')[1].replace(')', '') : '1';
if (style) {
var val = style.slice(0, -2);
return (style.slice(-2) === 'px' && !isNaN(parseInt(val)) && val.search('px') <= 0) ? parseInt(val) : style;
}
return 'none';
}
for (var p in prop) if (browser.fix(p)) el.style[browser.fix(p)] = prop[p];
return el;
}
// Bind element event(s) to a callback.
function bind(el, ev, callback, optUnbind) {
if (typeof(ev) === 'string') ev = [ev];
for (var i = 0, e, isAnimation; e = ev[i]; i++) {
isAnimation = indexOf(browser.animations, e) > 0;
e = (e === 'click' && 'ontouchstart' in window) ? 'touchend' :
(el.attachEvent && !isAnimation) ? 'on' + e : e;
(el.attachEvent && !isAnimation) ? (optUnbind ? el.detachEvent(e, callback) : el.attachEvent(e, callback)) :
(optUnbind ? el.removeEventListener(e, callback) : el.addEventListener(e, callback));
}
}
// Unbind element event(s) to a callback.
function unbind(el, ev, callback) {
bind(el, ev, callback, true);
}
// Check whether element has border-box set.
function borderbox(el) {
return css(el, 'box-sizing') === 'border-box';
}
var browser = {
// Vendor prefixes.
prefixes: ['webkit', 'Moz', 'ms', 'O'],
// CSS property cache.
cache: {},
// CSS keyframe cache.
keyframes: {},
// Flag for IE < 8.
isIE: function() {
if (browser.supports('filter') && !browser.supports('opacity')) browser.isIE = function() { return true; };
else browser.isIE = function() { return false; };
return browser.isIE();
},
// Reference to the document style element.
styleEl: document.getElementsByTagName('html')[0]['style'],
// Slidr CSS style sheet.
styleSheet: (function() {
var el = createEl('style', { 'type' : 'text/css' });
document.getElementsByTagName('head')[0].appendChild(el);
return el.sheet || el.styleSheet;
}()),
// Get browser specific stylesheet rules.
cssRules: function() {
browser.cssRules = function() { return browser.styleSheet.cssRules || browser.styleSheet.rules; };
return browser.cssRules();
},
// Use browser specific insert for stylesheets.
insertRule: function(rule) {
if (browser.styleSheet.insertRule) {
browser.insertRule = function(r) { browser.styleSheet.insertRule(r, browser.cssRules().length); };
} else {
browser.insertRule = function(r) {
var split = r.split(' {');
if (split.length === 2) {
var left = split[0];
var right = trim(split[1].replace(/;?\s?}$/g, ''));
if (left && right) browser.styleSheet.addRule(left, right);
}
}
}
browser.insertRule(rule);
},
// Adds a CSS rule to our Slidr stylesheet.
addCSSRule: function(name, rule, optSafe) {
name = normalize(name);
for (var r = 0, cssRule, cssName; cssRule = browser.cssRules()[r]; r++) {
cssName = normalize((cssRule.name || cssRule.selectorText || cssRule.cssText.split(' {')[0] || ''));
if (cssName === name) {
if (!!optSafe || (normalize(cssRule.cssText) === normalize(rule))) return;
browser.styleSheet.deleteRule(r);
break;
}
}
browser.insertRule(rule);
},
// Creates a CSS rule.
createRule: function(name, props) {
var rule = [name, '{'];
for (var p in props) if (browser.fix(p, true)) rule.push(browser.fix(p, true) + ':' + props[p] + ';');
rule.push('}');
return rule.join(' ');
},
// Creates a CSS style.
createStyle: function(name, props, optSafe) {
browser.addCSSRule(name, browser.createRule(name, props), optSafe);
},
// Get browser prefix.
prefix: function(prop) {
return (prop.split('-').length === 3) ? '-' + prop.split('-')[1] + '-' : '';
},
// Creates a keyframe animation rule.
createKeyframe: function(name, rules) {
var animation = browser.fix('animation', true);
if (animation && !browser.keyframes[name]) {
var rule = ['@' + browser.prefix(animation) + 'keyframes ' + name + ' {'];
for (var r in rules) rule.push(browser.createRule(r + '%', rules[r]));
rule.push('}');
browser.addCSSRule(name, rule.join(' '));
browser.keyframes[name] = true;
}
},
// Returns the browser supported property name, or null.
fix: function(prop, forCSS) {
if (!(prop in browser.cache)) {
var parts = prop.split('-');
for (var i = 0, p; p = parts[i]; i++) parts[i] = p[0].toUpperCase() + p.toLowerCase().slice(1);
var domprop = parts.join('');
domprop = domprop[0].toLowerCase() + domprop.slice(1);
if (browser.styleEl[domprop] !== undefined) {
browser.cache[prop] = { css: prop, dom: domprop };
} else {
domprop = parts.join('');
for (i = 0; i < browser.prefixes.length; i++) {
if (browser.styleEl[browser.prefixes[i] + domprop] !== undefined) {
browser.cache[prop] = {
css: '-' + browser.prefixes[i].toLowerCase() + '-' + prop, dom: browser.prefixes[i] + domprop
};
}
}
}
if (!browser.cache[prop]) browser.cache[prop] = null;
}
return (browser.cache[prop] !== null) ? (forCSS) ? browser.cache[prop].css : browser.cache[prop].dom : null;
},
// Check whether all given css properties are supported in the browser.
supports: function(/* prop1, prop2... */) {
for (var i = 0, prop; prop = arguments[i]; i++) if (!browser.fix(prop)) return false;
return true;
},
// Add CSS keyframes.
add: {
'fade': function(name, oStart, oEnd) {
browser.createKeyframe(name, {
'0': { 'opacity': oStart, 'visibility': 'visible' }, '100': { 'opacity': oEnd, 'visibility': 'hidden' }
});
},
'linear': function(name, type, tStart, tEnd, oStart, oEnd) {
browser.createKeyframe(name, {
'0': { 'transform': 'translate' + tStart[0] + '(0%)',
'opacity': (type === 'in' ? '0': oStart), 'visibility': 'visible' },
'1': { 'transform': 'translate' + tStart + 'px)', 'opacity': oStart },
'99': { 'transform': 'translate' + tEnd + 'px)', 'opacity': oEnd },
'100': { 'transform': 'translate' + tEnd[0] + '(0%)',
'opacity': (type === 'out' ? '0' : oEnd), 'visibility': 'hidden' }
});
},
'cube': function(name, rStart, rEnd, tZ, oStart, oEnd) {
browser.createKeyframe(name, {
'0': { 'transform': 'rotate' + rStart + '0deg) translateZ(' + tZ + 'px)', 'opacity': oStart,
'visibility': 'visible' },
'100': { 'transform': 'rotate' + rEnd + '0deg) translateZ(' + tZ + 'px)', 'opacity': oEnd,
'visibility': 'hidden' }
});
}
},
// CSS classnames for breadcrumbs/controls.
classnames: function(cls) {
return {
main: cls,
maincss: 'aside[id*="-' + cls + '"]',
nav: 'slidr-' + cls,
navcss: 'aside[id*="-' + cls + '"] .slidr-' + cls,
data: 'data-slidr-' + cls,
id: function(_, css) { return css ? 'aside[id="' + _.id + '-' + cls + '"]' : _.id + '-' + cls; }
}
},
// Sanitize events for IE.
sanitize: function(e) {
e = e || window.event;
if (!e.target) e.target = e.srcElement;
if (!e.currentTarget) e.currentTarget = e.srcElement;
if (!e.which && e.keyCode) e.which = e.keyCode;
return e;
},
// Stop event propagation.
stop: function(e) {
e = e || window.event;
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
return false;
},
// Animationend events.
animations: ['animationend', 'webkitAnimationEnd', 'oanimationend', 'MSAnimationEnd']
};
var transition = {
// Available transitions.
available: ['cube', 'fade', 'linear', 'none'],
// Validates a given transition.
validate: function(_, trans) {
trans = trans || _.settings['transition'];
return (indexOf(transition.available, trans) < 0 || !fx.supported[trans]) ? 'none' : trans;
},
// Get the direction transition for an element.
get: function(_, el, type, dir) {
return lookup(_.trans, [el, (type === 'in') ? slides.opposite(dir) : dir]);
},
// Sets the direction transition for an element.
set: function(_, el, dir, trans) {
trans = transition.validate(_, trans);
if (!_.trans[el]) _.trans[el] = {};
_.trans[el][dir] = trans;
return trans;
},
// Applies a directional transition to an element entering/leaving the Slidr.
apply: function(_, el, type, dir, trans) {
breadcrumbs.update(_, el, type);
fx.animate(_, el, trans, type, dir);
}
};
var callback = {
// Cache before/after hashes to prevent duplicate calls.
cache: {},
// Generate a unique hash string per metadata.
hash: function(meta) {
return [meta['id'], meta['in']['slidr'], meta['in']['trans'], meta['in']['dir'], meta['out']['slidr'],
meta['out']['trans'], meta['out']['dir']].join('-');
},
// Generate callback metadata.
meta: function(_, outs, ins, outdir, indir, outtrans, intrans) {
return {
'id': _.id,
'in': { 'el': slides.get(_, ins).el, 'slidr': ins, 'trans': intrans, 'dir': indir },
'out': { 'el': slides.get(_, outs).el, 'slidr': outs, 'trans': outtrans, 'dir': slides.opposite(outdir) }
};
},
// Callback before a Slidr transition.
before: function(_, meta) {
var hash = callback.hash(meta);
if (!callback.cache[hash]) callback.cache[hash] = {};
if (!callback.cache[hash].before) {
callback.cache[hash].before = true;
var cb = _.settings['before'];
if (typeof cb === 'function') cb(meta);
}
},
// Callback after a Slidr animation.
after: function(_, meta) {
var hash = callback.hash(meta);
if (!callback.cache[hash].after) {
callback.cache[hash].after = true;
var cb = _.settings['after'];
if (typeof cb === 'function') callback.bindonce(cb, meta);
}
},
// Bind after callback once.
bindonce: function(cb, meta) {
if (browser.supports('animation') && meta['in']['trans'] !== 'none') {
var newCallback = function(e) {
if (browser.keyframes[e.animationName]) {
cb(meta);
unbind(meta['in']['el'], browser.animations, newCallback);
callback.reset(meta);
}
};
bind(meta['in']['el'], browser.animations, newCallback);
} else {
cb(meta);
callback.reset(meta);
}
},
// Reset animation cache.
reset: function(meta) {
var hash = callback.hash(meta);
callback.cache[hash].before = false;
callback.cache[hash].after = false;
}
};
var slides = {
// Possible directions.
directions: ['left', 'up', 'top', 'right', 'down', 'bottom'],
// Check if next is a direction.
isdir: function(next) {
return indexOf(slides.directions, next) >= 0;
},
// Get the opoosite direction.
opposite: function(dir) {
var length = slides.directions.length;
return slides.isdir(dir) ? slides.directions[(indexOf(slides.directions, dir) + length/2) % length] : null;
},
// Get slide metadata.
get: function(_) {
var args = [];
for (var i = 1, a; (a = arguments[i++]) !== undefined; args.push(a)) {};
return lookup(_.slides, args);
},
// Display our starting slide.
display: function(_) {
if (!_.displayed && slides.get(_, _.start)) {
_.current = _.start;
breadcrumbs.create(_);
controls.create(_);
fx.init(_, _.current, 'fade');
fx.animate(_, _.current, 'fade', 'in');
_.displayed = true;
actions.controls(_, _.settings['controls']);
if (!!_.settings['breadcrumbs']) actions.breadcrumbs(_);
}
},
// Transition to the next slide.
slide: function(_, next) {
return slides.isdir(next) ? slides.go(_, slides.get(_, _.current, next), next, next) : slides.jump(_, next);
},
// Jump to a target slide.
jump: function(_, el) {
if (el && el !== _.current && slides.get(_, el)) {
var cur = _.crumbs[_.current];
var next = _.crumbs[el];
var hdir = (cur.x < next.x) ? 'right' : (cur.x > next.x) ? 'left' : null;
var vdir = (cur.y < next.y) ? 'up': (cur.y > next.y) ? 'down': null;
var outdir = (transition.get(_, _.current, 'out', hdir)) ? hdir :
(transition.get(_, _.current, 'out', vdir)) ? vdir : null;
var indir = (transition.get(_, el, 'in', hdir)) ? hdir :
(transition.get(_, el, 'in', vdir)) ? vdir : null;
slides.go(_, el, outdir, indir, (outdir) ? null : 'fade', (indir) ? null : 'fade');
}
},
// Go to a target slide.
go: function(_, el, outdir, indir, opt_outtrans, opt_intrans) {
if (_.current && el) {
var intrans = opt_intrans || transition.get(_, el, 'in', indir);
var outtrans = opt_outtrans || transition.get(_, _.current, 'out', outdir);
var meta = callback.meta(_, _.current, el, outdir, indir, outtrans, intrans);
callback.before(_, meta);
transition.apply(_, el, 'in', indir, intrans);
transition.apply(_, _.current, 'out', outdir, outtrans);
callback.after(_, meta);
_.current = el;
controls.update(_);
return true;
}
return false;
},
// Finds all valid slides (direct children with 'data-slidr' attributes).
find: function(_, opt_asList) {
var valid = (opt_asList) ? [] : {};
for (var i = 0, slide, name; slide = _.slidr.childNodes[i]; i++) {
name = getattr(slide, 'data-slidr');
if (name) {
if (opt_asList && indexOf(valid, name) < 0) valid.push(name);
else if (!(name in valid)) valid[name] = slide;
}
}
return valid;
},
// Validate the [ids] we're trying to add doesn't conflict with existing slide assignments.
validate: function(_, ids, trans, valid, prev, next) {
if (!ids || ids.constructor !== Array) return false;
// For each slide we're trying to add, check it against our known mapping.
for (var i = 0, current, newPrev, newNext, oldPrev, oldNext,
prevPrev, oldPrevTrans, oldNextTrans; current = ids[i]; i++) {
if (!(current in valid)) return false;
if (slides.get(_, current)) {
newPrev = ids[i-1] || null;
newNext = ids[i+1] || null;
oldPrev = slides.get(_, current, prev);
oldNext = slides.get(_, current, next);
prevPrev = slides.get(_, newNext, prev);
oldPrevTrans = transition.get(_, current, 'out', prev);
oldNextTrans = transition.get(_, current, 'out', next);
// Are we about to override an existing mapping?
if ((oldNext && newNext && oldNext != newNext)
|| (oldPrev && newPrev && oldPrev != newPrev)
|| (prevPrev && prevPrev != current)
|| (newPrev && oldPrevTrans && oldPrevTrans != trans)
|| (newNext && oldNextTrans && oldNextTrans != trans)
) {
return false;
}
}
}
return true;
},
// Adds a [list] of ids to our Slidr.
add: function(_, ids, trans, valid, prev, next) {
for (var i = 0, current; current = ids[i]; i++) {
_.slides[current] = _.slides[current] || {};
var s = slides.get(_, current);
s.el = valid[current];
if (ids[i-1]) {
s[prev] = ids[i-1];
transition.set(_, current, prev, trans);
}
if (ids[i+1]) {
s[next] = ids[i+1];
transition.set(_, current, next, trans);
}
fx.init(_, current, trans);
_.start = (!_.start) ? current : _.start;
}
if (_.started) (!_.displayed) ? slides.display(_) : breadcrumbs.create(_);
return true;
}
};
var controls = {
// Classnames
cls: browser.classnames('control'),
// Available control types.
types: ['border', 'corner', 'none'],
// Whether it's a valid control type.
valid: function(ctrl) {
return indexOf(controls.types, ctrl) >= 0;
},
// Create controls container.
create: function(_) {
if (_.slidr && !_.controls) {
_.controls = css(classname(createEl('aside', { 'id': controls.cls.id(_) }), 'add', 'disabled'), {
'opacity': '0',
'filter': 'alpha(opacity=0)',
'z-index': '0',
'visibility': 'hidden',
'pointer-events': 'none'
});
for (var n in _.nav) {
_.nav[n] = setattr(classname(createEl('div'), 'add', controls.cls.nav, n), controls.cls.data, n);
_.controls.appendChild(_.nav[n]);
}
controls.css(_);
_.slidr.appendChild(_.controls);
bind(_.controls, 'click', controls.onclick(_));
}
},
// Controls CSS rules.
css: function(_) {
browser.createStyle(controls.cls.maincss, {
'position': 'absolute',
'bottom': css(_.slidr, 'padding-bottom') + 'px',
'right': css(_.slidr, 'padding-right') + 'px',
'padding': '10px',
'box-sizing': 'border-box',
'width': '75px',
'height': '75px',
'transform': 'translateZ(9998px)'
}, true);
browser.createStyle(controls.cls.maincss + '.disabled', {
'transform': 'translateZ(0px) !important'
}, true);
browser.createStyle(controls.cls.maincss + '.breadcrumbs', {
'left': css(_.slidr, 'padding-left') + 'px',
'right': 'auto'
}, true);
browser.createStyle(controls.cls.maincss + '.border', {
'bottom': '0',
'right': '0',
'left': '0',
'width': '100%',
'height': '100%'
}, true);
browser.createStyle(controls.cls.navcss, {
'position': 'absolute',
'pointer-events': 'auto',
'cursor': 'pointer',
'transition': 'opacity 0.2s linear'
}, true);
var disabled = {
'opacity': '0.05',
'cursor': 'auto'
};
if (browser.isIE()) disabled['display'] = 'none';
browser.createStyle(controls.cls.navcss + '.disabled', disabled, true);
var n, horizontal, pos, dir, ctrl, after, border, borderpad;
for (n in _.nav) {
horizontal = (n === 'left' || n === 'right');
pos = (n === 'up') ? 'top' : (n === 'down') ? 'bottom' : n;
dir = horizontal ? 'top' : 'left';
ctrl = {
'width': horizontal ? '22px': '16px',
'height': horizontal ? '16px' : '22px',
'tap-highlight-color': 'rgba(0, 0, 0, 0)',
'touch-callout': 'none',
'user-select': 'none'
};
ctrl[pos] = '0';
ctrl[dir] = '50%';
ctrl['margin-' + dir] = '-8px';
browser.createStyle(controls.cls.navcss + '.' + n, ctrl, true);
after = {
'width': '0',
'height': '0',
'content': '""',
'position': 'absolute',
'border': '8px solid transparent'
};
after['border-' + slides.opposite(pos) + '-width'] = '12px';
after['border-' + pos + '-width'] = '10px';
after['border-' + slides.opposite(pos) + '-color'] = _.settings['theme'];
after[pos] = '0';
after[dir] = '50%';
after['margin-' + dir] = '-8px';
browser.createStyle(controls.cls.id(_, true) + ' .' + controls.cls.nav + '.' + n + ':after', after, true);
border = {};
border[horizontal ? 'height': 'width'] = '100%';
border[dir] = '0';
border['margin-' + dir] = '0';
browser.createStyle(controls.cls.maincss + '.border .' + controls.cls.nav + '.' + n, border, true);
borderpad = {};
borderpad[pos] = css(_.slidr, 'padding-' + pos) + 'px';
browser.createStyle(controls.cls.id(_, true) + '.border .' + controls.cls.nav + '.' + n, borderpad, true);
}
},
// On click callback.
onclick: function(_) {
return function handler(e) { actions.slide(_, getattr(browser.sanitize(e).target, controls.cls.data)); };
},
// Update controls.
update: function(_) {
for (var n in _.nav) classname(_.nav[n], actions.canSlide(_, n) ? 'rm' : 'add', 'disabled');
}
};
var breadcrumbs = {
// Classnames
cls: browser.classnames('breadcrumbs'),
// Initialize breadcrumbs container.
init: function(_) {
if (_.slidr && !_.breadcrumbs) {
_.breadcrumbs = css(classname(createEl('aside', { 'id': breadcrumbs.cls.id(_) }), 'add', 'disabled'), {
'opacity': '0',
'filter': 'alpha(opacity=0)',
'z-index': '0',
'pointer-events': 'none',
'visibility': 'hidden'
});
breadcrumbs.css(_);
_.slidr.appendChild(_.breadcrumbs);
bind(_.breadcrumbs, 'click', breadcrumbs.onclick(_));
}
},
// Breadcrumbs CSS rules.
css: function(_) {
browser.createStyle(breadcrumbs.cls.maincss, {
'position': 'absolute',
'bottom': css(_.slidr, 'padding-bottom') + 'px',
'right': css(_.slidr, 'padding-right') + 'px',
'padding': '10px',
'box-sizing': 'border-box',
'transform': 'translateZ(9999px)'
}, true);
browser.createStyle(breadcrumbs.cls.maincss + '.disabled', {
'transform': 'translateZ(0px) !important'
}, true);
browser.createStyle(breadcrumbs.cls.navcss, {
'padding': '0',
'font-size': '0',
'line-height': '0'
}, true);
browser.createStyle(breadcrumbs.cls.navcss + ' li', {
'width': '10px',
'height': '10px',
'display': 'inline-block',
'margin': '3px',
'tap-highlight-color': 'rgba(0, 0, 0, 0)',
'touch-callout': 'none',
'user-select': 'none'
}, true);
browser.createStyle(breadcrumbs.cls.id(_, true) + ' .' + breadcrumbs.cls.nav + ' li.normal', {
'border-radius': '100%',
'border': '1px ' + _.settings['theme'] +' solid',
'cursor': 'pointer',
'pointer-events': 'auto'
}, true);
browser.createStyle(breadcrumbs.cls.id(_, true) + ' .' + breadcrumbs.cls.nav + ' li.active', {
'width': '12px',
'height': '12px',
'margin': '2px',
'background-color': _.settings['theme']
}, true);
},
// On click callback.
onclick: function(_) {
return function handler(e) { actions.slide(_, getattr(browser.sanitize(e).target, breadcrumbs.cls.data)); };
},
// Breadcrumb offsets.
offsets: {
'right': { x: 1, y: 0 },
'up': { x: 0, y: 1 },
'left': { x: -1, y: 0 },
'down': { x: 0, y: -1 }
},
// Find breadcrumbs.
find: function(_, crumbs, bounds, el, x, y) {
if (el) {
if (!crumbs[el]) {
crumbs[el] = { x: x, y: y };
if (x < bounds.x.min) bounds.x.min = x;
if (x > bounds.x.max) bounds.x.max = x;
if (y < bounds.y.min) bounds.y.min = y;
if (y > bounds.y.max) bounds.y.max = y;
}
el = slides.get(_, el);
for (var o in breadcrumbs.offsets) {
if (el[o] && !crumbs[el[o]]) {
breadcrumbs.find(_, crumbs, bounds, el[o], x + breadcrumbs.offsets[o].x, y + breadcrumbs.offsets[o].y);
}
}
}
},
// Update breadcrumbs.
update: function(_, el, type) {
classname(_.crumbs[el].el, type === 'in' ? 'add' : 'rm', 'active');
},
// Create breadcrumbs.
create: function(_) {
breadcrumbs.init(_);
if (_.breadcrumbs) {
var crumbs = {};
var bounds = { x: { min: 0, max: 0 }, y: { min: 0, max: 0 } };
breadcrumbs.find(_, crumbs, bounds, _.start, 0, 0);
bounds.x.modifier = 0 - bounds.x.min;
bounds.y.modifier = 0 - bounds.y.min;
var crumbsMap = {};
for (var el in crumbs) {
crumbs[el].x += bounds.x.modifier;
crumbs[el].y += bounds.y.modifier;
crumbsMap[crumbs[el].x + ',' + crumbs[el].y] = el;
}
var rows = bounds.y.max - bounds.y.min + 1;
var columns = bounds.x.max - bounds.x.min + 1;
while (_.breadcrumbs.firstChild) _.breadcrumbs.removeChild(_.breadcrumbs.firstChild);
var ul = classname(createEl('ul'), 'add', breadcrumbs.cls.nav);
var li = createEl('li');
for (var r = rows - 1, ulclone; r >= 0; r--) {
ulclone = ul.cloneNode(false);
for (var c = 0, liclone, element; c < columns; c++) {
liclone = li.cloneNode(false);
element = crumbsMap[c + ',' + r];
if (element) {
classname(liclone, 'add', 'normal', element === _.current ? 'active' : null);
setattr(liclone, breadcrumbs.cls.data, element);
crumbs[element].el = liclone;
}
ulclone.appendChild(liclone);
};
_.breadcrumbs.appendChild(ulclone);
}
_.crumbs = crumbs;
}
}
};
var fx = {
// CSS rules to apply to a slide on initialize.
init: function(_, el, trans) {
var s = slides.get(_, el);
if (!s.initialized) {
var display = css(s.el, 'display');
var init = {
'display': (display === 'none') ? 'block' : display,
'visibility': 'hidden',
'position': 'absolute',
'opacity': '0',
'filter': 'alpha(opacity=0)',
'z-index': '0',
'pointer-events': 'none',
'backface-visibility': 'hidden',
'transform-style': 'preserve-3d'
}
if (browser.isIE()) init = extend(init, {'display': 'none', 'visibility': 'visible'});
s.initialized = true;
css(s.el, init);
}
},
// Properties defining animation support.
supported: {
'none': true,
'fade': browser.supports('animation', 'opacity'),
'linear': browser.supports('animation', 'opacity', 'transform'),
'cube': browser.supports('animation', 'backface-visibility', 'opacity', 'transform', 'transform-style')
},
// Defines our slide animations.
animation: {
'fade': (function() {
browser.add['fade']('slidr-fade-in', '0', '1');
browser.add['fade']('slidr-fade-out', '1', '0');
})(),
'linear': {
'in': {
'left': function(name, w, o) { browser.add['linear'](name, 'in', 'X(-' + w, 'X(0', o, '1'); },
'right': function(name, w, o) { browser.add['linear'](name, 'in', 'X(' + w, 'X(0', o, '1'); },
'up': function(name, h, o) { browser.add['linear'](name, 'in', 'Y(-' + h, 'Y(0', o, '1'); },
'down': function(name, h, o) { browser.add['linear'](name, 'in', 'Y(' + h, 'Y(0', o, '1'); }
},
'out': {
'left': function(name, w, o) { browser.add['linear'](name, 'out', 'X(0', 'X(' + w, '1', o); },
'right': function(name, w, o) { browser.add['linear'](name, 'out', 'X(0', 'X(-' + w, '1', o); },
'up': function(name, h, o) { browser.add['linear'](name, 'out', 'Y(0', 'Y(' + h, '1', o); },
'down': function(name, h, o) { browser.add['linear'](name, 'out', 'Y(0', 'Y(-' + h, '1', o); }
}
},
'cube': {
'in': {
'left': function(name, w, o) { browser.add['cube'](name, 'Y(-9', 'Y(', w/2, o, '1'); },
'right': function(name, w, o) { browser.add['cube'](name, 'Y(9', 'Y(', w/2, o, '1'); },
'up': function(name, h, o) { browser.add['cube'](name, 'X(9', 'X(', h/2, o, '1'); },
'down': function(name, h, o) { browser.add['cube'](name, 'X(-9', 'X(', h/2, o, '1'); }
},
'out': {
'left': function(name, w, o) { browser.add['cube'](name, 'Y(', 'Y(9', w/2, '1', o); },
'right': function(name, w, o) { browser.add['cube'](name, 'Y(', 'Y(-9', w/2, '1', o); },
'up': function(name, h, o) { browser.add['cube'](name, 'X(', 'X(-9', h/2, '1', o); },
'down': function(name, h, o) { browser.add['cube'](name, 'X(', 'X(9', h/2, '1', o); }
}
}
},
// Resolve keyframe animation name.
name: function(_, target, trans, type, dir) {
var parts = ['slidr', trans, type];
if ((trans === 'linear' || trans === 'cube') && dir) {
parts.push(dir);
var opacity = (!!_.settings['fade']) ? '0' : '1';
if (opacity === '0') parts.push('fade');
var prop = (dir === 'up' || dir === 'down') ? 'h' : 'w';
var s = (prop === 'h') ? size.getHeight(target) : size.getWidth(target);
parts.push(prop, s);
var keyframe = lookup(fx.animation, [trans, type, dir]);
if (keyframe) keyframe(parts.join('-'), s, opacity);
}
return parts.join('-');
},
// Animate an `el` with `trans` effects coming [in|out] as `type` from direction `dir`.
animate: function(_, el, trans, type, dir, opt_target, opt_z, opt_pointer) {
var anim = {
'opacity': (type === 'in') ? '1': '0',
'filter': 'alpha(opacity=' + (type === 'in' ? '100': '0') + ')',
'z-index': opt_z || (type === 'in' ? '1': '0'),
'visibility': (type === 'in') ? 'visible': 'hidden',
'pointer-events': opt_pointer || (type === 'in' ? 'auto': 'none')
};
if (browser.isIE()) anim = extend(anim, {'display': (type === 'in') ? 'block' : 'none', 'visibility': 'visible'});
var target = opt_target || slides.get(_, el).el;
var timing = _.settings['timing'][trans];
if (fx.supported[trans] && timing) {
var name = fx.name(_, target, trans, type, dir);
anim['animation'] = (trans === 'none') ? 'none' : [name, timing].join(' ');
}
css(target, anim);
if (slides.get(_, el) && browser.supports('transform')) fx.fixTranslateZ(_, target, type);
},
// Toggle translateZ on breadcrumbs/controls so it doesn't interfere with page flow.
fixTranslateZ: function(_, el, opt_type) {
var asides = el.getElementsByTagName('aside');
if (asides.length) {
for (var i = 0, aside, p, toggle, visibility; aside = asides[i]; i++) {
if (!!aside.getAttribute('id')) {
// Get the first parent data-slidr node, or use the current Slidr element.
p = aside.parentNode;
while (!getattr(p, 'data-slidr') && tagName(p) !== 'body') p = p.parentNode;
if (tagName(p) === 'body') p = _.slidr;
visibility = css(p, 'visibility');
toggle = (opt_type === 'out' || !opt_type && visibility === 'hidden') ? 'add' :
(visibility === 'visible') ? 'rm' : null;
if (toggle) classname(aside, toggle, 'disabled');
}
}
}
}
};
var size = {
// Active Slidr's to listen for resize.
active: {},
// Add Slidr's we want to monitor.
autoResize: function(_) {
size.active[_.id] = { src: _, w: 0, h: 0, d: size.dynamic(_) };
},
// Check whether width and height should by dynamically updated.
dynamic: function(_) {
var clone = css(_.slidr.cloneNode(false), { 'position': 'absolute', 'opacity': '0', 'filter': 'alpha(opacity=0)' });
var probe = css(createEl('div'), { 'width': '42px', 'height': '42px' });
clone.appendChild(probe);
_.slidr.parentNode.insertBefore(clone, _.slidr);
var originalWidth = (borderbox(clone) ? size.extraWidth(_.slidr) : 0) + 42;
var originalHeight = (borderbox(clone) ? size.extraHeight(_.slidr) : 0) + 42;
var cloneWidth = css(clone, 'width');
var cloneHeight = css(clone, 'height');
var minWidth = css(clone, 'min-width');
var minHeight = css(clone, 'min-height');
var dynamic = {
width: cloneWidth === 'auto' || cloneWidth === originalWidth || minWidth !== 0 && minWidth != 'auto',
height: cloneHeight === 'auto' || cloneHeight === originalHeight || minHeight !== 0 && minHeight != 'auto'
};
_.slidr.parentNode.removeChild(clone);
return dynamic;
},
// Returns the sum of all integer arguments passed in, or 0. Best effort.
sum: function() {
for (var i = 0, s = 0, arg; arg = arguments[i]; i++) s += arg;
return isNaN(s) ? 0 : s;
},
// Grabs the element width/height margin.
widthMargin: function(el) {
return size.sum(Math.max(0, css(el, 'margin-left')), Math.max(0, css(el, 'margin-right')));
},
heightMargin: function(el) {
return size.sum(Math.max(0, css(el, 'margin-top')), Math.max(0, css(el, 'margin-bottom')));
},
// Grabs the element width/height padding.
widthPad: function(el) { return size.sum(css(el, 'padding-left'), css(el, 'padding-right')); },
heightPad: function(el) { return size.sum(css(el, 'padding-top'), css(el, 'padding-bottom')); },
// Grabs the element width/height border.
widthBorder: function(el) { return size.sum(css(el, 'border-left-width'), css(el, 'border-right-width')); },
heightBorder: function(el) { return size.sum(css(el, 'border-top-width'), css(el, 'border-bottom-width')); },
// Grabs extra border-box padding.
extraWidth: function(el) { return size.sum(size.widthPad(el), size.widthBorder(el)); },
extraHeight: function(el) { return size.sum(size.heightPad(el), size.heightBorder(el)); },
// Gets the element width/height.
getWidth: function(el) {
var w = css(el, 'width');
if (browser.isIE() && w === 'auto' && el.clientWidth) w = el.clientWidth;
if (w !== 'auto') w += (size.widthMargin(el) + (borderbox(el) ? 0 : size.extraWidth(el)));
return w;
},
getHeight: function(el) {
var h = css(el, 'height');
if (browser.isIE() && h === 'auto' && el.clientHeight) h = el.clientHeight;
if (h !== 'auto') h += (size.heightMargin(el) + (borderbox(el) ? 0 : size.extraHeight(el)));
return h;
},
// Sets the width/height of our element.
setWidth: function(el, w) {
var prop = w;
if (w !== 'auto' && w !== '') prop = (w + (borderbox(el) ? size.extraWidth(el) : 0)) + 'px';
css(el, { width: prop });
return w;
},
setHeight: function(el, h) {
var prop = h;
if (h !== 'auto' && h !== '') prop = (h + (borderbox(el) ? size.extraHeight(el) : 0)) + 'px';
css(el, { height: prop });
return h;
}
};
var nav = {
// Mouse events.
mouse: {
// Slidr's with mouseover.
over: [],
// Whether a slidr-id already has mouseover.
isOver: function(id) { return indexOf(nav.mouse.over, id) >= 0; },
// Add a slidr-id with mouseover event.
add: function(id) { if (!nav.mouse.isOver(id)) nav.mouse.over.push(id); },
// Remove a slidr-id from mouseover event.
remove: function(id) { if (nav.mouse.isOver(id)) nav.mouse.over.splice(indexOf(nav.mouse.over, id), 1); },
// Get the current top level Slidr being mouse'd over.
current: function() {
var c = nav.mouse.over[nav.mouse.over.length-1];
for (var i = 0, l = nav.mouse.over.length, m = nav.mouse.over[i]; i < l; i++) if (contains(c, m)) c = m;
return c;
},
// Track mouseenter/mouseleave events.
track: function(el) {
bind(el, 'mouseenter', function(e) { nav.mouse.add(browser.sanitize(e).currentTarget.id); });
bind(el, 'mouseleave', function(e) { nav.mouse.remove(browser.sanitize(e).currentTarget.id); });
}
},
// Keyboard events.
keyboard: (function() {
bind(document, 'keydown', function(e) {
e = browser.sanitize(e);
if (nav.mouse.current() && e.which <= 40 && e.which >= 37) {
var c = INSTANCES[nav.mouse.current()];
var dir = null;
if (e.which === 40 && c['canSlide']('down')) { dir = 'down'; }
else if (e.which === 39 && c['canSlide']('right')) { dir = 'right'; }
else if (e.which === 38 && c['canSlide']('up')) { dir = 'up'; }
else if (e.which === 37 && c['canSlide']('left')) { dir = 'left'; }
if (dir) c['slide'](dir) && browser.stop(e);
}
});
})(),
// Touch events.
touch: function(_) {
var start = {};
var delta = {};
bind(_.slidr, 'touchstart', function(e) {
e = browser.sanitize(e);
start = { x: e.touches[0].pageX, y: e.touches[0].pageY, time: +new Date };
delta = { x: 0, y: 0, duration: 0 };
});
bind(_.slidr, 'touchmove', function(e) {
e = browser.sanitize(e);
if (e.touches.length > 1 || e.scale && e.scale !== 1) return;
delta.x = e.touches[0].pageX - start.x;
delta.y = e.touches[0].pageY - start.y;
delta.duration = +new Date - start.time;
if (delta.duration > 100 && (Math.abs(delta.x) + Math.abs(delta.y))/delta.duration < 0.25) return;
browser.stop(e);
});
bind(_.slidr, 'touchend', function(e) {
e = browser.sanitize(e);
if (Number(+new Date - start.time) < 250) {
var dx = Math.abs(delta.x);
var dy = Math.abs(delta.y);
var validH = dx > 20;
var validV = dy > 20;
var dirH = delta.x < 0 ? 'right': 'left';
var dirV = delta.y < 0 ? 'down' : 'up';
var dir = (validH && validV ? (dx > dy ? dirH : dirV) : (validH ? dirH : (validV ? dirV : null)));
if (dir) actions.slide(_, dir);
browser.stop(e);
}
});
}
};
var actions = {
// Starts a Slidr.
start: function(_, opt_start) {
if (!_.started && _.slidr) {
var display = css(_.slidr, 'display');
var position = css(_.slidr, 'position');
var opacity = css(_.slidr, 'opacity');
css(_.slidr, {
'visibility': 'visible',
'opacity': opacity,
'filter': 'alpha(opacity=' + opacity * 100 + ')',
'display': (display === 'inline-block' || display === 'inline') ? 'inline-block' : 'block',
'position': (position === 'static') ? 'relative' : position,
'overflow': (!!_.settings['overflow']) ? css(_.slidr, 'overflow') : 'hidden',
'transition': 'height 0.05s ease-out, width 0.05s ease-out',
'tap-highlight-color': 'rgba(0, 0, 0, 0)',
'touch-callout': 'none'
});
if (!_.start) actions.add(_, _.settings['direction'], slides.find(_, true), _.settings['transition']);
if (slides.get(_, opt_start)) _.start = opt_start;
slides.display(_);
size.autoResize(_);
fx.fixTranslateZ(_, _.slidr);
if (_.settings['keyboard']) nav.mouse.track(_.slidr);
if (_.settings['touch']) nav.touch(_);
_.started = true;
controls.update(_);
}
},
// Can we slide?
canSlide: function(_, next) {
return _.started && next && (slides.isdir(next) ? !!slides.get(_, _.current, next) : !!slides.get(_, next));
},
// Slide.
slide: function(_, next) {
if (actions.canSlide(_, next)) slides.slide(_, next);
},
// Adds a set of slides.
add: function(_, direction, ids, opt_transition, opt_overwrite) {
if (_.slidr) {
var trans = transition.validate(_, opt_transition);
var valid = slides.find(_);
var prev = (direction === 'horizontal' || direction === 'h') ? 'left' : 'up';
var next = (direction === 'horizontal' || direction === 'h') ? 'right' : 'down';
if (!slides.validate(_, ids, trans, valid, prev, next) && !opt_overwrite) {
console.warn('[Slidr] Error adding [' + direction + '] slides for [' + _.id + '].');
} else {
slides.add(_, ids, trans, valid, prev, next);
}
}
},
// Automatically transition between slides.
auto: function(_, msec, direction) {
if (_.started && slides.isdir(direction)) {
actions.stop(_);
_.auto.msec = msec;
_.auto.direction = direction;
_.auto.id = setInterval(function() {
if (!(_.settings['pause'] && nav.mouse.isOver(_.id))) slides.slide(_, direction);
}, msec);
}
},
// Stops auto transitioning.
stop: function(_) {
if (_.started && _.auto.id) {
clearInterval(_.auto.id);
_.auto.id = null;
}
},
// Toggle breadcrumbs.
breadcrumbs: function(_) {
if (_.breadcrumbs && _.displayed) {
var type = css(_.breadcrumbs, 'opacity') === '0' ? 'in' : 'out';
fx.animate(_, null, 'fade', type, null, _.breadcrumbs, '3', 'none');
if (_.controls) classname(_.controls, type === 'in' ? 'add' : 'rm', 'breadcrumbs');
}
},
// Toggle controls.
controls: function(_, opt_scheme) {
if (_.controls && _.displayed) {
if (!controls.valid(opt_scheme)) opt_scheme = null;
var hidden = css(_.controls, 'visibility') === 'hidden';
var type = (opt_scheme && opt_scheme !== 'none') ? 'in' : 'out';
if (type === 'out' && hidden) return;
if (opt_scheme === 'border') classname(_.controls, 'add', 'border');
else if (opt_scheme === 'corner') classname(_.controls, 'rm', 'border');
fx.animate(_, null, 'fade', type, null, _.controls, '2', 'none');
}
}
};
// The Slidr constructor.
var Slidr = function(id, el, settings) {
var _ = {
// Slidr id.
id: id,
// Reference to the Slidr element.
slidr: el,
// Reference to the Slidr breadcrumbs element.
breadcrumbs: null,
// Reference to the Slidr controller element.
controls: null,
// Settings for this Slidr.
settings: settings,
// Whether we've successfully called start().
started: false,
// Whether we've successfully called slides.display().
displayed: false,
// The slide to start at.
start: null,
// The current slide.
current: null,
// The auto() metadata.
auto: { id: null, msec: 5000, direction: 'right' },
// A {mapping} of slides to their neighbors.
slides: {},
// A {mapping} of slides and their transition effects.
trans: {},
// A {mapping} of slides and their (x, y) position.
crumbs: {},
// Reference to the Slidr controller navigators.
nav: { 'up': null, 'down': null, 'left': null, 'right': null }
};
var api = {
/**
* Start the Slidr!
* Automatically finds slides to create if nothing was added prior to calling start().
* @param {string} opt_start `data-slidr` id to start on.
* @return {this}
*/
'start': function(opt_start) {
actions.start(_, opt_start);
return this;
},
/**
* Check whether we can slide.
* @param {string} next a direction ('up', 'down', 'left', 'right') or a `data-slidr` id.
* @return {boolean}
*/
'canSlide': function(next) {
return actions.canSlide(_, next);
},
/**
* Slide!
* @param {string} next a direction ('up', 'down', 'left', 'right') or a `data-slidr` id.
* @return {this}
*/
'slide': function(next) {
actions.slide(_, next);
return this;
},
/**
* Adds a set of slides.
* @param {string} direction `horizontal || h` or `vertical || v`.
* @param {Array} ids A list of `data-slidr` id's to add to Slidr. Slides must be direct children of the Slidr.
* @param {string=} opt_transition The transition to apply between the slides, or uses the default.
* @param {boolean=} opt_overwrite Whether to overwrite existing slide mappings/transitions if conflicts occur.
* @return {this}
*/
'add': function(direction, ids, opt_transition, opt_overwrite) {
actions.add(_, direction, ids, opt_transition, opt_overwrite);
return this;
},
/**
* Automatically advance to the next slide after a certain timeout. Calls start() if not already called.
* Reuses any previous parameters (msec and direction) if auto() is called to resume after stop().
* @param {int=} opt_msec The number of millis between each slide transition. Default is 5000 (5 seconds).
* @param {string=} opt_direction 'up', 'down', 'left', or 'right'. Default is 'right'.
* @param {string=} opt_start The `data-slidr` id to start at (only works if auto is called to start the Slidr).
* @return {this}
*/
'auto': function(opt_msec, opt_direction, opt_start) {
actions.start(_, opt_start);
actions.auto(_, opt_msec || _.auto.msec, opt_direction || _.auto.direction);
return this;
},
/**
* Stop auto transition if it's turned on.
* @return {this}
*/
'stop': function() {
actions.stop(_);
return this;
},
/**
* Set custom animation timings.
* @param {string|Object} transition Either a transition name (i.e. 'cube'), or a {'transition': 'timing'} object.
* @param {string=} opt_timing The new animation timing (i.e "0.5s ease-in"). Not required if transition is an object.
* @return {this}
*/
'timing': function(transition, opt_timing) {
if (!!transition && transition.constructor === Object) {
_.settings['timing'] = extend(_.settings['timing'], transition);
} else if (typeof(transition) === 'string' && typeof(opt_timing) === 'string') {
_.settings['timing'][transition] = opt_timing;
}
return this;
},
/**
* Toggle breadcrumbs.
* @return {this}
*/
'breadcrumbs': function() {
actions.breadcrumbs(_);
return this;
},
/**
* Toggle controls.
* @param {string=} opt_scheme Toggle on/off if not present, else change scheme. `border`, `corner` or `none`.
* @return {this}
*/
'controls': function(opt_scheme) {
actions.controls(_, opt_scheme);
return this;
}
};
return api;
};
// Global timer for dynamic sizing.
var TIMER = setInterval((function watch() {
var _, cur, index, el, width, height;
for (index in size.active) {
cur = size.active[index];
_ = cur.src;
if (!browser.isIE() && !contains(document, _.slidr)) {
delete size.active[index];
delete INSTANCES[_.id];
} else if (css(_.slidr, 'visibility') === 'hidden') {
size.active[index].w = size.setWidth(_.slidr, 0);
size.active[index].h = size.setHeight(_.slidr, 0);
} else if (slides.get(_, _.current)) {
el = slides.get(_, _.current).el;
width = size.getWidth(el);
height = size.getHeight(el);
if (cur.d.width && cur.w != width) size.active[index].w = size.setWidth(_.slidr, width);
if (cur.d.height && cur.h != height) size.active[index].h = size.setHeight(_.slidr, height);
}
}
return watch;
})(), 250);
// Current version.
var VERSION = '0.5.0';
// Active Slidr instances.
var INSTANCES = {};
// Callback no-op.
var NOOP = function() {};
// Slidr default settings.
var DEFAULTS = {
'after': NOOP, // Callback function after a slide transition finishes.
'before': NOOP, // Callback function before a slide transition begins.
'breadcrumbs': false, // Show or hide breadcrumbs on start(). `true` or `false`.
'controls': 'border', // Show or hide control arrows on start(). `border`, `corner` or `none`.
'direction': 'horizontal', // The default direction for new slides. `horizontal` or `h`, `vertical` or `v`.
'fade': true, // Whether slide transitions should fade in/out. `true` or `false`.
'keyboard': false, // Whether to enable keyboard navigation upon mouseover. `true` or `false`.
'overflow': false, // Whether to overflow transitions at slidr borders. `true` or `false`.
'pause': false, // Whether to pause on mouseover when running in auto(). `true` or `false`.
'theme': '#fff', // Sets color theme for breadcrumbs/controls. #hexcode or rgba(value).
'timing': {}, // Custom animation timings to apply. {'transition': 'timing'}.
'touch': false, // Whether to enable touch navigation for mobile devices. `true` or `false`.
'transition': 'linear' // The default transition to apply. `cube`, `linear`, `fade`, or `none`.
};
// Slidr default animation timings.
var TIMING = {
'none': 'none',
'fade': '0.4s ease-out',
'linear': '0.6s ease-out',
'cube': '1s cubic-bezier(0.15, 0.9, 0.25, 1)'
};
// Global API.
return {
/**
* Current version.
* @return {string} major.minor.patch.
*/
'version': function() {
return VERSION;
},
/**
* Available transitions.
* @return {Array} of transitions.
*/
'transitions': function() {
return transition.available.slice(0);
},
/**
* Creates and returns a Slidr.
* Calling create on the same element twice returns the already instantiated Slidr.
* @param {string} id The element id to turn into a Slidr.
* @param {Object=} opt_settings Settings to apply.
*/
'create': function(id, opt_settings) {
var el = document.getElementById(id);
if (!el) {
console.warn('[Slidr] Could not find element with id [' + id + '].');
return;
}
var settings = extend(DEFAULTS, opt_settings || {});
settings['timing'] = extend(TIMING, settings['timing']);
INSTANCES[id] = INSTANCES[id] || new Slidr(id, el, settings);
return INSTANCES[id];
}
};
}));