|
|
Line 1: |
Line 1: |
- | /*!
| |
- | * jquery.scrollto.js 0.0.1 - https://github.com/yckart/jquery.scrollto.js
| |
- | * Scroll smooth to any element in your DOM.
| |
- | *
| |
- | * Copyright (c) 2012 Yannick Albert (http://yckart.com)
| |
- | * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).
| |
- | * 2013/02/17
| |
- | **/
| |
- | $.scrollTo = $.fn.scrollTo = function(x, y, options){
| |
- | if (!(this instanceof $)) return $.fn.scrollTo.apply($('html, body'), arguments);
| |
| | | |
- | options = $.extend({}, {
| |
- | gap: {
| |
- | x: 0,
| |
- | y: 0
| |
- | },
| |
- | animation: {
| |
- | easing: 'swing',
| |
- | duration: 600,
| |
- | complete: $.noop,
| |
- | step: $.noop
| |
- | }
| |
- | }, options);
| |
- |
| |
- | return this.each(function(){
| |
- | var elem = $(this);
| |
- | elem.stop().animate({
| |
- | scrollLeft: !isNaN(Number(x)) ? x : $(y).offset().left + options.gap.x,
| |
- | scrollTop: !isNaN(Number(y)) ? y : $(y).offset().top + options.gap.y
| |
- | }, options.animation);
| |
- | });
| |
- | };
| |
- |
| |
- | /**
| |
- | * onHashChange (oHch) event handler
| |
- | * @version onHashChange 1.0
| |
- | * @copyright Copyright (c) 2010-2012, Gabriele Girelli
| |
- | * @author ggirelli <g.girelli@studenti.unitn.it>
| |
- | */
| |
- | function oHch(event) {
| |
- | var getHashValue = function() {
| |
- | var hasValue = window.location.hash.split("#")[1];
| |
- | if (typeof hasValue == "undefined") {
| |
- | return false;
| |
- | }
| |
- | return hasValue;
| |
- | }
| |
- | var lastHash = getHashValue();
| |
- | (function listenHash() {
| |
- | var hash = getHashValue();
| |
- |
| |
- | if (hash !== lastHash) {
| |
- | event();
| |
- | lastHash = hash;
| |
- | }
| |
- |
| |
- | var t = setTimeout(listenHash, 100);
| |
- |
| |
- | })();
| |
- | }
| |
- |
| |
- | /**
| |
- | * onTimeChange (oTch) event handler
| |
- | * @version onTimeChange 1.0
| |
- | * @copyright Copyright (c) 2010-2012, Gabriele Girelli
| |
- | * @author ggirelli <g.girelli@studenti.unitn.it>
| |
- | */
| |
- | function oTch(event) {
| |
- | var getTimeValue = function() {
| |
- | var d = new Date();
| |
- | return d.getTime();
| |
- | }
| |
- | var lastTime = getTimeValue();
| |
- | (function listenTime() {
| |
- | var time = getTimeValue();
| |
- | if (time !== lastTime) {
| |
- | event();
| |
- | lastTime = time;
| |
- | }
| |
- |
| |
- | var t = setTimeout(listenTime, 100);
| |
- |
| |
- | })();
| |
- | }
| |
- |
| |
- | /**
| |
- | * onWidthChange (oWri) event handler
| |
- | * @version onWidthChange 1.0
| |
- | * @copyright Copyright (c) 2010-2012, Gabriele Girelli
| |
- | * @author ggirelli <g.girelli@studenti.unitn.it>
| |
- | */
| |
- | function oWch(event) {
| |
- | var getWidthValue = function() {
| |
- | return window.innerWidth;
| |
- | }
| |
- | var lastWidth = getWidthValue();
| |
- | (function listenWidth() {
| |
- | var width = getWidthValue();
| |
- | if (width !== lastWidth) {
| |
- | event();
| |
- | lastWidth = width;
| |
- | }
| |
- |
| |
- | var w = setTimeout(listenWidth, 100);
| |
- |
| |
- | })();
| |
- | }
| |
- |
| |
- |
| |
- | /*!
| |
- | * jmpress.js v0.4.0
| |
- | * http://shama.github.com/jmpress.js
| |
- | *
| |
- | * A jQuery plugin to build a website on the infinite canvas.
| |
- | *
| |
- | * Copyright 2012 Kyle Robinson Young @shama & Tobias Koppers @sokra
| |
- | * Licensed MIT
| |
- | * http://www.opensource.org/licenses/mit-license.php
| |
- | *
| |
- | * Based on the foundation laid by Bartek Szopka @bartaz
| |
- | */
| |
- |
| |
- | /*!
| |
- | * core.js
| |
- | * The core of jmpress.js
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | /**
| |
- | * Set supported prefixes
| |
- | *
| |
- | * @access protected
| |
- | * @return Function to get prefixed property
| |
- | */
| |
- | var pfx = (function () {
| |
- | var style = document.createElement('dummy').style,
| |
- | prefixes = 'Webkit Moz O ms Khtml'.split(' '),
| |
- | memory = {};
| |
- | return function ( prop ) {
| |
- | if ( typeof memory[ prop ] === "undefined" ) {
| |
- | var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
| |
- | props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
| |
- | memory[ prop ] = null;
| |
- | for ( var i in props ) {
| |
- | if ( style[ props[i] ] !== undefined ) {
| |
- | memory[ prop ] = props[i];
| |
- | break;
| |
- | }
| |
- | }
| |
- | }
| |
- | return memory[ prop ];
| |
- | };
| |
- | }());
| |
- |
| |
- | /**
| |
- | * map ex. "WebkitTransform" to "-webkit-transform"
| |
- | */
| |
- | function mapProperty( name ) {
| |
- | if(!name) {
| |
- | return;
| |
- | }
| |
- | var index = 1 + name.substr(1).search(/[A-Z]/);
| |
- | var prefix = name.substr(0, index).toLowerCase();
| |
- | var postfix = name.substr(index).toLowerCase();
| |
- | return "-" + prefix + "-" + postfix;
| |
- | }
| |
- | function addComma( attribute ) {
| |
- | if(!attribute) {
| |
- | return "";
| |
- | }
| |
- | return attribute + ",";
| |
- | }
| |
- |
| |
- | /**
| |
- | * Default Settings
| |
- | */
| |
- | var defaults = {
| |
- | /* CLASSES */
| |
- | stepSelector: '.step'
| |
- | ,containerClass: ''
| |
- | ,canvasClass: ''
| |
- | ,areaClass: ''
| |
- | ,notSupportedClass: 'not-supported'
| |
- | ,loadedClass: 'loaded'
| |
- |
| |
- | /* CONFIG */
| |
- | ,fullscreen: true
| |
- |
| |
- | /* ANIMATION */
| |
- | ,animation: {
| |
- | transformOrigin: 'top left'
| |
- | ,transitionProperty: addComma(mapProperty(pfx('transform'))) + addComma(mapProperty(pfx('perspective'))) + 'opacity'
| |
- | ,transitionDuration: '1s'
| |
- | ,transitionDelay: '500ms'
| |
- | ,transitionTimingFunction: 'ease-in-out'
| |
- | ,transformStyle: "preserve-3d"
| |
- | }
| |
- | ,transitionDuration: 1500
| |
- |
| |
- | /* TEST */
| |
- | ,test: false
| |
- | };
| |
- | var callbacks = {
| |
- | 'beforeChange': 1
| |
- | ,'beforeInitStep': 1
| |
- | ,'initStep': 1
| |
- | ,'beforeInit': 1
| |
- | ,'afterInit': 1
| |
- | ,'beforeDeinit': 1
| |
- | ,'afterDeinit': 1
| |
- | ,'applyStep': 1
| |
- | ,'unapplyStep': 1
| |
- | ,'setInactive': 1
| |
- | ,'beforeActive': 1
| |
- | ,'setActive': 1
| |
- | ,'selectInitialStep': 1
| |
- | ,'selectPrev': 1
| |
- | ,'selectNext': 1
| |
- | ,'selectHome': 1
| |
- | ,'selectEnd': 1
| |
- | ,'loadStep': 1
| |
- | ,'applyTarget': 1
| |
- | };
| |
- | for(var callbackName in callbacks) {
| |
- | defaults[callbackName] = [];
| |
- | }
| |
- |
| |
- |
| |
- | /**
| |
- | * Initialize jmpress
| |
- | */
| |
- | function init( args ) {
| |
- | args = $.extend(true, {}, args || {});
| |
- |
| |
- | // accept functions and arrays of functions as callbacks
| |
- | var callbackArgs = {};
| |
- | var callbackName = null;
| |
- | for (callbackName in callbacks) {
| |
- | callbackArgs[callbackName] = $.isFunction( args[callbackName] ) ?
| |
- | [ args[callbackName] ] :
| |
- | args[callbackName];
| |
- | args[callbackName] = [];
| |
- | }
| |
- |
| |
- | // MERGE SETTINGS
| |
- | var settings = $.extend(true, {}, defaults, args);
| |
- |
| |
- | for (callbackName in callbacks) {
| |
- | if (callbackArgs[callbackName]) {
| |
- | Array.prototype.push.apply(settings[callbackName], callbackArgs[callbackName]);
| |
- | }
| |
- | }
| |
- |
| |
- | /*** MEMBER VARS ***/
| |
- |
| |
- | var jmpress = $( this )
| |
- | ,container = null
| |
- | ,area = null
| |
- | ,oldStyle = {
| |
- | container: ""
| |
- | ,area: ""
| |
- | }
| |
- | ,canvas = null
| |
- | ,current = null
| |
- | ,active = false
| |
- | ,activeSubstep = null
| |
- | ,activeDelegated = false;
| |
- |
| |
- |
| |
- | /*** MEMBER FUNCTIONS ***/
| |
- | // functions have to be called with this
| |
- |
| |
- | /**
| |
- | * Init a single step
| |
- | *
| |
- | * @param element the element of the step
| |
- | * @param idx number of step
| |
- | */
| |
- | function doStepInit( element, idx ) {
| |
- | var data = dataset( element );
| |
- | var step = {
| |
- | oldStyle: $(element).attr("style") || ""
| |
- | };
| |
- |
| |
- | var callbackData = {
| |
- | data: data
| |
- | ,stepData: step
| |
- | };
| |
- | callCallback.call(this, 'beforeInitStep', $(element), callbackData);
| |
- | step.delegate = data.delegate;
| |
- | callCallback.call(this, 'initStep', $(element), callbackData);
| |
- |
| |
- | $(element).data('stepData', step);
| |
- |
| |
- | if ( !$(element).attr('id') ) {
| |
- | $(element).attr('id', 'step-' + (idx + 1));
| |
- | }
| |
- |
| |
- | callCallback.call(this, 'applyStep', $(element), callbackData);
| |
- | }
| |
- | /**
| |
- | * Deinit a single step
| |
- | *
| |
- | * @param element the element of the step
| |
- | */
| |
- | function doStepDeinit( element ) {
| |
- | var stepData = $(element).data('stepData');
| |
- |
| |
- | $(element).attr("style", stepData.oldStyle);
| |
- |
| |
- | callCallback.call(this, 'unapplyStep', $(element), {
| |
- | stepData: stepData
| |
- | });
| |
- | }
| |
- | /**
| |
- | * Reapplies stepData to the element
| |
- | *
| |
- | * @param element
| |
- | */
| |
- | function doStepReapply( element ) {
| |
- | callCallback.call(this, 'unapplyStep', $(element), {
| |
- | stepData: element.data("stepData")
| |
- | });
| |
- |
| |
- | callCallback.call(this, 'applyStep', $(element), {
| |
- | stepData: element.data("stepData")
| |
- | });
| |
- | }
| |
- | /**
| |
- | * Completly deinit jmpress
| |
- | *
| |
- | */
| |
- | function deinit() {
| |
- | if ( active ) {
| |
- | callCallback.call(this, 'setInactive', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | ,reason: "deinit"
| |
- | } );
| |
- | }
| |
- | if (current.jmpressClass) {
| |
- | $(jmpress).removeClass(current.jmpressClass);
| |
- | }
| |
- |
| |
- | callCallback.call(this, 'beforeDeinit', $(this), {});
| |
- |
| |
- | $(settings.stepSelector, jmpress).each(function( idx ) {
| |
- | doStepDeinit.call(jmpress, this );
| |
- | });
| |
- |
| |
- | container.attr("style", oldStyle.container);
| |
- | if(settings.fullscreen) {
| |
- | $("html").attr("style", "");
| |
- | }
| |
- | area.attr("style", oldStyle.area);
| |
- | $(canvas).children().each(function() {
| |
- | jmpress.append( $( this ) );
| |
- | });
| |
- | if( settings.fullscreen ) {
| |
- | canvas.remove();
| |
- | } else {
| |
- | canvas.remove();
| |
- | area.remove();
| |
- | }
| |
- |
| |
- | callCallback.call(this, 'afterDeinit', $(this), {});
| |
- |
| |
- | $(jmpress).data("jmpressmethods", false);
| |
- | }
| |
- | /**
| |
- | * Call a callback
| |
- | *
| |
- | * @param callbackName String callback which should be called
| |
- | * @param element some arguments to the callback
| |
- | * @param eventData
| |
- | */
| |
- | function callCallback( callbackName, element, eventData ) {
| |
- | eventData.settings = settings;
| |
- | eventData.current = current;
| |
- | eventData.container = container;
| |
- | eventData.parents = element ? getStepParents(element) : null;
| |
- | eventData.current = current;
| |
- | eventData.jmpress = this;
| |
- | var result = {};
| |
- | $.each( settings[callbackName], function(idx, callback) {
| |
- | result.value = callback.call( jmpress, element, eventData ) || result.value;
| |
- | });
| |
- | return result.value;
| |
- | }
| |
- | /**
| |
- | * Load Siblings
| |
- | *
| |
- | * @access protected
| |
- | * @return void
| |
- | */
| |
- | function loadSiblings() {
| |
- | if (!active) {
| |
- | return;
| |
- | }
| |
- | var siblings = $(active).near( settings.stepSelector )
| |
- | .add( $(active).near( settings.stepSelector, true) )
| |
- | .add( callCallback.call(this, 'selectPrev', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | }))
| |
- | .add( callCallback.call(this, 'selectNext', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | }));
| |
- | siblings.each(function() {
| |
- | var step = this;
| |
- | if ($(step).hasClass( settings.loadedClass )) {
| |
- | return;
| |
- | }
| |
- | setTimeout(function() {
| |
- | if ($(step).hasClass( settings.loadedClass )) {
| |
- | return;
| |
- | }
| |
- | callCallback.call(jmpress, 'loadStep', step, {
| |
- | stepData: $(step).data('stepData')
| |
- | });
| |
- | $(step).addClass( settings.loadedClass );
| |
- | }, settings.transitionDuration - 100);
| |
- | });
| |
- | if ($(active).hasClass( settings.loadedClass )) {
| |
- | return;
| |
- | }
| |
- | callCallback.call(jmpress, 'loadStep', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | });
| |
- | $(active).addClass( settings.loadedClass );
| |
- | }
| |
- | /**
| |
- | *
| |
- | */
| |
- | function getStepParents( el ) {
| |
- | var parents = [];
| |
- | var currentEl = el;
| |
- | while($(currentEl).parent().length &&
| |
- | $(currentEl).parent().is(settings.stepSelector)) {
| |
- | currentEl = $(currentEl).parent();
| |
- | parents.push(currentEl[0]);
| |
- | }
| |
- | return parents;
| |
- | }
| |
- | /**
| |
- | * Reselect the active step
| |
- | *
| |
- | * @param String type reason of reselecting step
| |
- | */
| |
- | function reselect( type ) {
| |
- | return select( { step: active, substep: activeSubstep }, type);
| |
- | }
| |
- | /**
| |
- | * Select a given step
| |
- | *
| |
- | * @param el element to select
| |
- | * @param type reason of changing step
| |
- | * @return Object element selected
| |
- | */
| |
- | function select( el, type ) {
| |
- | var substep;
| |
- | if ( $.isPlainObject( el ) ) {
| |
- | substep = el.substep;
| |
- | el = el.step;
| |
- | }
| |
- | if ( typeof el === 'string') {
| |
- | el = jmpress.find( el ).first();
| |
- | }
| |
- | if ( !el || !$(el).data('stepData') ) {
| |
- | return false;
| |
- | }
| |
- |
| |
- | // Sometimes it's possible to trigger focus on first link with some keyboard action.
| |
- | // Browser in such a case tries to scroll the page to make this element visible
| |
- | // (even that body overflow is set to hidden) and it breaks our careful positioning.
| |
- | //
| |
- | // So, as a lousy (and lazy) workaround we will make the page scroll back to the top
| |
- | // whenever slide is selected
| |
- | //
| |
- | // If you are reading this and know any better way to handle it, I'll be glad to hear about it!
| |
- | scrollFix.call(this);
| |
- |
| |
- | var step = $(el).data('stepData');
| |
- |
| |
- | var cancelSelect = false;
| |
- | callCallback.call(this, "beforeChange", el, {
| |
- | stepData: step
| |
- | ,reason: type
| |
- | ,cancel: function() {
| |
- | cancelSelect = true;
| |
- | }
| |
- | });
| |
- | if (cancelSelect) {
| |
- | return undefined;
| |
- | }
| |
- |
| |
- | var target = {};
| |
- |
| |
- | var delegated = el;
| |
- | if($(el).data("stepData").delegate) {
| |
- | delegated = $(el).parentsUntil(jmpress).filter(settings.stepSelector).filter(step.delegate) ||
| |
- | $(el).near(step.delegate) ||
| |
- | $(el).near(step.delegate, true) ||
| |
- | $(step.delegate, jmpress);
| |
- | step = delegated.data("stepData");
| |
- | }
| |
- | if ( activeDelegated ) {
| |
- | callCallback.call(this, 'setInactive', activeDelegated, {
| |
- | stepData: $(activeDelegated).data('stepData')
| |
- | ,delegatedFrom: active
| |
- | ,reason: type
| |
- | ,target: target
| |
- | ,nextStep: delegated
| |
- | ,nextSubstep: substep
| |
- | ,nextStepData: step
| |
- | } );
| |
- | }
| |
- | var callbackData = {
| |
- | stepData: step
| |
- | ,delegatedFrom: el
| |
- | ,reason: type
| |
- | ,target: target
| |
- | ,substep: substep
| |
- | ,prevStep: activeDelegated
| |
- | ,prevSubstep: activeSubstep
| |
- | ,prevStepData: activeDelegated && $(activeDelegated).data('stepData')
| |
- | };
| |
- | callCallback.call(this, 'beforeActive', delegated, callbackData);
| |
- | callCallback.call(this, 'setActive', delegated, callbackData);
| |
- |
| |
- | // Set on step class on root element
| |
- | if (current.jmpressClass) {
| |
- | $(jmpress).removeClass(current.jmpressClass);
| |
- | }
| |
- | $(jmpress).addClass(current.jmpressClass = 'step-' + $(delegated).attr('id') );
| |
- | if (current.jmpressDelegatedClass) {
| |
- | $(jmpress).removeClass(current.jmpressDelegatedClass);
| |
- | }
| |
- | $(jmpress).addClass(current.jmpressDelegatedClass = 'delegating-step-' + $(el).attr('id') );
| |
- |
| |
- | callCallback.call(this, "applyTarget", active, $.extend({
| |
- | canvas: canvas
| |
- | ,area: area
| |
- | }, callbackData));
| |
- |
| |
- | active = el;
| |
- | activeSubstep = callbackData.substep;
| |
- | activeDelegated = delegated;
| |
- |
| |
- | loadSiblings.call(this);
| |
- |
| |
- | return delegated;
| |
- | }
| |
- | /**
| |
- | * This should fix ANY kind of buggy scrolling
| |
- | */
| |
- | function scrollFix() {
| |
- | function fix() {
| |
- | if ($(container)[0].tagName === "BODY") {
| |
- | window.scrollTo(0, 0);
| |
- | }
| |
- | $(container).scrollTop(0);
| |
- | $(container).scrollLeft(0);
| |
- | function check() {
| |
- | if ($(container).scrollTop() !== 0 ||
| |
- | $(container).scrollLeft() !== 0) {
| |
- | fix();
| |
- | }
| |
- | }
| |
- | setTimeout(check, 1);
| |
- | setTimeout(check, 10);
| |
- | setTimeout(check, 100);
| |
- | setTimeout(check, 200);
| |
- | setTimeout(check, 400);
| |
- | }
| |
- | fix();
| |
- | }
| |
- | /**
| |
- | * Alias for select
| |
- | */
| |
- | function goTo( el ) {
| |
- | return select.call(this, el, "jump" );
| |
- | }
| |
- | /**
| |
- | * Goto Next Slide
| |
- | *
| |
- | * @return Object newly active slide
| |
- | */
| |
- | function next() {
| |
- | return select.call(this, callCallback.call(this, 'selectNext', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | ,substep: activeSubstep
| |
- | }), "next" );
| |
- | }
| |
- | /**
| |
- | * Goto Previous Slide
| |
- | *
| |
- | * @return Object newly active slide
| |
- | */
| |
- | function prev() {
| |
- | return select.call(this, callCallback.call(this, 'selectPrev', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | ,substep: activeSubstep
| |
- | }), "prev" );
| |
- | }
| |
- | /**
| |
- | * Goto First Slide
| |
- | *
| |
- | * @return Object newly active slide
| |
- | */
| |
- | function home() {
| |
- | return select.call(this, callCallback.call(this, 'selectHome', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | }), "home" );
| |
- | }
| |
- | /**
| |
- | * Goto Last Slide
| |
- | *
| |
- | * @return Object newly active slide
| |
- | */
| |
- | function end() {
| |
- | return select.call(this, callCallback.call(this, 'selectEnd', active, {
| |
- | stepData: $(active).data('stepData')
| |
- | }), "end" );
| |
- | }
| |
- | /**
| |
- | * Manipulate the canvas
| |
- | *
| |
- | * @param props
| |
- | * @return Object
| |
- | */
| |
- | function canvasMod( props ) {
| |
- | css(canvas, props || {});
| |
- | return $(canvas);
| |
- | }
| |
- | /**
| |
- | * Return current step
| |
- | *
| |
- | * @return Object
| |
- | */
| |
- | function getActive() {
| |
- | return activeDelegated && $(activeDelegated);
| |
- | }
| |
- | /**
| |
- | * fire a callback
| |
- | *
| |
- | * @param callbackName
| |
- | * @param element
| |
- | * @param eventData
| |
- | * @return void
| |
- | */
| |
- | function fire( callbackName, element, eventData ) {
| |
- | if( !callbacks[callbackName] ) {
| |
- | $.error( "callback " + callbackName + " is not registered." );
| |
- | } else {
| |
- | callCallback.call(this, callbackName, element, eventData);
| |
- | }
| |
- | }
| |
- |
| |
- | /**
| |
- | * PUBLIC METHODS LIST
| |
- | */
| |
- | jmpress.data("jmpressmethods", {
| |
- | select: select
| |
- | ,reselect: reselect
| |
- | ,scrollFix: scrollFix
| |
- | ,goTo: goTo
| |
- | ,next: next
| |
- | ,prev: prev
| |
- | ,home: home
| |
- | ,end: end
| |
- | ,canvas: canvasMod
| |
- | ,container: function() { return container; }
| |
- | ,settings: function() { return settings; }
| |
- | ,active: getActive
| |
- | ,current: function() { return current; }
| |
- | ,fire: fire
| |
- | ,deinit: deinit
| |
- | ,reapply: doStepReapply
| |
- | });
| |
- |
| |
- | /**
| |
- | * Check for support
| |
- | * This will be removed in near future, when support is coming
| |
- | *
| |
- | * @access protected
| |
- | * @return void
| |
- | */
| |
- | function checkSupport() {
| |
- | var ua = navigator.userAgent.toLowerCase();
| |
- | var supported = ( ua.search(/(iphone)|(ipod)|(android)/) === -1 );
| |
- | return supported;
| |
- | }
| |
- |
| |
- | // BEGIN INIT
| |
- |
| |
- | // CHECK FOR SUPPORT
| |
- | if (checkSupport() === false) {
| |
- | if (settings.notSupportedClass) {
| |
- | jmpress.addClass(settings.notSupportedClass);
| |
- | }
| |
- | return;
| |
- | } else {
| |
- | if (settings.notSupportedClass) {
| |
- | jmpress.removeClass(settings.notSupportedClass);
| |
- | }
| |
- | }
| |
- |
| |
- | // grabbing all steps
| |
- | var steps = $(settings.stepSelector, jmpress);
| |
- |
| |
- | // GERNERAL INIT OF FRAME
| |
- | container = jmpress;
| |
- | area = $('<div />');
| |
- | canvas = $('<div />');
| |
- | $(jmpress).children().filter(steps).each(function() {
| |
- | canvas.append( $( this ) );
| |
- | });
| |
- | if(settings.fullscreen) {
| |
- | container = $('body');
| |
- | $("html").css({
| |
- | overflow: 'hidden'
| |
- | });
| |
- | area = jmpress;
| |
- | }
| |
- | oldStyle.area = area.attr("style") || "";
| |
- | oldStyle.container = container.attr("style") || "";
| |
- | if(settings.fullscreen) {
| |
- | container.css({
| |
- | height: '100%'
| |
- | });
| |
- | jmpress.append( canvas );
| |
- | } else {
| |
- | container.css({
| |
- | position: "relative"
| |
- | });
| |
- | area.append( canvas );
| |
- | jmpress.append( area );
| |
- | }
| |
- |
| |
- | $(container).addClass(settings.containerClass);
| |
- | $(area).addClass(settings.areaClass);
| |
- | $(canvas).addClass(settings.canvasClass);
| |
- |
| |
- | document.documentElement.style.height = "100%";
| |
- | container.css({
| |
- | overflow: 'hidden'
| |
- | });
| |
- |
| |
- | var props = {
| |
- | position: "absolute"
| |
- | ,transitionDuration: '0s'
| |
- | };
| |
- | props = $.extend({}, settings.animation, props);
| |
- | css(area, props);
| |
- | css(area, {
| |
- | top: '50%'
| |
- | ,left: '50%'
| |
- | ,perspective: '1000px'
| |
- | });
| |
- | css(canvas, props);
| |
- |
| |
- | current = {};
| |
- |
| |
- | callCallback.call(this, 'beforeInit', null, {});
| |
- |
| |
- | // INITIALIZE EACH STEP
| |
- | steps.each(function( idx ) {
| |
- | doStepInit.call(jmpress, this, idx );
| |
- | });
| |
- |
| |
- | callCallback.call(this, 'afterInit', null, {});
| |
- |
| |
- | // START
| |
- | select.call(this, callCallback.call(this, 'selectInitialStep', "init", {}) );
| |
- |
| |
- | if (settings.initClass) {
| |
- | $(steps).removeClass(settings.initClass);
| |
- | }
| |
- | }
| |
- | /**
| |
- | * Return default settings
| |
- | *
| |
- | * @return Object
| |
- | */
| |
- | function getDefaults() {
| |
- | return defaults;
| |
- | }
| |
- | /**
| |
- | * Register a callback or a jmpress function
| |
- | *
| |
- | * @access public
| |
- | * @param name String the name of the callback or function
| |
- | * @param func Function? the function to be added
| |
- | */
| |
- | function register(name, func) {
| |
- | if( $.isFunction(func) ) {
| |
- | if( methods[name] ) {
| |
- | $.error( "function " + name + " is already registered." );
| |
- | } else {
| |
- | methods[name] = func;
| |
- | }
| |
- | } else {
| |
- | if( callbacks[name] ) {
| |
- | $.error( "callback " + name + " is already registered." );
| |
- | } else {
| |
- | callbacks[name] = 1;
| |
- | defaults[name] = [];
| |
- | }
| |
- | }
| |
- | }
| |
- | /**
| |
- | * Set CSS on element w/ prefixes
| |
- | *
| |
- | * @return Object element which properties were set
| |
- | *
| |
- | * TODO: Consider bypassing pfx and blindly set as jQuery
| |
- | * already checks for support
| |
- | */
| |
- | function css( el, props ) {
| |
- | var key, pkey, cssObj = {};
| |
- | for ( key in props ) {
| |
- | if ( props.hasOwnProperty(key) ) {
| |
- | pkey = pfx(key);
| |
- | if ( pkey !== null ) {
| |
- | cssObj[pkey] = props[key];
| |
- | }
| |
- | }
| |
- | }
| |
- | $(el).css(cssObj);
| |
- | return el;
| |
- | }
| |
- | /**
| |
- | * Return dataset for element
| |
- | *
| |
- | * @param el element
| |
- | * @return Object
| |
- | */
| |
- | function dataset( el ) {
| |
- | if ( $(el)[0].dataset ) {
| |
- | return $.extend({}, $(el)[0].dataset);
| |
- | }
| |
- | function toCamelcase( str ) {
| |
- | str = str.split( '-' );
| |
- | for( var i = 1; i < str.length; i++ ) {
| |
- | str[i] = str[i].substr(0, 1).toUpperCase() + str[i].substr(1);
| |
- | }
| |
- | return str.join( '' );
| |
- | }
| |
- | var returnDataset = {};
| |
- | var attrs = $(el)[0].attributes;
| |
- | $.each(attrs, function ( idx, attr ) {
| |
- | if ( attr.nodeName.substr(0, 5) === "data-" ) {
| |
- | returnDataset[ toCamelcase(attr.nodeName.substr(5)) ] = attr.nodeValue;
| |
- | }
| |
- | });
| |
- | return returnDataset;
| |
- | }
| |
- | /**
| |
- | * Returns true, if jmpress is initialized
| |
- | *
| |
- | * @return bool
| |
- | */
| |
- | function initialized() {
| |
- | return !!$(this).data("jmpressmethods");
| |
- | }
| |
- |
| |
- |
| |
- | /**
| |
- | * PUBLIC STATIC METHODS LIST
| |
- | */
| |
- | var methods = {
| |
- | init: init
| |
- | ,initialized: initialized
| |
- | ,deinit: function() {}
| |
- | ,css: css
| |
- | ,pfx: pfx
| |
- | ,defaults: getDefaults
| |
- | ,register: register
| |
- | ,dataset: dataset
| |
- | };
| |
- |
| |
- | /**
| |
- | * $.jmpress()
| |
- | */
| |
- | $.fn.jmpress = function( method ) {
| |
- | function f() {
| |
- | var jmpressmethods = $(this).data("jmpressmethods");
| |
- | if ( jmpressmethods && jmpressmethods[method] ) {
| |
- | if ( method.substr(0, 1) === '_' && jmpressmethods.settings().test === false) {
| |
- | $.error( 'Method ' + method + ' is protected and should only be used internally.' );
| |
- | } else {
| |
- | return jmpressmethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
| |
- | }
| |
- | } else if ( methods[method] ) {
| |
- | if ( method.substr(0, 1) === '_' && defaults.test === false) {
| |
- | $.error( 'Method ' + method + ' is protected and should only be used internally.' );
| |
- | } else {
| |
- | return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
| |
- | }
| |
- | } else if ( callbacks[method] && jmpressmethods ) {
| |
- | var settings = jmpressmethods.settings();
| |
- | var func = Array.prototype.slice.call( arguments, 1 )[0];
| |
- | if ($.isFunction( func )) {
| |
- | settings[method] = settings[method] || [];
| |
- | settings[method].push(func);
| |
- | }
| |
- | } else if ( typeof method === 'object' || ! method ) {
| |
- | return init.apply( this, arguments );
| |
- | } else {
| |
- | $.error( 'Method ' + method + ' does not exist on jQuery.jmpress' );
| |
- | }
| |
- | // to allow chaining
| |
- | return this;
| |
- | }
| |
- | var args = arguments;
| |
- | var result;
| |
- | $(this).each(function(idx, element) {
| |
- | result = f.apply(element, args);
| |
- | });
| |
- | return result;
| |
- | };
| |
- | $.extend({
| |
- | jmpress: function( method ) {
| |
- | if ( methods[method] ) {
| |
- | if ( method.substr(0, 1) === '_' && defaults.test === false) {
| |
- | $.error( 'Method ' + method + ' is protected and should only be used internally.' );
| |
- | } else {
| |
- | return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
| |
- | }
| |
- | } else if ( callbacks[method] ) {
| |
- | // plugin interface
| |
- | var func = Array.prototype.slice.call( arguments, 1 )[0];
| |
- | if ($.isFunction( func )) {
| |
- | defaults[method].push(func);
| |
- | } else {
| |
- | $.error( 'Second parameter should be a function: $.jmpress( callbackName, callbackFunction )' );
| |
- | }
| |
- | } else {
| |
- | $.error( 'Method ' + method + ' does not exist on jQuery.jmpress' );
| |
- | }
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * near.js
| |
- | * Find steps near each other
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | // add near( selector, backwards = false) to jquery
| |
- |
| |
- |
| |
- | function checkAndGo( elements, func, selector, backwards ) {
| |
- | var next;
| |
- | elements.each(function(idx, element) {
| |
- | if(backwards) {
| |
- | next = func(element, selector, backwards);
| |
- | if (next) {
| |
- | return false;
| |
- | }
| |
- | }
| |
- | if( $(element).is(selector) ) {
| |
- | next = element;
| |
- | return false;
| |
- | }
| |
- | if(!backwards) {
| |
- | next = func(element, selector, backwards);
| |
- | if (next) {
| |
- | return false;
| |
- | }
| |
- | }
| |
- | });
| |
- | return next;
| |
- | }
| |
- | function findNextInChildren(item, selector, backwards) {
| |
- | var children = $(item).children();
| |
- | if(backwards) {
| |
- | children = $(children.get().reverse());
| |
- | }
| |
- | return checkAndGo( children, findNextInChildren, selector, backwards );
| |
- | }
| |
- | function findNextInSiblings(item, selector, backwards) {
| |
- | return checkAndGo(
| |
- | $(item)[backwards ? "prevAll" : "nextAll"](),
| |
- | findNextInChildren, selector, backwards );
| |
- | }
| |
- | function findNextInParents(item, selector, backwards) {
| |
- | var next;
| |
- | var parents = $(item).parents();
| |
- | parents = $(parents.get());
| |
- | $.each(parents.get(), function(idx, element) {
| |
- | if( backwards && $(element).is(selector) ) {
| |
- | next = element;
| |
- | return false;
| |
- | }
| |
- | next = findNextInSiblings(element, selector, backwards);
| |
- | if(next) {
| |
- | return false;
| |
- | }
| |
- | });
| |
- | return next;
| |
- | }
| |
- |
| |
- | $.fn.near = function( selector, backwards ) {
| |
- | var array = [];
| |
- | $(this).each(function(idx, element) {
| |
- | var near = (backwards ?
| |
- | false :
| |
- | findNextInChildren( element, selector, backwards )) ||
| |
- | findNextInSiblings( element, selector, backwards ) ||
| |
- | findNextInParents( element, selector, backwards );
| |
- | if( near ) {
| |
- | array.push(near);
| |
- | }
| |
- | });
| |
- | return $(array);
| |
- | };
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * transform.js
| |
- | * The engine that powers the transforms or falls back to other methods
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- | function toCssNumber(number) {
| |
- | return (Math.round(10000*number)/10000)+"";
| |
- | }
| |
- |
| |
- | /**
| |
- | * 3D and 2D engines
| |
- | */
| |
- | var engines = {
| |
- | 3: {
| |
- | transform: function( el, data ) {
| |
- | var transform = 'translate(-50%,-50%)';
| |
- | $.each(data, function(idx, item) {
| |
- | var coord = ["X", "Y", "Z"];
| |
- | var i;
| |
- | if(item[0] === "translate") { // ["translate", x, y, z]
| |
- | transform += " translate3d(" + toCssNumber(item[1] || 0) + "px," + toCssNumber(item[2] || 0) + "px," + toCssNumber(item[3] || 0) + "px)";
| |
- | } else if(item[0] === "rotate") {
| |
- | var order = item[4] ? [1, 2, 3] : [3, 2, 1];
| |
- | for(i = 0; i < 3; i++) {
| |
- | transform += " rotate" + coord[order[i]-1] + "(" + toCssNumber(item[order[i]] || 0) + "deg)";
| |
- | }
| |
- | } else if(item[0] === "scale") {
| |
- | for(i = 0; i < 3; i++) {
| |
- | transform += " scale" + coord[i] + "(" + toCssNumber(item[i+1] || 1) + ")";
| |
- | }
| |
- | }
| |
- | });
| |
- | $.jmpress("css", el, $.extend({}, { transform: transform }));
| |
- | }
| |
- | }
| |
- | ,2: {
| |
- | transform: function( el, data ) {
| |
- | var transform = 'translate(-50%,-50%)';
| |
- | $.each(data, function(idx, item) {
| |
- | var coord = ["X", "Y"];
| |
- | if(item[0] === "translate") { // ["translate", x, y, z]
| |
- | transform += " translate(" + toCssNumber(item[1] || 0) + "px," + toCssNumber(item[2] || 0) + "px)";
| |
- | } else if(item[0] === "rotate") {
| |
- | transform += " rotate(" + toCssNumber(item[3] || 0) + "deg)";
| |
- | } else if(item[0] === "scale") {
| |
- | for(var i = 0; i < 2; i++) {
| |
- | transform += " scale" + coord[i] + "(" + toCssNumber(item[i+1] || 1) + ")";
| |
- | }
| |
- | }
| |
- | });
| |
- | $.jmpress("css", el, $.extend({}, { transform: transform }));
| |
- | }
| |
- | }
| |
- | ,1: {
| |
- | // CHECK IF SUPPORT IS REALLY NEEDED?
| |
- | // this not even work without scaling...
| |
- | // it may better to display the normal view
| |
- | transform: function( el, data ) {
| |
- | var anitarget = { top: 0, left: 0 };
| |
- | $.each(data, function(idx, item) {
| |
- | var coord = ["X", "Y"];
| |
- | if(item[0] === "translate") { // ["translate", x, y, z]
| |
- | anitarget.left = Math.round(item[1] || 0) + "px";
| |
- | anitarget.top = Math.round(item[2] || 0) + "px";
| |
- | }
| |
- | });
| |
- | el.animate(anitarget, 1000); // TODO: Use animation duration
| |
- | }
| |
- | }
| |
- | };
| |
- |
| |
- | /**
| |
- | * Engine to power cross-browser translate, scale and rotate.
| |
- | */
| |
- | var engine = (function() {
| |
- | if ($.jmpress("pfx", "perspective")) {
| |
- | return engines[3];
| |
- | } else if ($.jmpress("pfx", "transform")) {
| |
- | return engines[2];
| |
- | } else {
| |
- | // CHECK IF SUPPORT IS REALLY NEEDED?
| |
- | return engines[1];
| |
- | }
| |
- | }());
| |
- |
| |
- | $.jmpress("defaults").reasonableAnimation = {};
| |
- | $.jmpress("initStep", function( step, eventData ) {
| |
- | var data = eventData.data;
| |
- | var stepData = eventData.stepData;
| |
- | var pf = parseFloat;
| |
- | $.extend(stepData, {
| |
- | x: pf(data.x) || 0
| |
- | ,y: pf(data.y) || 0
| |
- | ,z: pf(data.z) || 0
| |
- | ,r: pf(data.r) || 0
| |
- | ,phi: pf(data.phi) || 0
| |
- | ,rotate: pf(data.rotate) || 0
| |
- | ,rotateX: pf(data.rotateX) || 0
| |
- | ,rotateY: pf(data.rotateY) || 0
| |
- | ,rotateZ: pf(data.rotateZ) || 0
| |
- | ,revertRotate: false
| |
- | ,scale: pf(data.scale) || 1
| |
- | ,scaleX: pf(data.scaleX) || false
| |
- | ,scaleY: pf(data.scaleY) || false
| |
- | ,scaleZ: pf(data.scaleZ) || 1
| |
- | });
| |
- | });
| |
- | $.jmpress("afterInit", function( nil, eventData ) {
| |
- | var stepSelector = eventData.settings.stepSelector,
| |
- | current = eventData.current;
| |
- | current.perspectiveScale = 1;
| |
- | current.maxNestedDepth = 0;
| |
- | var nestedSteps = $(eventData.jmpress).find(stepSelector).children(stepSelector);
| |
- | while(nestedSteps.length) {
| |
- | current.maxNestedDepth++;
| |
- | nestedSteps = nestedSteps.children(stepSelector);
| |
- | }
| |
- | });
| |
- | $.jmpress("applyStep", function( step, eventData ) {
| |
- | $.jmpress("css", $(step), {
| |
- | position: "absolute"
| |
- | ,transformStyle: "preserve-3d"
| |
- | });
| |
- | if ( eventData.parents.length > 0 ) {
| |
- | $.jmpress("css", $(step), {
| |
- | top: "50%"
| |
- | ,left: "50%"
| |
- | });
| |
- | }
| |
- | var sd = eventData.stepData;
| |
- | var transform = [
| |
- | ["translate",
| |
- | sd.x || (sd.r * Math.sin(sd.phi*Math.PI/180)),
| |
- | sd.y || (-sd.r * Math.cos(sd.phi*Math.PI/180)),
| |
- | sd.z],
| |
- | ["rotate",
| |
- | sd.rotateX,
| |
- | sd.rotateY,
| |
- | sd.rotateZ || sd.rotate,
| |
- | true],
| |
- | ["scale",
| |
- | sd.scaleX || sd.scale,
| |
- | sd.scaleY || sd.scale,
| |
- | sd.scaleZ || sd.scale]
| |
- | ];
| |
- | engine.transform( step, transform );
| |
- | });
| |
- | $.jmpress("setActive", function( element, eventData ) {
| |
- | var target = eventData.target;
| |
- | var step = eventData.stepData;
| |
- | var tf = target.transform = [];
| |
- | target.perspectiveScale = 1;
| |
- |
| |
- | for(var i = eventData.current.maxNestedDepth; i > (eventData.parents.length || 0); i--) {
| |
- | tf.push(["scale"], ["rotate"], ["translate"]);
| |
- | }
| |
- |
| |
- | tf.push(["scale",
| |
- | 1 / (step.scaleX || step.scale),
| |
- | 1 / (step.scaleY || step.scale),
| |
- | 1 / (step.scaleZ)]);
| |
- | tf.push(["rotate",
| |
- | -step.rotateX,
| |
- | -step.rotateY,
| |
- | -(step.rotateZ || step.rotate)]);
| |
- | tf.push(["translate",
| |
- | -(step.x || (step.r * Math.sin(step.phi*Math.PI/180))),
| |
- | -(step.y || (-step.r * Math.cos(step.phi*Math.PI/180))),
| |
- | -step.z]);
| |
- | target.perspectiveScale *= (step.scaleX || step.scale);
| |
- |
| |
- | $.each(eventData.parents, function(idx, element) {
| |
- | var step = $(element).data("stepData");
| |
- | tf.push(["scale",
| |
- | 1 / (step.scaleX || step.scale),
| |
- | 1 / (step.scaleY || step.scale),
| |
- | 1 / (step.scaleZ)]);
| |
- | tf.push(["rotate",
| |
- | -step.rotateX,
| |
- | -step.rotateY,
| |
- | -(step.rotateZ || step.rotate)]);
| |
- | tf.push(["translate",
| |
- | -(step.x || (step.r * Math.sin(step.phi*Math.PI/180))),
| |
- | -(step.y || (-step.r * Math.cos(step.phi*Math.PI/180))),
| |
- | -step.z]);
| |
- | target.perspectiveScale *= (step.scaleX || step.scale);
| |
- | });
| |
- |
| |
- | $.each(tf, function(idx, item) {
| |
- | if(item[0] !== "rotate") {
| |
- | return;
| |
- | }
| |
- | function lowRotate(name) {
| |
- | if(eventData.current["rotate"+name+"-"+idx] === undefined) {
| |
- | eventData.current["rotate"+name+"-"+idx] = item[name] || 0;
| |
- | }
| |
- | var cur = eventData.current["rotate"+name+"-"+idx], tar = item[name] || 0,
| |
- | curmod = cur % 360, tarmod = tar % 360;
| |
- | if(curmod < 0) {
| |
- | curmod += 360;
| |
- | }
| |
- | if(tarmod < 0) {
| |
- | tarmod += 360;
| |
- | }
| |
- | var diff = tarmod - curmod;
| |
- | if(diff < -180) {
| |
- | diff += 360;
| |
- | } else if(diff > 180) {
| |
- | diff -= 360;
| |
- | }
| |
- | eventData.current["rotate"+name+"-"+idx] = item[name] = cur + diff;
| |
- | }
| |
- | lowRotate(1);
| |
- | lowRotate(2);
| |
- | lowRotate(3);
| |
- | });
| |
- | });
| |
- | $.jmpress("applyTarget", function( active, eventData ) {
| |
- |
| |
- | var target = eventData.target,
| |
- | props, step = eventData.stepData,
| |
- | settings = eventData.settings,
| |
- | zoomin = target.perspectiveScale * 1.3 < eventData.current.perspectiveScale,
| |
- | zoomout = target.perspectiveScale > eventData.current.perspectiveScale * 1.3;
| |
- |
| |
- | // extract first scale from transform
| |
- | var lastScale = -1;
| |
- | $.each(target.transform, function(idx, item) {
| |
- | if(item.length <= 1) {
| |
- | return;
| |
- | }
| |
- | if(item[0] === "rotate" &&
| |
- | item[1] % 360 === 0 &&
| |
- | item[2] % 360 === 0 &&
| |
- | item[3] % 360 === 0) {
| |
- | return;
| |
- | }
| |
- | if(item[0] === "scale") {
| |
- | lastScale = idx;
| |
- | } else {
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | if(lastScale !== eventData.current.oldLastScale) {
| |
- | zoomin = zoomout = false;
| |
- | eventData.current.oldLastScale = lastScale;
| |
- | }
| |
- |
| |
- | var extracted = [];
| |
- | if(lastScale !== -1) {
| |
- | while(lastScale >= 0) {
| |
- | if(target.transform[lastScale][0] === "scale") {
| |
- | extracted.push(target.transform[lastScale]);
| |
- | target.transform[lastScale] = ["scale"];
| |
- | }
| |
- | lastScale--;
| |
- | }
| |
- | }
| |
- |
| |
- | var animation = settings.animation;
| |
- | if(settings.reasonableAnimation[eventData.reason]) {
| |
- | animation = $.extend({},
| |
- | animation,
| |
- | settings.reasonableAnimation[eventData.reason]);
| |
- | }
| |
- |
| |
- | props = {
| |
- | // to keep the perspective look similar for different scales
| |
- | // we need to 'scale' the perspective, too
| |
- | perspective: Math.round(target.perspectiveScale * 1000) + "px"
| |
- | };
| |
- | props = $.extend({}, animation, props);
| |
- | if (!zoomin) {
| |
- | props.transitionDelay = '0s';
| |
- | }
| |
- | if (!active) {
| |
- | props.transitionDuration = '0s';
| |
- | props.transitionDelay = '0s';
| |
- | }
| |
- | $.jmpress("css", eventData.area, props);
| |
- | engine.transform(eventData.area, extracted);
| |
- |
| |
- | props = $.extend({}, animation);
| |
- | if (!zoomout) {
| |
- | props.transitionDelay = '0s';
| |
- | }
| |
- | if (!active) {
| |
- | props.transitionDuration = '0s';
| |
- | props.transitionDelay = '0s';
| |
- | }
| |
- |
| |
- | eventData.current.perspectiveScale = target.perspectiveScale;
| |
- |
| |
- | $.jmpress("css", eventData.canvas, props);
| |
- | engine.transform(eventData.canvas, target.transform);
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * active.js
| |
- | * Set the active classes on steps
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* DEFINES */
| |
- | var activeClass = 'activeClass',
| |
- | nestedActiveClass = 'nestedActiveClass';
| |
- |
| |
- | /* DEFAULTS */
| |
- | var defaults = $jmpress( 'defaults' );
| |
- | defaults[nestedActiveClass] = "nested-active";
| |
- | defaults[activeClass] = "active";
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress( 'setInactive', function( step, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | activeClassSetting = settings[activeClass],
| |
- | nestedActiveClassSettings = settings[nestedActiveClass];
| |
- | if(activeClassSetting) {
| |
- | $(step).removeClass( activeClassSetting );
| |
- | }
| |
- | if(nestedActiveClassSettings) {
| |
- | $.each(eventData.parents, function(idx, element) {
| |
- | $(element).removeClass(nestedActiveClassSettings);
| |
- | });
| |
- | }
| |
- | });
| |
- | $jmpress( 'setActive', function( step, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | activeClassSetting = settings[activeClass],
| |
- | nestedActiveClassSettings = settings[nestedActiveClass];
| |
- | if(activeClassSetting) {
| |
- | $(step).addClass( activeClassSetting );
| |
- | }
| |
- | if(nestedActiveClassSettings) {
| |
- | $.each(eventData.parents, function(idx, element) {
| |
- | $(element).addClass(nestedActiveClassSettings);
| |
- | });
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * circular.js
| |
- | * Repeat from start after end
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function firstSlide( step, eventData ) {
| |
- | return $(this).find(eventData.settings.stepSelector).first();
| |
- | }
| |
- | function prevOrNext( jmpress, step, eventData, prev) {
| |
- | if (!step) {
| |
- | return false;
| |
- | }
| |
- | var stepSelector = eventData.settings.stepSelector;
| |
- | step = $(step);
| |
- | do {
| |
- | var item = step.near( stepSelector, prev );
| |
- | if (item.length === 0 || item.closest(jmpress).length === 0) {
| |
- | item = $(jmpress).find(stepSelector)[prev?"last":"first"]();
| |
- | }
| |
- | if (!item.length) {
| |
- | return false;
| |
- | }
| |
- | step = item;
| |
- | } while( step.data("stepData").exclude );
| |
- | return step;
| |
- | }
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress( 'initStep', function( step, eventData ) {
| |
- | eventData.stepData.exclude = eventData.data.exclude && ["false", "no"].indexOf(eventData.data.exclude) === -1;
| |
- | });
| |
- | $jmpress( 'selectInitialStep', firstSlide);
| |
- | $jmpress( 'selectHome', firstSlide);
| |
- | $jmpress( 'selectEnd', function( step, eventData ) {
| |
- | return $(this).find(eventData.settings.stepSelector).last();
| |
- | });
| |
- | $jmpress( 'selectPrev', function( step, eventData ) {
| |
- | return prevOrNext(this, step, eventData, true);
| |
- | });
| |
- | $jmpress( 'selectNext', function( step, eventData ) {
| |
- | return prevOrNext(this, step, eventData);
| |
- | });
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * start.js
| |
- | * Set the first step to start on
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | /* HOOKS */
| |
- | $.jmpress( 'selectInitialStep', function( nil, eventData ) {
| |
- | return eventData.settings.start;
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * ways.js
| |
- | * Control the flow of the steps
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- | // TODO allow call of route after init
| |
- | function routeFunc( jmpress, route, type ) {
| |
- | for(var i = 0; i < route.length - 1; i++) {
| |
- | var from = route[i];
| |
- | var to = route[i+1];
| |
- | $(from, jmpress).attr('data-' + type, to);
| |
- | }
| |
- | }
| |
- | function selectPrevOrNext( step, eventData, attr, prev ) {
| |
- | var stepData = eventData.stepData;
| |
- | if(stepData[attr]) {
| |
- | var near = $(step).near(stepData[attr], prev);
| |
- | if(near && near.length) {
| |
- | return near;
| |
- | }
| |
- | near = $(stepData[attr], this)[prev?"last":"first"]();
| |
- | if(near && near.length) {
| |
- | return near;
| |
- | }
| |
- | }
| |
- | }
| |
- |
| |
- | /* EXPORTED FUNCTIONS */
| |
- | $jmpress( 'register', 'route', function( route, unidirectional, reversedRoute ) {
| |
- | if( typeof route === "string" ) {
| |
- | route = [route, route];
| |
- | }
| |
- | routeFunc(this, route, reversedRoute ? "prev" : "next");
| |
- | if (!unidirectional) {
| |
- | routeFunc(this, route.reverse(), reversedRoute ? "next" : "prev");
| |
- | }
| |
- | });
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress( 'initStep', function( step, eventData ) {
| |
- | for(var attr in {next:1,prev:1}) {
| |
- | eventData.stepData[attr] = eventData.data[attr];
| |
- | }
| |
- | });
| |
- | $jmpress( 'selectNext', function( step, eventData ) {
| |
- | return selectPrevOrNext(step, eventData, "next");
| |
- | });
| |
- | $jmpress( 'selectPrev', function( step, eventData ) {
| |
- | return selectPrevOrNext(step, eventData, "prev", true);
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * ajax.js
| |
- | * Load steps via ajax
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* DEFINES */
| |
- | var afterStepLoaded = 'afterStepLoaded';
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | /* REGISTER EVENTS */
| |
- | $jmpress('register', afterStepLoaded);
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress('initStep', function( step, eventData ) {
| |
- | eventData.stepData.src = $(step).attr('href') || eventData.data.src || false;
| |
- | });
| |
- | $jmpress('loadStep', function( step, eventData ) {
| |
- | var stepData = eventData.stepData,
| |
- | href = stepData && stepData.src;
| |
- | if ( href ) {
| |
- | $(step).load(href, function(response, status, xhr) {
| |
- | $(eventData.jmpress).jmpress('fire', afterStepLoaded, step, $.extend({}, eventData, {
| |
- | response: response
| |
- | ,status: status
| |
- | ,xhr: xhr
| |
- | }));
| |
- | });
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * hash.js
| |
- | * Detect and set the URL hash
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress,
| |
- | hashLink = "a[href^=#]";
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- | /**
| |
- | * getElementFromUrl
| |
- | *
| |
- | * @return String or undefined
| |
- | */
| |
- | function getElementFromUrl(settings) {
| |
- | // get id from url # by removing `#` or `#/` from the beginning,
| |
- | // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
| |
- | // TODO SECURITY check user input to be valid!
| |
- | try {
| |
- | var el = $( '#' + window.location.hash.replace(/^#\/?/,"") );
| |
- | return el.length > 0 && el.is(settings.stepSelector) ? el : undefined;
| |
- | } catch(e) {}
| |
- | }
| |
- |
| |
- | /* DEFAULTS */
| |
- | $jmpress('defaults').hash = {
| |
- | use: true
| |
- | ,update: true
| |
- | ,bindChange: true
| |
- | // NOTICE: {use: true, update: false, bindChange: true}
| |
- | // will cause a error after clicking on a link to the current step
| |
- | };
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress('selectInitialStep', function( step, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | hashSettings = settings.hash,
| |
- | current = eventData.current,
| |
- | jmpress = $(this);
| |
- | eventData.current.hashNamespace = ".jmpress-"+randomString();
| |
- | // HASH CHANGE EVENT
| |
- | if ( hashSettings.use ) {
| |
- | if ( hashSettings.bindChange ) {
| |
- | $(window).bind('hashchange'+current.hashNamespace, function() {
| |
- | var urlItem = getElementFromUrl(settings);
| |
- | if ( jmpress.jmpress('initialized') ) {
| |
- | jmpress.jmpress("scrollFix");
| |
- | }
| |
- | if(urlItem && urlItem.length) {
| |
- | if(urlItem.attr("id") !== jmpress.jmpress("active").attr("id")) {
| |
- | jmpress.jmpress('select', urlItem);
| |
- | }
| |
- | var shouldBeHash = "#/" + urlItem.attr("id");
| |
- | if(window.location.hash !== shouldBeHash) {
| |
- | window.location.hash = shouldBeHash;
| |
- | }
| |
- | }
| |
- | });
| |
- | $(hashLink).on("click"+current.hashNamespace, function(event) {
| |
- | var href = $(this).attr("href");
| |
- | try {
| |
- | if($(href).is(settings.stepSelector)) {
| |
- | jmpress.jmpress("select", href);
| |
- | event.preventDefault();
| |
- | event.stopPropagation();
| |
- | }
| |
- | } catch(e) {}
| |
- | });
| |
- | }
| |
- | return getElementFromUrl(settings);
| |
- | }
| |
- | });
| |
- | $jmpress('afterDeinit', function( nil, eventData ) {
| |
- | $(hashLink).off(eventData.current.hashNamespace);
| |
- | $(window).unbind(eventData.current.hashNamespace);
| |
- | });
| |
- | $jmpress('setActive', function( step, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | current = eventData.current;
| |
- | // `#/step-id` is used instead of `#step-id` to prevent default browser
| |
- | // scrolling to element in hash
| |
- | if ( settings.hash.use && settings.hash.update ) {
| |
- | clearTimeout(current.hashtimeout);
| |
- | current.hashtimeout = setTimeout(function() {
| |
- | window.location.hash = "#/" + $(eventData.delegatedFrom).attr('id');
| |
- | }, settings.transitionDuration + 200);
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * keyboard.js
| |
- | * Keyboard event mapping and default keyboard actions
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress,
| |
- | jmpressNext = "next",
| |
- | jmpressPrev = "prev";
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- | function stopEvent(event) {
| |
- | event.preventDefault();
| |
- | event.stopPropagation();
| |
- | }
| |
- |
| |
- | /* DEFAULTS */
| |
- | $jmpress('defaults').keyboard = {
| |
- | use: true
| |
- | ,keys: {
| |
- | 33: jmpressPrev // pg up
| |
- | ,37: jmpressPrev // left
| |
- | ,38: jmpressPrev // up
| |
- |
| |
- | ,9: jmpressNext+":"+jmpressPrev // tab
| |
- | ,32: jmpressNext // space
| |
- | ,34: jmpressNext // pg down
| |
- | ,39: jmpressNext // right
| |
- | ,40: jmpressNext // down
| |
- |
| |
- | ,36: "home" // home
| |
- |
| |
- | ,35: "end" // end
| |
- | }
| |
- | ,ignore: {
| |
- | "INPUT": [
| |
- | 32 // space
| |
- | ,37 // left
| |
- | ,38 // up
| |
- | ,39 // right
| |
- | ,40 // down
| |
- | ]
| |
- | ,"TEXTAREA": [
| |
- | 32 // space
| |
- | ,37 // left
| |
- | ,38 // up
| |
- | ,39 // right
| |
- | ,40 // down
| |
- | ]
| |
- | ,"SELECT": [
| |
- | 38 // up
| |
- | ,40 // down
| |
- | ]
| |
- | }
| |
- | ,tabSelector: "a[href]:visible, :input:visible"
| |
- | };
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress('afterInit', function( nil, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | keyboardSettings = settings.keyboard,
| |
- | ignoreKeyboardSettings = keyboardSettings.ignore,
| |
- | current = eventData.current,
| |
- | jmpress = $(this);
| |
- |
| |
- | // tabindex make it focusable so that it can recieve key events
| |
- | if(!settings.fullscreen) {
| |
- | jmpress.attr("tabindex", 0);
| |
- | }
| |
- |
| |
- | current.keyboardNamespace = ".jmpress-"+randomString();
| |
- |
| |
- | // KEYPRESS EVENT: this fixes a Opera bug
| |
- | $(settings.fullscreen ? document : jmpress)
| |
- | .bind("keypress"+current.keyboardNamespace, function( event ) {
| |
- |
| |
- | for( var nodeName in ignoreKeyboardSettings ) {
| |
- | if ( event.target.nodeName === nodeName && ignoreKeyboardSettings[nodeName].indexOf(event.which) !== -1 ) {
| |
- | return;
| |
- | }
| |
- | }
| |
- | if(event.which >= 37 && event.which <= 40 || event.which === 32) {
| |
- | stopEvent(event);
| |
- | }
| |
- | });
| |
- | // KEYDOWN EVENT
| |
- | $(settings.fullscreen ? document : jmpress)
| |
- | .bind("keydown"+current.keyboardNamespace, function( event ) {
| |
- | var eventTarget = $(event.target);
| |
- |
| |
- | if ( !settings.fullscreen && !eventTarget.closest(jmpress).length || !keyboardSettings.use ) {
| |
- | return;
| |
- | }
| |
- |
| |
- | for( var nodeName in ignoreKeyboardSettings ) {
| |
- | if ( eventTarget[0].nodeName === nodeName && ignoreKeyboardSettings[nodeName].indexOf(event.which) !== -1 ) {
| |
- | return;
| |
- | }
| |
- | }
| |
- |
| |
- | var reverseSelect = false;
| |
- | var nextFocus;
| |
- | if (event.which === 9) {
| |
- | // tab
| |
- | if ( !eventTarget.closest( jmpress.jmpress('active') ).length ) {
| |
- | if ( !event.shiftKey ) {
| |
- | nextFocus = jmpress.jmpress('active').find("a[href], :input").filter(":visible").first();
| |
- | } else {
| |
- | reverseSelect = true;
| |
- | }
| |
- | } else {
| |
- | nextFocus = eventTarget.near( keyboardSettings.tabSelector, event.shiftKey );
| |
- | if( !$(nextFocus)
| |
- | .closest( settings.stepSelector )
| |
- | .is(jmpress.jmpress('active') ) ) {
| |
- | nextFocus = undefined;
| |
- | }
| |
- | }
| |
- | if( nextFocus && nextFocus.length > 0 ) {
| |
- | nextFocus.focus();
| |
- | jmpress.jmpress("scrollFix");
| |
- | stopEvent(event);
| |
- | return;
| |
- | } else {
| |
- | if(event.shiftKey) {
| |
- | reverseSelect = true;
| |
- | }
| |
- | }
| |
- | }
| |
- |
| |
- | var action = keyboardSettings.keys[ event.which ];
| |
- | if ( typeof action === "string" ) {
| |
- | if (action.indexOf(":") !== -1) {
| |
- | action = action.split(":");
| |
- | action = event.shiftKey ? action[1] : action[0];
| |
- | }
| |
- | jmpress.jmpress( action );
| |
- | stopEvent(event);
| |
- | } else if ( $.isFunction(action) ) {
| |
- | action.call(jmpress, event);
| |
- | } else if ( action ) {
| |
- | jmpress.jmpress.apply( jmpress, action );
| |
- | stopEvent(event);
| |
- | }
| |
- |
| |
- | if (reverseSelect) {
| |
- | // tab
| |
- | nextFocus = jmpress.jmpress('active').find("a[href], :input").filter(":visible").last();
| |
- | nextFocus.focus();
| |
- | jmpress.jmpress("scrollFix");
| |
- | }
| |
- | });
| |
- | });
| |
- | $jmpress('afterDeinit', function( nil, eventData ) {
| |
- | $(document).unbind(eventData.current.keyboardNamespace);
| |
- | });
| |
- |
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * viewport.js
| |
- | * Scale to fit a given viewport
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | var defaults = $.jmpress("defaults");
| |
- | defaults.viewPort = {
| |
- | width: false
| |
- | ,height: false
| |
- | ,maxScale: 0
| |
- | ,minScale: 0
| |
- | ,zoomable: 0
| |
- | ,zoomBindMove: true
| |
- | ,zoomBindWheel: true
| |
- | };
| |
- | var keys = defaults.keyboard.keys;
| |
- | keys[$.browser.mozilla?107:187] = "zoomIn"; // +
| |
- | keys[$.browser.mozilla?109:189] = "zoomOut"; // -
| |
- | defaults.reasonableAnimation.resize = {
| |
- | transitionDuration: '0s'
| |
- | ,transitionDelay: '0ms'
| |
- | };
| |
- | defaults.reasonableAnimation.zoom = {
| |
- | transitionDuration: '0s'
| |
- | ,transitionDelay: '0ms'
| |
- | };
| |
- | $.jmpress("initStep", function( step, eventData ) {
| |
- | for(var variable in {"viewPortHeight":1, "viewPortWidth":1, "viewPortMinScale":1, "viewPortMaxScale":1, "viewPortZoomable":1}) {
| |
- | eventData.stepData[variable] = eventData.data[variable] && parseFloat(eventData.data[variable]);
| |
- | }
| |
- | });
| |
- | $.jmpress("afterInit", function( nil, eventData ) {
| |
- | var jmpress = this;
| |
- | eventData.current.viewPortNamespace = ".jmpress-"+randomString();
| |
- | $(window).bind("resize"+eventData.current.viewPortNamespace, function (event) {
| |
- | $(jmpress).jmpress("reselect", "resize");
| |
- | });
| |
- | eventData.current.userZoom = 0;
| |
- | eventData.current.userTranslateX = 0;
| |
- | eventData.current.userTranslateY = 0;
| |
- | if(eventData.settings.viewPort.zoomBindWheel) {
| |
- | $(eventData.settings.fullscreen ? document : this)
| |
- | .bind("mousewheel"+eventData.current.viewPortNamespace, function( event, delta ) {
| |
- | delta = delta || event.originalEvent.wheelDelta;
| |
- | var direction = (delta / Math.abs(delta));
| |
- | if(direction < 0) {
| |
- | $(eventData.jmpress).jmpress("zoomOut", event.originalEvent.x, event.originalEvent.y);
| |
- | } else if(direction > 0) {
| |
- | $(eventData.jmpress).jmpress("zoomIn", event.originalEvent.x, event.originalEvent.y);
| |
- | }
| |
- | });
| |
- | }
| |
- | if(eventData.settings.viewPort.zoomBindMove) {
| |
- | $(eventData.settings.fullscreen ? document : this).bind("mousedown"+eventData.current.viewPortNamespace, function (event) {
| |
- | if(eventData.current.userZoom) {
| |
- | eventData.current.userTranslating = { x: event.clientX, y: event.clientY };
| |
- | event.preventDefault();
| |
- | event.stopImmediatePropagation();
| |
- | }
| |
- | }).bind("mousemove"+eventData.current.viewPortNamespace, function (event) {
| |
- | var userTranslating = eventData.current.userTranslating;
| |
- | if(userTranslating) {
| |
- | $(jmpress).jmpress("zoomTranslate", event.clientX - userTranslating.x, event.clientY - userTranslating.y);
| |
- | userTranslating.x = event.clientX;
| |
- | userTranslating.y = event.clientY;
| |
- | event.preventDefault();
| |
- | event.stopImmediatePropagation();
| |
- | }
| |
- | }).bind("mouseup"+eventData.current.viewPortNamespace, function (event) {
| |
- | if(eventData.current.userTranslating) {
| |
- | eventData.current.userTranslating = undefined;
| |
- | event.preventDefault();
| |
- | event.stopImmediatePropagation();
| |
- | }
| |
- | });
| |
- | }
| |
- | });
| |
- | function maxAbs(value, range) {
| |
- | return Math.max(Math.min(value, range), -range);
| |
- | }
| |
- | function zoom(x, y, direction) {
| |
- | var current = $(this).jmpress("current"),
| |
- | settings = $(this).jmpress("settings"),
| |
- | stepData = $(this).jmpress("active").data("stepData"),
| |
- | container = $(this).jmpress("container");
| |
- | if(current.userZoom === 0 && direction < 0) {
| |
- | return;
| |
- | }
| |
- | var zoomableSteps = stepData.viewPortZoomable || settings.viewPort.zoomable;
| |
- | if(current.userZoom === zoomableSteps && direction > 0) {
| |
- | return;
| |
- | }
| |
- | current.userZoom += direction;
| |
- |
| |
- | var halfWidth = $(container).innerWidth()/2,
| |
- | halfHeight = $(container).innerHeight()/2;
| |
- |
| |
- | x = x ? x - halfWidth : x;
| |
- | y = y ? y - halfHeight : y;
| |
- |
| |
- | // TODO this is not perfect... too much math... :(
| |
- | current.userTranslateX =
| |
- | maxAbs(current.userTranslateX - direction * x / current.zoomOriginWindowScale / zoomableSteps,
| |
- | halfWidth * current.userZoom * current.userZoom / zoomableSteps);
| |
- | current.userTranslateY =
| |
- | maxAbs(current.userTranslateY - direction * y / current.zoomOriginWindowScale / zoomableSteps,
| |
- | halfHeight * current.userZoom * current.userZoom / zoomableSteps);
| |
- |
| |
- | $(this).jmpress("reselect", "zoom");
| |
- | }
| |
- | $.jmpress("register", "zoomIn", function(x, y) {
| |
- | zoom.call(this, x||0, y||0, 1);
| |
- | });
| |
- | $.jmpress("register", "zoomOut", function(x, y) {
| |
- | zoom.call(this, x||0, y||0, -1);
| |
- | });
| |
- | $.jmpress("register", "zoomTranslate", function(x, y) {
| |
- | var current = $(this).jmpress("current"),
| |
- | settings = $(this).jmpress("settings"),
| |
- | stepData = $(this).jmpress("active").data("stepData"),
| |
- | container = $(this).jmpress("container");
| |
- | var zoomableSteps = stepData.viewPortZoomable || settings.viewPort.zoomable;
| |
- | var halfWidth = $(container).innerWidth(),
| |
- | halfHeight = $(container).innerHeight();
| |
- | current.userTranslateX =
| |
- | maxAbs(current.userTranslateX + x / current.zoomOriginWindowScale,
| |
- | halfWidth * current.userZoom * current.userZoom / zoomableSteps);
| |
- | current.userTranslateY =
| |
- | maxAbs(current.userTranslateY + y / current.zoomOriginWindowScale,
| |
- | halfHeight * current.userZoom * current.userZoom / zoomableSteps);
| |
- | $(this).jmpress("reselect", "zoom");
| |
- | });
| |
- | $.jmpress('afterDeinit', function( nil, eventData ) {
| |
- | $(window).unbind(eventData.current.viewPortNamespace);
| |
- | });
| |
- | $.jmpress("setActive", function( step, eventData ) {
| |
- | var viewPort = eventData.settings.viewPort;
| |
- | var viewPortHeight = eventData.stepData.viewPortHeight || viewPort.height;
| |
- | var viewPortWidth = eventData.stepData.viewPortWidth || viewPort.width;
| |
- | var viewPortMaxScale = eventData.stepData.viewPortMaxScale || viewPort.maxScale;
| |
- | var viewPortMinScale = eventData.stepData.viewPortMinScale || viewPort.minScale;
| |
- | // Correct the scale based on the window's size
| |
- | var windowScaleY = viewPortHeight && $(eventData.container).innerHeight()/viewPortHeight;
| |
- | var windowScaleX = viewPortWidth && $(eventData.container).innerWidth()/viewPortWidth;
| |
- | var windowScale = (windowScaleX || windowScaleY) && Math.min( windowScaleX || windowScaleY, windowScaleY || windowScaleX );
| |
- |
| |
- | if(windowScale) {
| |
- | windowScale = windowScale || 1;
| |
- | if(viewPortMaxScale) {
| |
- | windowScale = Math.min(windowScale, viewPortMaxScale);
| |
- | }
| |
- | if(viewPortMinScale) {
| |
- | windowScale = Math.max(windowScale, viewPortMinScale);
| |
- | }
| |
- |
| |
- | var zoomableSteps = eventData.stepData.viewPortZoomable || eventData.settings.viewPort.zoomable;
| |
- | if(zoomableSteps) {
| |
- | var diff = (1/windowScale) - (1/viewPortMaxScale);
| |
- | diff /= zoomableSteps;
| |
- | windowScale = 1/((1/windowScale) - diff * eventData.current.userZoom);
| |
- | }
| |
- |
| |
- | eventData.target.transform.reverse();
| |
- | if(eventData.current.userTranslateX && eventData.current.userTranslateY) {
| |
- | eventData.target.transform.push(["translate", eventData.current.userTranslateX, eventData.current.userTranslateY, 0]);
| |
- | } else {
| |
- | eventData.target.transform.push(["translate"]);
| |
- | }
| |
- | eventData.target.transform.push(["scale",
| |
- | windowScale,
| |
- | windowScale,
| |
- | 1]);
| |
- | eventData.target.transform.reverse();
| |
- | }
| |
- | eventData.current.zoomOriginWindowScale = windowScale;
| |
- | });
| |
- | $.jmpress("setInactive", function( step, eventData ) {
| |
- | if(!eventData.nextStep || !step || $(eventData.nextStep).attr("id") !== $(step).attr("id")) {
| |
- | eventData.current.userZoom = 0;
| |
- | eventData.current.userTranslateX = 0;
| |
- | eventData.current.userTranslateY = 0;
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * mouse.js
| |
- | * Clicking to select a step
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | /* DEFAULTS */
| |
- | $jmpress("defaults").mouse = {
| |
- | clickSelects: true
| |
- | };
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress("afterInit", function( nil, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | stepSelector = settings.stepSelector,
| |
- | current = eventData.current,
| |
- | jmpress = $(this);
| |
- | current.clickableStepsNamespace = ".jmpress-"+randomString();
| |
- | jmpress.bind("click"+current.clickableStepsNamespace, function(event) {
| |
- | if (!settings.mouse.clickSelects || current.userZoom) {
| |
- | return;
| |
- | }
| |
- |
| |
- | // get clicked step
| |
- | var clickedStep = $(event.target).closest(stepSelector);
| |
- |
| |
- | // clicks on the active step do default
| |
- | if ( clickedStep.is( jmpress.jmpress("active") ) ) {
| |
- | return;
| |
- | }
| |
- |
| |
- | if (clickedStep.length) {
| |
- | // select the clicked step
| |
- | jmpress.jmpress("select", clickedStep[0], "click");
| |
- | event.preventDefault();
| |
- | event.stopPropagation();
| |
- | }
| |
- | });
| |
- | });
| |
- | $jmpress('afterDeinit', function( nil, eventData ) {
| |
- | $(this).unbind(eventData.current.clickableStepsNamespace);
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * mobile.js
| |
- | * Adds support for swipe on touch supported browsers
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress;
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress( 'afterInit', function( step, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | current = eventData.current,
| |
- | jmpress = eventData.jmpress;
| |
- | current.mobileNamespace = ".jmpress-"+randomString();
| |
- | var data, start = [0,0];
| |
- | $(settings.fullscreen ? document : jmpress)
| |
- | .bind("touchstart"+current.mobileNamespace, function( event ) {
| |
- |
| |
- | data = event.originalEvent.touches[0];
| |
- | start = [ data.pageX, data.pageY ];
| |
- |
| |
- | }).bind("touchmove"+current.mobileNamespace, function( event ) {
| |
- | data = event.originalEvent.touches[0];
| |
- | event.preventDefault();
| |
- | return false;
| |
- | }).bind("touchend"+current.mobileNamespace, function( event ) {
| |
- | var end = [ data.pageX, data.pageY ],
| |
- | diff = [ end[0]-start[0], end[1]-start[1] ];
| |
- |
| |
- | if(Math.max(Math.abs(diff[0]), Math.abs(diff[1])) > 50) {
| |
- | diff = Math.abs(diff[0]) > Math.abs(diff[1]) ? diff[0] : diff[1];
| |
- | $(jmpress).jmpress(diff > 0 ? "prev" : "next");
| |
- | event.preventDefault();
| |
- | return false;
| |
- | }
| |
- | });
| |
- | });
| |
- | $jmpress('afterDeinit', function( nil, eventData ) {
| |
- | var settings = eventData.settings,
| |
- | current = eventData.current,
| |
- | jmpress = eventData.jmpress;
| |
- | $(settings.fullscreen ? document : jmpress).unbind(current.mobileNamespace);
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * templates.js
| |
- | * The amazing template engine
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- | var $jmpress = $.jmpress,
| |
- | templateFromParentIdent = "_template_",
| |
- | templateFromApplyIdent = "_applied_template_";
| |
- |
| |
- | /* STATIC VARS */
| |
- | var templates = {};
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- | function addUndefined( target, values, prefix ) {
| |
- | for( var name in values ) {
| |
- | var targetName = name;
| |
- | if ( prefix ) {
| |
- | targetName = prefix + targetName.substr(0, 1).toUpperCase() + targetName.substr(1);
| |
- | }
| |
- | if ( $.isPlainObject(values[name]) ) {
| |
- | addUndefined( target, values[name], targetName );
| |
- | } else if( target[targetName] === undefined ) {
| |
- | target[targetName] = values[name];
| |
- | }
| |
- | }
| |
- | }
| |
- | function applyChildrenTemplates( children, templateChildren ) {
| |
- | if ($.isArray(templateChildren)) {
| |
- | if (templateChildren.length < children.length) {
| |
- | $.error("more nested steps than children in template");
| |
- | } else {
| |
- | children.each(function(idx, child) {
| |
- | child = $(child);
| |
- | var tmpl = child.data(templateFromParentIdent) || {};
| |
- | addUndefined(tmpl, templateChildren[idx]);
| |
- | child.data(templateFromParentIdent, tmpl);
| |
- | });
| |
- | }
| |
- | } else if($.isFunction(templateChildren)) {
| |
- | children.each(function(idx, child) {
| |
- | child = $(child);
| |
- | var tmpl = child.data(templateFromParentIdent) || {};
| |
- | addUndefined(tmpl, templateChildren(idx, child, children));
| |
- | child.data(templateFromParentIdent, tmpl);
| |
- | });
| |
- | } // TODO: else if(object)
| |
- | }
| |
- | function applyTemplate( data, element, template, eventData ) {
| |
- | if (template.children) {
| |
- | var children = element.children( eventData.settings.stepSelector );
| |
- | applyChildrenTemplates( children, template.children );
| |
- | }
| |
- | applyTemplateData( data, template );
| |
- | }
| |
- | function applyTemplateData( data, template ) {
| |
- | addUndefined(data, template);
| |
- | }
| |
- |
| |
- | /* HOOKS */
| |
- | $jmpress("beforeInitStep", function( step, eventData ) {
| |
- | step = $(step);
| |
- | var data = eventData.data,
| |
- | templateFromAttr = data.template,
| |
- | templateFromApply = step.data(templateFromApplyIdent),
| |
- | templateFromParent = step.data(templateFromParentIdent);
| |
- | if(templateFromAttr) {
| |
- | $.each(templateFromAttr.split(" "), function(idx, tmpl) {
| |
- | var template = templates[tmpl];
| |
- | applyTemplate( data, step, template, eventData );
| |
- | });
| |
- | }
| |
- | if (templateFromApply) {
| |
- | applyTemplate( data, step, templateFromApply, eventData );
| |
- | }
| |
- | if (templateFromParent) {
| |
- | applyTemplate( data, step, templateFromParent, eventData );
| |
- | step.data(templateFromParentIdent, null);
| |
- | if(templateFromParent.template) {
| |
- | $.each(templateFromParent.template.split(" "), function(idx, tmpl) {
| |
- | var template = templates[tmpl];
| |
- | applyTemplate( data, step, template, eventData );
| |
- | });
| |
- | }
| |
- | }
| |
- | });
| |
- | $jmpress("beforeInit", function( nil, eventData ) {
| |
- | var data = $jmpress("dataset", this),
| |
- | dataTemplate = data.template,
| |
- | stepSelector = eventData.settings.stepSelector;
| |
- | if (dataTemplate) {
| |
- | var template = templates[dataTemplate];
| |
- | applyChildrenTemplates( $(this).find(stepSelector).filter(function() {
| |
- | return !$(this).parent().is(stepSelector);
| |
- | }), template.children );
| |
- | }
| |
- | });
| |
- |
| |
- | /* EXPORTED FUNCTIONS */
| |
- | $jmpress("register", "template", function( name, tmpl ) {
| |
- | if (templates[name]) {
| |
- | templates[name] = $.extend(true, {}, templates[name], tmpl);
| |
- | } else {
| |
- | templates[name] = $.extend(true, {}, tmpl);
| |
- | }
| |
- | });
| |
- | $jmpress("register", "apply", function( selector, tmpl ) {
| |
- | if( !tmpl ) {
| |
- | // TODO ERROR because settings not found
| |
- | var stepSelector = $(this).jmpress("settings").stepSelector;
| |
- | applyChildrenTemplates( $(this).find(stepSelector).filter(function() {
| |
- | return !$(this).parent().is(stepSelector);
| |
- | }), selector );
| |
- | } else if($.isArray(tmpl)) {
| |
- | applyChildrenTemplates( $(selector), tmpl );
| |
- | } else {
| |
- | var template;
| |
- | if(typeof tmpl === "string") {
| |
- | template = templates[tmpl];
| |
- | } else {
| |
- | template = $.extend(true, {}, tmpl);
| |
- | }
| |
- | $(selector).each(function(idx, element) {
| |
- | element = $(element);
| |
- | var tmpl = element.data(templateFromApplyIdent) || {};
| |
- | addUndefined(tmpl, template);
| |
- | element.data(templateFromApplyIdent, tmpl);
| |
- | });
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * jqevents.js
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | /* FUNCTIONS */
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | /* HOOKS */
| |
- | // the events should not bubble up the tree
| |
- | // elsewise nested jmpress would cause buggy behavior
| |
- | $.jmpress("setActive", function( step, eventData ) {
| |
- | if(eventData.prevStep !== step) {
| |
- | $(step).triggerHandler("enterStep");
| |
- | }
| |
- | });
| |
- | $.jmpress("setInactive", function( step, eventData ) {
| |
- | if(eventData.nextStep !== step) {
| |
- | $(step).triggerHandler("leaveStep");
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |
- | /*!
| |
- | * animation.js
| |
- | * Apply custom animations to steps
| |
- | */
| |
- | (function( $, document, window, undefined ) {
| |
- |
| |
- | 'use strict';
| |
- |
| |
- | function randomString() {
| |
- | return "" + Math.round(Math.random() * 100000, 0);
| |
- | }
| |
- |
| |
- | function parseSubstepInfo(str) {
| |
- | var arr = str.split(" ");
| |
- | var className = arr[0];
| |
- | var config = { willClass: "will-"+className, doClass: "do-"+className, hasClass: "has-"+className };
| |
- | var state = "";
| |
- | for(var i = 1; i < arr.length; i++) {
| |
- | var s = arr[i];
| |
- | switch(state) {
| |
- | case "":
| |
- | if(s === "after") {
| |
- | state = "after";
| |
- | } else {
| |
- | $.warn("unknown keyword in '"+str+"'. '"+s+"' unknown.");
| |
- | }
| |
- | break;
| |
- | case "after":
| |
- | if(s.match(/^[1-9][0-9]*m?s?/)) {
| |
- | var value = parseFloat(s);
| |
- | if(s.indexOf("ms") !== -1) {
| |
- | value *= 1;
| |
- | } else if(s.indexOf("s") !== -1) {
| |
- | value *= 1000;
| |
- | } else if(s.indexOf("m") !== -1) {
| |
- | value *= 60000;
| |
- | }
| |
- | config.delay = value;
| |
- | } else {
| |
- | config.after = Array.prototype.slice.call(arr, i).join(" ");
| |
- | }
| |
- | }
| |
- | }
| |
- | return config;
| |
- | }
| |
- | function find(array, selector, start, end) {
| |
- | end = end || (array.length - 1);
| |
- | start = start || 0;
| |
- | for(var i = start; i < end + 1; i++) {
| |
- | if($(array[i].element).is(selector)) {
| |
- | return i;
| |
- | }
| |
- | }
| |
- | }
| |
- | function addOn(list, substep, delay) {
| |
- | $.each(substep._on, function(idx, child) {
| |
- | list.push({substep: child.substep, delay: child.delay + delay});
| |
- | addOn(list, child.substep, child.delay + delay);
| |
- | });
| |
- | }
| |
- | $.jmpress("defaults").customAnimationDataAttribute = "jmpress";
| |
- | $.jmpress("afterInit", function( nil, eventData ) {
| |
- | eventData.current.animationTimeouts = [];
| |
- | eventData.current.animationCleanupWaiting = [];
| |
- | });
| |
- | $.jmpress("applyStep", function( step, eventData ) {
| |
- | // read custom animation from elements
| |
- | var substepsData = {};
| |
- | var listOfSubsteps = [];
| |
- | $(step).find("[data-"+eventData.settings.customAnimationDataAttribute+"]")
| |
- | .each(function(idx, element) {
| |
- | if($(element).closest(eventData.settings.stepSelector).is(step)) {
| |
- | listOfSubsteps.push({element: element});
| |
- | }
| |
- | });
| |
- | if(listOfSubsteps.length === 0) {
| |
- | return;
| |
- | }
| |
- | $.each(listOfSubsteps, function(idx, substep) {
| |
- | substep.info = parseSubstepInfo(
| |
- | $(substep.element).data(eventData.settings.customAnimationDataAttribute));
| |
- | $(substep.element).addClass(substep.info.willClass);
| |
- | substep._on = [];
| |
- | substep._after = null;
| |
- | });
| |
- | var current = {_after: undefined, _on: [], info: {}}; // virtual zero step
| |
- | $.each(listOfSubsteps, function(idx, substep) {
| |
- | var other = substep.info.after;
| |
- | if(other) {
| |
- | if(other === "step") {
| |
- | other = current;
| |
- | } else if(other === "prev") {
| |
- | other = listOfSubsteps[idx-1];
| |
- | } else {
| |
- | var index = find(listOfSubsteps, other, 0, idx - 1);
| |
- | if(index === -1) {
| |
- | index = find(listOfSubsteps, other);
| |
- | }
| |
- | other = (index === -1 || index === idx) ? listOfSubsteps[idx-1] : listOfSubsteps[index];
| |
- | }
| |
- | } else {
| |
- | other = listOfSubsteps[idx-1];
| |
- | }
| |
- | if(other) {
| |
- | if(!substep.info.delay) {
| |
- | if(!other._after) {
| |
- | other._after = substep;
| |
- | return;
| |
- | }
| |
- | other = other._after;
| |
- | }
| |
- | other._on.push({substep: substep, delay: substep.info.delay || 0});
| |
- | }
| |
- | });
| |
- | if(current._after === undefined && current._on.length === 0) {
| |
- | var startStep = find(listOfSubsteps, eventData.stepData.startSubstep) || 0;
| |
- | current._after = listOfSubsteps[startStep];
| |
- | }
| |
- | var substepsInOrder = [];
| |
- | function findNextFunc(idx, item) {
| |
- | if(item.substep._after) {
| |
- | current = item.substep._after;
| |
- | return false;
| |
- | }
| |
- | }
| |
- | do {
| |
- | var substepList = [{substep: current, delay: 0}];
| |
- | addOn(substepList, current, 0);
| |
- | substepsInOrder.push(substepList);
| |
- | current = null;
| |
- | $.each(substepList, findNextFunc);
| |
- | } while(current);
| |
- | substepsData.list = substepsInOrder;
| |
- | $(step).data("substepsData", substepsData);
| |
- | });
| |
- | $.jmpress("unapplyStep", function( step, eventData ) {
| |
- | var substepsData = $(step).data("substepsData");
| |
- | if(substepsData) {
| |
- | $.each(substepsData.list, function(idx, activeSubsteps) {
| |
- | $.each(activeSubsteps, function(idx, substep) {
| |
- | if(substep.substep.info.willClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.willClass);
| |
- | }
| |
- | if(substep.substep.info.hasClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.hasClass);
| |
- | }
| |
- | if(substep.substep.info.doClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.doClass);
| |
- | }
| |
- | });
| |
- | });
| |
- | }
| |
- | });
| |
- | $.jmpress("setActive", function(step, eventData) {
| |
- | var substepsData = $(step).data("substepsData");
| |
- | if(!substepsData) {
| |
- | return;
| |
- | }
| |
- | if(eventData.substep === undefined) {
| |
- | eventData.substep =
| |
- | (eventData.reason === "prev" ?
| |
- | substepsData.list.length-1 :
| |
- | 0
| |
- | );
| |
- | }
| |
- | var substep = eventData.substep;
| |
- | $.each(eventData.current.animationTimeouts, function(idx, timeout) {
| |
- | clearTimeout(timeout);
| |
- | });
| |
- | eventData.current.animationTimeouts = [];
| |
- | $.each(substepsData.list, function(idx, activeSubsteps) {
| |
- | var applyHas = idx < substep;
| |
- | var applyDo = idx <= substep;
| |
- | $.each(activeSubsteps, function(idx, substep) {
| |
- | if(substep.substep.info.hasClass) {
| |
- | $(substep.substep.element)[(applyHas?"add":"remove")+"Class"](substep.substep.info.hasClass);
| |
- | }
| |
- | function applyIt() {
| |
- | $(substep.substep.element).addClass(substep.substep.info.doClass);
| |
- | }
| |
- | if(applyDo && !applyHas && substep.delay && eventData.reason !== "prev") {
| |
- | if(substep.substep.info.doClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.doClass);
| |
- | eventData.current.animationTimeouts.push(setTimeout(applyIt, substep.delay));
| |
- | }
| |
- | } else {
| |
- | if(substep.substep.info.doClass) {
| |
- | $(substep.substep.element)[(applyDo?"add":"remove")+"Class"](substep.substep.info.doClass);
| |
- | }
| |
- | }
| |
- | });
| |
- | });
| |
- | });
| |
- | $.jmpress("setInactive", function(step, eventData) {
| |
- | if(eventData.nextStep === step) {
| |
- | return;
| |
- | }
| |
- | function cleanupAnimation( substepsData ) {
| |
- | $.each(substepsData.list, function(idx, activeSubsteps) {
| |
- | $.each(activeSubsteps, function(idx, substep) {
| |
- | if(substep.substep.info.hasClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.hasClass);
| |
- | }
| |
- | if(substep.substep.info.doClass) {
| |
- | $(substep.substep.element).removeClass(substep.substep.info.doClass);
| |
- | }
| |
- | });
| |
- | });
| |
- | }
| |
- | $.each(eventData.current.animationCleanupWaiting, function(idx, item) {
| |
- | cleanupAnimation(item);
| |
- | });
| |
- | eventData.current.animationCleanupWaiting = [];
| |
- | var substepsData = $(step).data("substepsData");
| |
- | if(substepsData) {
| |
- | eventData.current.animationCleanupWaiting.push( substepsData );
| |
- | }
| |
- | });
| |
- | $.jmpress("selectNext", function( step, eventData ) {
| |
- | if(eventData.substep === undefined) {
| |
- | return;
| |
- | }
| |
- | var substepsData = $(step).data("substepsData");
| |
- | if(!substepsData) {
| |
- | return;
| |
- | }
| |
- | if(eventData.substep < substepsData.list.length-1) {
| |
- | return {step: step, substep: eventData.substep+1};
| |
- | }
| |
- | });
| |
- | $.jmpress("selectPrev", function( step, eventData ) {
| |
- | if(eventData.substep === undefined) {
| |
- | return;
| |
- | }
| |
- | var substepsData = $(step).data("substepsData");
| |
- | if(!substepsData) {
| |
- | return;
| |
- | }
| |
- | if(eventData.substep > 0) {
| |
- | return {step: step, substep: eventData.substep-1};
| |
- | }
| |
- | });
| |
- |
| |
- | }(jQuery, document, window));
| |