diff --git a/src/threesixty.js b/src/threesixty.js
index e27d7c1..ad74ddc 100644
--- a/src/threesixty.js
+++ b/src/threesixty.js
@@ -7,73 +7,29 @@
*
*/
(function($) {
- 'use strict';
- /**
- * @class ThreeSixty
- * **The ThreeSixty slider class**.
- *
- * This as jQuery plugin to create 360 degree product image slider.
- * The plugin is full customizable with number of options provided. The plugin
- * have the power to display images in any angle 360 degrees. This feature can be
- * used successfully in many use cases e.g. on an e-commerce site to help customers
- * look products in detail, from any angle they desire.
- *
- * **Features**
- *
- * - Smooth Animation
- * - Plenty of option parameters for customization
- * - Api interaction
- * - Simple mouse interaction
- * - Custom behavior tweaking
- * - Support for touch devices
- * - Easy to integrate
- * - No flash
- *
- * Example code:
- * var product1 = $('.product1').ThreeSixty({
- * totalFrames: 72,
- * endFrame: 72,
- * currentFrame: 1,
- * imgList: '.threesixty_images',
- * progress: '.spinner',
- * imagePath:'/assets/product1/',
- * filePrefix: 'ipod-',
- * ext: '.jpg',
- * height: 265,
- * width: 400,
- * navigation: true
- * });
- * **Note:** There are loads other options that you can override to customize
- * this plugin.
-
- * @extends jQuery
- * @singleton
- * @param {String} [el] jQuery selector string for the parent container
- * @param {Object} [options] An optional config object
- *
- * @return this
- */
- $.ThreeSixty = function(el, options) {
- // To avoid scope issues, use 'base' instead of 'this'
- // to reference this class from internal events and functions.
- var base = this,
- AppConfig, frames = [],
- VERSION = '2.0.5';
- // Access to jQuery and DOM versions of element
- /**
- * @property {$el}
- * jQuery Dom node attached to the slider inherits all jQuery public functions.
- */
- base.$el = $(el);
- base.el = el;
- // Add a reverse reference to the DOM object
- base.$el.data('ThreeSixty', base);
+ 'use strict';
/**
- * @method init
- * The function extends the user options with default settings for the
- * slider and initilize the slider.
- * **Style Override example**
+ * @class ThreeSixty
+ * **The ThreeSixty slider class**.
+ *
+ * This as jQuery plugin to create 360 degree product image slider.
+ * The plugin is full customizable with number of options provided. The plugin
+ * have the power to display images in any angle 360 degrees. This feature can be
+ * used successfully in many use cases e.g. on an e-commerce site to help customers
+ * look products in detail, from any angle they desire.
*
+ * **Features**
+ *
+ * - Smooth Animation
+ * - Plenty of option parameters for customization
+ * - Api interaction
+ * - Simple mouse interaction
+ * - Custom behavior tweaking
+ * - Support for touch devices
+ * - Easy to integrate
+ * - No flash
+ *
+ * Example code:
* var product1 = $('.product1').ThreeSixty({
* totalFrames: 72,
* endFrame: 72,
@@ -85,806 +41,888 @@
* ext: '.jpg',
* height: 265,
* width: 400,
- * navigation: true,
- * styles: {
- * border: 2px solide #b4b4b4,
- * background: url(http://example.com/images/loader.gif) no-repeat
- * }
+ * navigation: true
* });
- */
- base.init = function() {
- AppConfig = $.extend({}, $.ThreeSixty.defaultOptions, options);
- if(AppConfig.disableSpin) {
- AppConfig.currentFrame = 1;
- AppConfig.endFrame = 1;
- }
- base.initProgress();
- base.loadImages();
- };
-
- /*
- * Function to resize the height of responsive slider.
- */
- base.resize = function() {
- // calculate height
- };
- /**
- * @method initProgress
- * The function sets initial styles and start the progress indicator
- * to show loading of images.
+ * **Note:** There are loads other options that you can override to customize
+ * this plugin.
+
+ * @extends jQuery
+ * @singleton
+ * @param {String} [el] jQuery selector string for the parent container
+ * @param {Object} [options] An optional config object
*
- * @private
- */
- base.initProgress = function() {
- base.$el.css({
- width: AppConfig.width + 'px',
- height: AppConfig.height + 'px',
- 'background-image': 'none !important'
- });
- if(AppConfig.styles) {
- base.$el.css(AppConfig.styles);
- }
-
- base.responsive();
-
- base.$el.find(AppConfig.progress).css({
- marginTop: ((AppConfig.height / 2) - 15) + 'px'
- });
- base.$el.find(AppConfig.progress).fadeIn('slow');
- base.$el.find(AppConfig.imgList).hide();
- };
-
- /**
- * @method loadImages
- * @private
- * The function asynchronously loads images and inject into the slider.
- */
- base.loadImages = function() {
- var li, imageName, image, host, baseIndex;
- li = document.createElement('li');
- baseIndex = AppConfig.zeroBased ? 0 : 1;
- imageName = !AppConfig.imgArray ?
- AppConfig.domain + AppConfig.imagePath + AppConfig.filePrefix + base.zeroPad((AppConfig.loadedImages + baseIndex)) + AppConfig.ext + ((base.browser.isIE()) ? '?' + new Date().getTime() : '') :
- AppConfig.imgArray[AppConfig.loadedImages];
- image = $('
').attr('src', imageName).addClass('previous-image').appendTo(li);
-
- frames.push(image);
-
- base.$el.find(AppConfig.imgList).append(li);
-
- $(image).load(function () {
- base.imageLoaded();
- });
- };
-
- /**
- * @method loadImages
- * @private
- * The function gets triggers once the image is loaded. We also update
- * the progress percentage in this function.
+ * @return this
*/
- base.imageLoaded = function () {
- AppConfig.loadedImages += 1;
- $(AppConfig.progress + ' span').text(Math.floor(AppConfig.loadedImages / AppConfig.totalFrames * 100) + '%');
- if (AppConfig.loadedImages >= AppConfig.totalFrames) {
+ $.ThreeSixty = function(el, options) {
+ // To avoid scope issues, use 'base' instead of 'this'
+ // to reference this class from internal events and functions.
+ var base = this,
+ AppConfig, frames = [],
+ VERSION = '2.0.5';
+ // Access to jQuery and DOM versions of element
+ /**
+ * @property {$el}
+ * jQuery Dom node attached to the slider inherits all jQuery public functions.
+ */
+ base.$el = $(el);
+ base.el = el;
+ // Add a reverse reference to the DOM object
+ base.$el.data('ThreeSixty', base);
+ /**
+ * @method init
+ * The function extends the user options with default settings for the
+ * slider and initilize the slider.
+ * **Style Override example**
+ *
+ * var product1 = $('.product1').ThreeSixty({
+ * totalFrames: 72,
+ * endFrame: 72,
+ * currentFrame: 1,
+ * imgList: '.threesixty_images',
+ * progress: '.spinner',
+ * imagePath:'/assets/product1/',
+ * filePrefix: 'ipod-',
+ * ext: '.jpg',
+ * height: 265,
+ * width: 400,
+ * navigation: true,
+ * styles: {
+ * border: 2px solide #b4b4b4,
+ * background: url(http://example.com/images/loader.gif) no-repeat
+ * }
+ * });
+ */
+ base.init = function() {
+ AppConfig = $.extend({}, $.ThreeSixty.defaultOptions, options);
if(AppConfig.disableSpin) {
- frames[0].removeClass('previous-image').addClass('current-image');
+ AppConfig.currentFrame = 1;
+ AppConfig.endFrame = 1;
}
- $(AppConfig.progress).fadeOut('slow', function () {
- $(this).hide();
- base.showImages();
- base.showNavigation();
- });
- } else {
+ base.initProgress();
base.loadImages();
- }
- };
-
- /**
- * @method loadImages
- * @private
- * This function is called when all the images are loaded.
- * **The function does following operations**
- * - Removes background image placeholder
- * - Displays the 360 images
- * - Initilizes mouse intraction events
- */
- base.showImages = function () {
- base.$el.find('.txtC').fadeIn();
- base.$el.find(AppConfig.imgList).fadeIn();
- base.ready = true;
- AppConfig.ready = true;
-
- if (AppConfig.drag) {
- base.initEvents();
- }
- base.refresh();
- base.initPlugins();
- AppConfig.onReady();
-
- setTimeout(function() { base.responsive(); }, 50);
- };
-
- /**
- * The function to initilize external plugin
- */
- base.initPlugins = function () {
- $.each(AppConfig.plugins, function(i, plugin) {
- if(typeof $[plugin] === 'function') {
- $[plugin].call(base, base.$el, AppConfig);
+ };
+
+ /*
+ * Function to resize the height of responsive slider.
+ */
+ base.resize = function() {
+ // calculate height
+ };
+ /**
+ * @method initProgress
+ * The function sets initial styles and start the progress indicator
+ * to show loading of images.
+ *
+ * @private
+ */
+ base.initProgress = function() {
+ base.$el.css({
+ width: AppConfig.width + 'px',
+ height: AppConfig.height + 'px',
+ 'background-image': 'none !important'
+ });
+ if(AppConfig.styles) {
+ base.$el.css(AppConfig.styles);
+ }
+
+ base.responsive();
+
+ base.$el.find(AppConfig.progress).css({
+ marginTop: ((AppConfig.height / 2) - 15) + 'px'
+ });
+ base.$el.find(AppConfig.progress).fadeIn('slow');
+ base.$el.find(AppConfig.imgList).hide();
+ };
+
+ /**
+ * @method loadImages
+ * @private
+ * The function asynchronously loads images and inject into the slider.
+ */
+ base.loadImages = function() {
+ var li, imageName, image, host, baseIndex;
+ li = document.createElement('li');
+ baseIndex = AppConfig.zeroBased ? 0 : 1;
+ imageName = !AppConfig.imgArray ?
+ AppConfig.domain + AppConfig.imagePath + AppConfig.filePrefix + base.zeroPad((AppConfig.loadedImages + baseIndex)) + AppConfig.ext + ((base.browser.isIE()) ? '?' + new Date().getTime() : '') :
+ AppConfig.imgArray[AppConfig.loadedImages];
+ image = $('
').attr('src', imageName).addClass('previous-image').appendTo(li);
+
+ frames.push(image);
+
+ base.$el.find(AppConfig.imgList).append(li);
+
+ // $(image).load(function () {
+ // base.imageLoaded();
+ // });
+
+ $(image).on('load', function(){
+ base.imageLoaded();
+ });
+ };
+
+ /**
+ * @method loadImages
+ * @private
+ * The function gets triggers once the image is loaded. We also update
+ * the progress percentage in this function.
+ */
+ base.imageLoaded = function () {
+ AppConfig.loadedImages += 1;
+ $(AppConfig.progress + ' span').text(Math.floor(AppConfig.loadedImages / AppConfig.totalFrames * 100) + '%');
+ if (AppConfig.loadedImages >= AppConfig.totalFrames) {
+ if(AppConfig.disableSpin) {
+ frames[0].removeClass('previous-image').addClass('current-image');
+ }
+ $(AppConfig.progress).fadeOut('slow', function () {
+ $(this).hide();
+ base.showImages();
+ base.showNavigation();
+ });
} else {
- throw new Error(plugin + ' not available.');
+ base.loadImages();
}
- });
- };
-
- /**
- * @method showNavigation
- * Creates a navigation panel if navigation is set to true in the
- * settings.
- */
- base.showNavigation = function() {
- if (AppConfig.navigation && !AppConfig.navigation_init) {
- var nav_bar, next, previous, play_stop;
-
- nav_bar = $('
').attr('class', 'nav_bar');
-
- next = $('').attr({
- 'href': '#',
- 'class': 'nav_bar_next'
- }).html('next');
-
- previous = $('').attr({
- 'href': '#',
- 'class': 'nav_bar_previous'
- }).html('previous');
-
- play_stop = $('').attr({
- 'href': '#',
- 'class': 'nav_bar_play'
- }).html('play');
-
- nav_bar.append(previous);
- nav_bar.append(play_stop);
- nav_bar.append(next);
-
- base.$el.prepend(nav_bar);
-
- next.bind('mousedown touchstart', base.next);
- previous.bind('mousedown touchstart', base.previous);
- play_stop.bind('mousedown touchstart', base.play_stop);
- AppConfig.navigation_init = true;
- }
- };
-
- /**
- * @method play_stop
- * @private
- * Function toggles the autoplay rotation of 360 slider
- * @param {Object} [event] jQuery events object.
- *
- */
-
- base.play_stop = function(event) {
- event.preventDefault();
-
- if (!AppConfig.autoplay) {
- AppConfig.autoplay = true;
- AppConfig.play = setInterval(base.moveToNextFrame, AppConfig.playSpeed);
- $(event.currentTarget).removeClass('nav_bar_play').addClass('nav_bar_stop');
- } else {
- AppConfig.autoplay = false;
- $(event.currentTarget).removeClass('nav_bar_stop').addClass('nav_bar_play');
- clearInterval(AppConfig.play);
- AppConfig.play = null;
- }
- };
-
- /**
- * @method next
- * Using this function you can rotate 360 to next 5 frames.
- * @param {Object} [event] jQuery events object.
- *
- */
-
- base.next = function(event) {
- if (event) { event.preventDefault(); }
- AppConfig.endFrame -= 5;
- base.refresh();
- };
-
- /**
- * @method previous
- * Using this function you can rotate 360 to previous 5 frames.
- * @param {Object} [event] jQuery events object.
- *
- */
- base.previous = function(event) {
- if (event) { event.preventDefault(); }
- AppConfig.endFrame += 5;
- base.refresh();
- };
-
- /**
- * @method play
- * You are start the auto rotaion for the slider with this function.
- *
- */
- base.play = function(speed, direction) {
- var _speed = speed || AppConfig.playSpeed;
- var _direction = direction || AppConfig.autoplayDirection;
- AppConfig.autoplayDirection = _direction
-
- if (!AppConfig.autoplay) {
- AppConfig.autoplay = true;
- AppConfig.play = setInterval(base.moveToNextFrame, _speed);
- }
- };
-
- /**
- * @method stop
- * You can stop the auto rotation of the 360 slider with this function.
- *
- */
-
- base.stop = function() {
- if (AppConfig.autoplay) {
- AppConfig.autoplay = false;
- clearInterval(AppConfig.play);
- AppConfig.play = null;
- }
- };
-
- /**
- * @method endFrame
- * @private
- * Function animates to previous frame
- *
- */
- base.moveToNextFrame = function () {
- if (AppConfig.autoplayDirection === 1) {
- AppConfig.endFrame -= 1;
- } else {
- AppConfig.endFrame += 1;
- }
- base.refresh();
- };
-
- /**
- * @method gotoAndPlay
- * @public
- * Function animates to previous frame
- *
- */
- base.gotoAndPlay = function (n) {
- if( AppConfig.disableWrap ) {
- AppConfig.endFrame = n;
- base.refresh();
- } else {
- // Since we could be looped around grab the multiplier
- var multiplier = Math.ceil(AppConfig.endFrame / AppConfig.totalFrames);
- if(multiplier === 0) {
- multiplier = 1;
+ };
+
+ /**
+ * @method loadImages
+ * @private
+ * This function is called when all the images are loaded.
+ * **The function does following operations**
+ * - Removes background image placeholder
+ * - Displays the 360 images
+ * - Initilizes mouse intraction events
+ */
+ base.showImages = function () {
+ base.$el.find('.txtC').fadeIn();
+ base.$el.find(AppConfig.imgList).fadeIn();
+ base.ready = true;
+ AppConfig.ready = true;
+
+ if (AppConfig.drag) {
+ base.initEvents();
}
-
- // Figure out the quickest path to the requested frame
- var realEndFrame = (multiplier > 1) ?
- AppConfig.endFrame - ((multiplier - 1) * AppConfig.totalFrames) :
- AppConfig.endFrame;
-
- var currentFromEnd = AppConfig.totalFrames - realEndFrame;
-
- // Jump past end if it's faster
- var newEndFrame = 0;
- if(n - realEndFrame > 0) {
- // Faster to move the difference ahead?
- if(n - realEndFrame < realEndFrame + (AppConfig.totalFrames - n)) {
- newEndFrame = AppConfig.endFrame + (n - realEndFrame);
+ base.refresh();
+ base.initPlugins();
+ AppConfig.onReady();
+
+ setTimeout(function() { base.responsive(); }, 50);
+ };
+
+ /**
+ * The function to initilize external plugin
+ */
+ base.initPlugins = function () {
+ $.each(AppConfig.plugins, function(i, plugin) {
+ if(typeof $[plugin] === 'function') {
+ $[plugin].call(base, base.$el, AppConfig);
} else {
- newEndFrame = AppConfig.endFrame - (realEndFrame + (AppConfig.totalFrames - n));
+ throw new Error(plugin + ' not available.');
}
+ });
+ };
+
+ /**
+ * @method showNavigation
+ * Creates a navigation panel if navigation is set to true in the
+ * settings.
+ */
+ base.showNavigation = function() {
+ if (AppConfig.navigation && !AppConfig.navigation_init) {
+ var nav_bar, next, previous, play_stop;
+
+ nav_bar = $('').attr('class', 'nav_bar');
+
+ next = $('').attr({
+ 'href': '#',
+ 'class': 'nav_bar_next'
+ }).html('next');
+
+ previous = $('').attr({
+ 'href': '#',
+ 'class': 'nav_bar_previous'
+ }).html('previous');
+
+ play_stop = $('').attr({
+ 'href': '#',
+ 'class': 'nav_bar_play'
+ }).html('play');
+
+ nav_bar.append(previous);
+ nav_bar.append(play_stop);
+ nav_bar.append(next);
+
+ base.$el.prepend(nav_bar);
+
+ next.bind('mousedown touchstart', base.next);
+ previous.bind('mousedown touchstart', base.previous);
+ play_stop.bind('mousedown touchstart', base.play_stop);
+ AppConfig.navigation_init = true;
+ }
+ };
+
+ /**
+ * @method play_stop
+ * @private
+ * Function toggles the autoplay rotation of 360 slider
+ * @param {Object} [event] jQuery events object.
+ *
+ */
+
+ base.play_stop = function(event) {
+ event.preventDefault();
+
+ if (!AppConfig.autoplay) {
+ AppConfig.autoplay = true;
+ AppConfig.play = setInterval(base.moveToNextFrame, AppConfig.playSpeed);
+ $(event.currentTarget).removeClass('nav_bar_play').addClass('nav_bar_stop');
} else {
- // Faster to move the distance back?
- if(realEndFrame - n < currentFromEnd + n) {
- newEndFrame = AppConfig.endFrame - (realEndFrame - n);
- } else {
- newEndFrame = AppConfig.endFrame + (currentFromEnd + n);
- }
+ AppConfig.autoplay = false;
+ $(event.currentTarget).removeClass('nav_bar_stop').addClass('nav_bar_play');
+ clearInterval(AppConfig.play);
+ AppConfig.play = null;
}
-
- // Now set the end frame
- if(realEndFrame !== n) {
- AppConfig.endFrame = newEndFrame;
- base.refresh();
+ };
+
+ /**
+ * @method next
+ * Using this function you can rotate 360 to next 5 frames.
+ * @param {Object} [event] jQuery events object.
+ *
+ */
+
+ base.next = function(event) {
+ if (event) { event.preventDefault(); }
+ AppConfig.endFrame -= 5;
+ base.refresh();
+ };
+
+ /**
+ * @method previous
+ * Using this function you can rotate 360 to previous 5 frames.
+ * @param {Object} [event] jQuery events object.
+ *
+ */
+ base.previous = function(event) {
+ if (event) { event.preventDefault(); }
+ AppConfig.endFrame += 5;
+ base.refresh();
+ };
+
+ /**
+ * @method play
+ * You are start the auto rotaion for the slider with this function.
+ *
+ */
+ base.play = function(speed, direction) {
+ var _speed = speed || AppConfig.playSpeed;
+ var _direction = direction || AppConfig.autoplayDirection;
+ AppConfig.autoplayDirection = _direction
+
+ if (!AppConfig.autoplay) {
+ AppConfig.autoplay = true;
+ AppConfig.play = setInterval(base.moveToNextFrame, _speed);
}
- }
- };
-
-
- /**
- * @method initEvents
- * @private
- * Function initilizes all the mouse and touch events for 360 slider movement.
- *
- */
- base.initEvents = function () {
- base.$el.bind('mousedown touchstart touchmove touchend mousemove click', function (event) {
-
- event.preventDefault();
-
- if ((event.type === 'mousedown' && event.which === 1) || event.type === 'touchstart') {
- AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;
- AppConfig.dragging = true;
- AppConfig.onDragStart(AppConfig.currentFrame);
- } else if (event.type === 'touchmove') {
- base.trackPointer(event);
- } else if (event.type === 'touchend') {
- AppConfig.dragging = false;
- AppConfig.onDragStop(AppConfig.endFrame);
+ };
+
+ /**
+ * @method stop
+ * You can stop the auto rotation of the 360 slider with this function.
+ *
+ */
+
+ base.stop = function() {
+ if (AppConfig.autoplay) {
+ AppConfig.autoplay = false;
+ clearInterval(AppConfig.play);
+ AppConfig.play = null;
}
- });
-
- $(document).bind('mouseup', function (event) {
- AppConfig.dragging = false;
- AppConfig.onDragStop(AppConfig.endFrame);
- $(this).css('cursor', 'none');
- });
-
- $(window).bind('resize', function (event) {
- base.responsive();
- });
-
- $(document).bind('mousemove', function (event) {
- if (AppConfig.dragging) {
- event.preventDefault();
- if(!base.browser.isIE && AppConfig.showCursor) {
- base.$el.css('cursor', 'url(assets/images/hand_closed.png), auto');
- }
+ };
+
+ /**
+ * @method endFrame
+ * @private
+ * Function animates to previous frame
+ *
+ */
+ base.moveToNextFrame = function () {
+ if (AppConfig.autoplayDirection === 1) {
+ AppConfig.endFrame -= 1;
} else {
- if(!base.browser.isIE && AppConfig.showCursor) {
- base.$el.css('cursor', 'url(assets/images/hand_open.png), auto');
- }
+ AppConfig.endFrame += 1;
}
- base.trackPointer(event);
-
- });
-
- $(window).resize(function() {
- base.resize();
- });
- };
-
- /**
- * @method getPointerEvent
- * @private
- * Function returns touch pointer events
- *
- * @params {Object} [event]
- */
- base.getPointerEvent = function (event) {
- return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event;
- };
-
- /**
- * @method trackPointer
- * @private
- * Function calculates the distance between the start pointer and end pointer/
- *
- * @params {Object} [event]
- */
- base.trackPointer = function (event) {
- if (AppConfig.ready && AppConfig.dragging) {
- AppConfig.pointerEndPosX = base.getPointerEvent(event).pageX;
- if (AppConfig.monitorStartTime < new Date().getTime() - AppConfig.monitorInt) {
- AppConfig.pointerDistance = AppConfig.pointerEndPosX - AppConfig.pointerStartPosX;
- if(AppConfig.pointerDistance > 0){
- AppConfig.endFrame = AppConfig.currentFrame + Math.ceil((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));
- }else{
- AppConfig.endFrame = AppConfig.currentFrame + Math.floor((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));
- }
-
- if( AppConfig.disableWrap ) {
- AppConfig.endFrame = Math.min(AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0), AppConfig.endFrame);
- AppConfig.endFrame = Math.max((AppConfig.zeroBased ? 0 : 1), AppConfig.endFrame);
- }
+ base.refresh();
+ };
+
+ /**
+ * @method gotoAndPlay
+ * @public
+ * Function animates to previous frame
+ *
+ */
+ base.gotoAndPlay = function (n) {
+ if( AppConfig.disableWrap ) {
+ AppConfig.endFrame = n;
base.refresh();
- AppConfig.monitorStartTime = new Date().getTime();
- AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;
- }
- }
- };
-
- /**
- * @method refresh
- * @public
- * Function refeshes the timer and set interval for render cycle.
- *
- */
-
- base.refresh = function () {
- if (AppConfig.ticker === 0) {
- AppConfig.ticker = setInterval(base.render, Math.round(1000 / AppConfig.framerate));
- }
- };
-
- /**
- * @method refresh
- * @private
- * Function render the animation frames on the screen with easing effect.
- */
-
- base.render = function () {
- var frameEasing;
- if (AppConfig.currentFrame !== AppConfig.endFrame) {
- frameEasing = AppConfig.endFrame < AppConfig.currentFrame ? Math.floor((AppConfig.endFrame - AppConfig.currentFrame) * 0.1) : Math.ceil((AppConfig.endFrame - AppConfig.currentFrame) * 0.1);
- base.hidePreviousFrame();
- AppConfig.currentFrame += frameEasing;
- base.showCurrentFrame();
- base.$el.trigger('frameIndexChanged', [base.getNormalizedCurrentFrame(), AppConfig.totalFrames]);
- } else {
- window.clearInterval(AppConfig.ticker);
- AppConfig.ticker = 0;
- }
- };
-
- /**
- * @method hidePreviousFrame
- * @private
- * Function hide the previous frame in the animation loop.
- */
-
- base.hidePreviousFrame = function () {
- frames[base.getNormalizedCurrentFrame()].removeClass('current-image').addClass('previous-image');
- };
-
- /**
- * @method showCurrentFrame
- * @private
- * Function shows the current frame in the animation loop.
- */
- base.showCurrentFrame = function () {
- frames[base.getNormalizedCurrentFrame()].removeClass('previous-image').addClass('current-image');
- };
-
- /**
- * @method getNormalizedCurrentFrame
- * @private
- * Function normalize and calculate the current frame once the user release the mouse and release touch event.
- */
-
- base.getNormalizedCurrentFrame = function () {
- var c, e;
-
- if ( !AppConfig.disableWrap ) {
- c = Math.ceil(AppConfig.currentFrame % AppConfig.totalFrames);
- if (c < 0) {
- c += AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0);
- }
- } else {
- c = Math.min(AppConfig.currentFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));
- e = Math.min(AppConfig.endFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));
- c = Math.max(c, (AppConfig.zeroBased ? 0 : 1));
- e = Math.max(e, (AppConfig.zeroBased ? 0 : 1));
- AppConfig.currentFrame = c;
- AppConfig.endFrame = e;
- }
-
- return c;
- };
-
- /*
- * @method getCurrentFrame
- * Function returns the current active frame.
- *
- * @return Number
- */
-
- base.getCurrentFrame = function() {
- return AppConfig.currentFrame;
- };
-
- /*
- * @method responsive
- * Function calculates and set responsive height and width
- *
- */
-
- base.responsive = function() {
- if(AppConfig.responsive) {
- base.$el.css({
- height: base.$el.find('.current-image').first().css('height'),
- width: '100%'
- });
- }
- };
-
- /**
- * Function to return with zero padding.
- */
- base.zeroPad = function (num) {
- function pad(number, length) {
- var str = number.toString();
- if(AppConfig.zeroPadding) {
- while (str.length < length) {
- str = '0' + str;
+ } else {
+ // Since we could be looped around grab the multiplier
+ var multiplier = Math.ceil(AppConfig.endFrame / AppConfig.totalFrames);
+ if(multiplier === 0) {
+ multiplier = 1;
+ }
+
+ // Figure out the quickest path to the requested frame
+ var realEndFrame = (multiplier > 1) ?
+ AppConfig.endFrame - ((multiplier - 1) * AppConfig.totalFrames) :
+ AppConfig.endFrame;
+
+ var currentFromEnd = AppConfig.totalFrames - realEndFrame;
+
+ // Jump past end if it's faster
+ var newEndFrame = 0;
+ if(n - realEndFrame > 0) {
+ // Faster to move the difference ahead?
+ if(n - realEndFrame < realEndFrame + (AppConfig.totalFrames - n)) {
+ newEndFrame = AppConfig.endFrame + (n - realEndFrame);
+ } else {
+ newEndFrame = AppConfig.endFrame - (realEndFrame + (AppConfig.totalFrames - n));
}
+ } else {
+ // Faster to move the distance back?
+ if(realEndFrame - n < currentFromEnd + n) {
+ newEndFrame = AppConfig.endFrame - (realEndFrame - n);
+ } else {
+ newEndFrame = AppConfig.endFrame + (currentFromEnd + n);
+ }
+ }
+
+ // Now set the end frame
+ if(realEndFrame !== n) {
+ AppConfig.endFrame = newEndFrame;
+ base.refresh();
}
- return str;
- }
-
- var approximateLog = Math.log(AppConfig.totalFrames) / Math.LN10;
- var roundTo = 1e3;
- var roundedLog = Math.round(approximateLog * roundTo) / roundTo;
- var numChars = Math.floor(roundedLog) + 1;
- return pad(num, numChars);
- };
-
- base.browser = {};
-
- /**
- * Function to detect if the brower is IE
- * @return {boolean}
- *
- * http://msdn.microsoft.com/en-gb/library/ms537509(v=vs.85).aspx
- */
- base.browser.isIE = function () {
- var rv = -1;
- if (navigator.appName === 'Microsoft Internet Explorer')
- {
- var ua = navigator.userAgent;
- var re = new RegExp('MSIE ([0-9]{1,}[\\.0-9]{0,})');
- if (re.exec(ua) !== null){
- rv = parseFloat( RegExp.$1 );
}
- }
-
- return rv !== -1;
- };
-
-
- /**
- * @method getConfig
- * The function returns the extended version of config object the plugin is going to
- * user.
- *
- * @public
- *
- * @return Object
- */
- base.getConfig = function() {
- return AppConfig;
- };
-
- $.ThreeSixty.defaultOptions = {
+ };
+
+
/**
- * @cfg {Boolean} dragging [dragging=false]
+ * @method initEvents
* @private
- * Private propery contains a flags if users is in dragging mode.
+ * Function initilizes all the mouse and touch events for 360 slider movement.
+ *
*/
- dragging: false,
+ base.initEvents = function () {
+ base.$el.bind('mousedown touchstart touchmove touchend mousemove click', function (event) {
+
+ event.preventDefault();
+
+ if ((event.type === 'mousedown' && event.which === 1) || event.type === 'touchstart') {
+ AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;
+ AppConfig.dragging = true;
+ AppConfig.onDragStart(AppConfig.currentFrame);
+ } else if (event.type === 'touchmove') {
+ base.trackPointer(event);
+ } else if (event.type === 'touchend') {
+ AppConfig.dragging = false;
+ AppConfig.onDragStop(AppConfig.endFrame);
+ }
+ });
+
+ $(document).bind('mouseup', function (event) {
+ AppConfig.dragging = false;
+ AppConfig.onDragStop(AppConfig.endFrame);
+ $(this).css('cursor', 'none');
+ });
+
+ $(window).bind('resize', function (event) {
+ base.responsive();
+ });
+
+ $(document).bind('mousemove', function (event) {
+ if (AppConfig.dragging) {
+ event.preventDefault();
+ if(!base.browser.isIE && AppConfig.showCursor) {
+ base.$el.css('cursor', 'url(assets/images/hand_closed.png), auto');
+ }
+ } else {
+ if(!base.browser.isIE && AppConfig.showCursor) {
+ base.$el.css('cursor', 'url(assets/images/hand_open.png), auto');
+ }
+ }
+ base.trackPointer(event);
+
+ });
+
+ $(window).resize(function() {
+ base.resize();
+ });
+ };
+
/**
- * @cfg {Boolean} ready [ready=false]
+ * @method getPointerEvent
* @private
- * Private propery is set to true is all assets are loading and application is
- * ready to render 360 slider.
+ * Function returns touch pointer events
+ *
+ * @params {Object} [event]
*/
- ready: false,
+ base.getPointerEvent = function (event) {
+ return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event;
+ };
+
/**
- * @cfg {Number} pointerStartPosX
+ * @method trackPointer
* @private
- * private property mouse pointer start x position when user starts dragging slider.
- */
- pointerStartPosX: 0,
- /**
- * @cfg {Number} pointerEndPosX
+ * Function calculates the distance between the start pointer and end pointer/
+ *
+ * @params {Object} [event]
+ */
+ base.trackPointer = function (event) {
+ if (AppConfig.ready && AppConfig.dragging) {
+ AppConfig.pointerEndPosX = base.getPointerEvent(event).pageX;
+ if (AppConfig.monitorStartTime < new Date().getTime() - AppConfig.monitorInt) {
+ AppConfig.pointerDistance = AppConfig.pointerEndPosX - AppConfig.pointerStartPosX;
+ if(AppConfig.pointerDistance > 0){
+ AppConfig.endFrame = AppConfig.currentFrame + Math.ceil((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));
+ }else{
+ AppConfig.endFrame = AppConfig.currentFrame + Math.floor((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));
+ }
+
+ if( AppConfig.disableWrap ) {
+ AppConfig.endFrame = Math.min(AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0), AppConfig.endFrame);
+ AppConfig.endFrame = Math.max((AppConfig.zeroBased ? 0 : 1), AppConfig.endFrame);
+ }
+ base.refresh();
+ AppConfig.monitorStartTime = new Date().getTime();
+ AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;
+ }
+ }
+ };
+
+ /**
+ * @method refresh
+ * @public
+ * Function refeshes the timer and set interval for render cycle.
+ *
+ */
+
+ base.refresh = function () {
+ if (AppConfig.ticker === 0) {
+ AppConfig.ticker = setInterval(base.render, Math.round(1000 / AppConfig.framerate));
+ }
+ };
+
+ /**
+ * @method refresh
* @private
- * private property mouse pointer start x position when user end dragging slider.
- */
- pointerEndPosX: 0,
+ * Function render the animation frames on the screen with easing effect.
+ */
+
+ base.render = function () {
+ var frameEasing;
+ if (AppConfig.currentFrame !== AppConfig.endFrame) {
+ frameEasing = AppConfig.endFrame < AppConfig.currentFrame ? Math.floor((AppConfig.endFrame - AppConfig.currentFrame) * 0.1) : Math.ceil((AppConfig.endFrame - AppConfig.currentFrame) * 0.1);
+ base.hidePreviousFrame();
+ AppConfig.currentFrame += frameEasing;
+ base.showCurrentFrame();
+ base.$el.trigger('frameIndexChanged', [base.getNormalizedCurrentFrame(), AppConfig.totalFrames]);
+ } else {
+ window.clearInterval(AppConfig.ticker);
+ AppConfig.ticker = 0;
+ }
+ };
+
/**
- * @cfg {Number} pointerDistance
+ * @method hidePreviousFrame
* @private
- * private property contains the distance between the pointerStartPosX and pointerEndPosX
+ * Function hide the previous frame in the animation loop.
*/
- pointerDistance: 0,
+
+ base.hidePreviousFrame = function () {
+ frames[base.getNormalizedCurrentFrame()].removeClass('current-image').addClass('previous-image');
+ };
+
/**
- * @cfg {Number} monitorStartTime
+ * @method showCurrentFrame
* @private
- * private property contains time user took in dragging mouse from pointerStartPosX and pointerEndPosX
+ * Function shows the current frame in the animation loop.
*/
- monitorStartTime: 0,
- monitorInt: 10,
+ base.showCurrentFrame = function () {
+ frames[base.getNormalizedCurrentFrame()].removeClass('previous-image').addClass('current-image');
+ };
+
/**
- * @cfg {Number} ticker
+ * @method getNormalizedCurrentFrame
* @private
- * Timer event that renders the 360
- */
- ticker: 0,
- /**
- * @cfg {Number} speedMultiplier
- * This property controls the sensitivity for the 360 slider
- */
- speedMultiplier: 7,
- /**
- * @cfg {Number} totalFrames
- * Set total number for frames used in the 360 rotation
- */
- totalFrames: 180,
- /**
- * @cfg {Number} currentFrame
- * Current frame of the slider.
- */
- currentFrame: 0,
- /**
- * @cfg {Array} endFrame
- * Private perperty contains information about the end frame when user slides the slider.
- */
- endFrame: 0,
- /**
- * @cfg {Number} loadedImages
- * Private property contains count of loaded images.
- */
- loadedImages: 0,
- /**
- * @cfg {Array} framerate
- * Set framerate for the slider animation
- */
- framerate: 60,
- /**
- * @cfg {String} domains
- * Set comma seprated list of all parallel domain from where 360 assets needs to be loaded.
- */
- domains: null,
- /**
- * @cfg {String} domain
- * Domain from where assets needs to be loaded. Use this propery is you want to load all assets from
- * single domain.
- */
- domain: '',
- /**
- * @cfg {Boolean} parallel
- * Set to true if you want to load assets from parallel domain. Default false
- */
- parallel: false,
- /**
- * @cfg {Number} queueAmount
- * Set number of calls to be made on parallel domains.
- */
- queueAmount: 8,
- /**
- * @cfg {Number} idle
- * Mouse Inactivite idle time in seconds. If set more than 0 will auto spine the slider
- */
- idle: 0,
- /**
- * @cfg {String} filePrefix
- * Prefix for the image file name before the numeric value.
- */
- filePrefix: '',
- /**
- * @cfg {String} ext [ext=.png]
- * Slider image extension.
- */
- ext: 'png',
- /**
- * @cfg {Object} height [300]
- * Height of the slider
- */
- height: 300,
- /**
- * @cfg {Number} width [300]
- * Width of the slider
- */
- width: 300,
- /**
- * @cfg {Object} styles
- * CSS Styles for the 360 slider
- */
- styles: {},
- /**
- * @cfg {Boolean} navigation[false]
- * State if navigation controls are visible or not.
- */
- navigation: false,
- /**
- * @cfg {Boolean} autoplay[false]
- * Autoplay the 360 animation
- */
- autoplay: false,
- /**
- * @cfg {number} autoplayDirection [1]
- * Direction for autoplay the 360 animation. 1 for right spin, and -1 for left spin.
- */
- autoplayDirection: 1,
- /**
- * Property to disable auto spin
- * @type {Boolean}
- */
- disableSpin: false,
- /**
- * Property to disable infinite wrap
- * @type {Boolean}
- */
- disableWrap: false,
- /**
- * Responsive width
- * @type {Boolean}
- */
- responsive: false,
- /**
- * Zero Padding for filenames
- * @type {Boolean}
- */
- zeroPadding: false,
- /**
- * Zero based for image filenames starting at 0
- * @type {Boolean}
- */
- zeroBased: false,
- /**
- * @type {Array}
- * List of plugins
- */
- plugins: [],
- /**
- * @type {Boolean}
- * Show hand cursor on drag
- */
- showCursor: false,
- /**
- * @cfg {Boolean} drag
- * Set it to false if you want to disable mousedrag or touch events
- */
- drag: true,
- /**
- * @cfg {Function} onReady
- * Callback triggers once all images are loaded and ready to render on the screen
- */
- onReady: function() {},
- /**
- * @cfg {Function} onDragStart
- * Callback triggers when a user initiates dragging
- */
- onDragStart: function() {},
- /**
- * @cfg {Function} onDragStop
- * Callback triggers when a user releases after dragging
- */
- onDragStop: function() {},
- /**
- * @cfg {String} imgList
- * Set ul element where image will be loaded
- */
- imgList: '.threesixty_images',
- /**
- * @cfg {Array} imgArray
- * Use set of images in array to load images
- */
- imgArray: null,
- /**
- * @cfg {Number} playSpeed
- * Value to control the speed of play button rotation
+ * Function normalize and calculate the current frame once the user release the mouse and release touch event.
+ */
+
+ base.getNormalizedCurrentFrame = function () {
+ var c, e;
+
+ if ( !AppConfig.disableWrap ) {
+ c = Math.ceil(AppConfig.currentFrame % AppConfig.totalFrames);
+ if (c < 0) {
+ c += AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0);
+ }
+ } else {
+ c = Math.min(AppConfig.currentFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));
+ e = Math.min(AppConfig.endFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));
+ c = Math.max(c, (AppConfig.zeroBased ? 0 : 1));
+ e = Math.max(e, (AppConfig.zeroBased ? 0 : 1));
+ AppConfig.currentFrame = c;
+ AppConfig.endFrame = e;
+ }
+
+ return c;
+ };
+
+ /*
+ * @method getCurrentFrame
+ * Function returns the current active frame.
+ *
+ * @return Number
+ */
+
+ base.getCurrentFrame = function() {
+ return AppConfig.currentFrame;
+ };
+
+ /*
+ * @method responsive
+ * Function calculates and set responsive height and width
+ *
*/
- playSpeed: 100
- };
- base.init();
- };
+
+ base.responsive = function() {
+ if(AppConfig.responsive) {
+ base.$el.css({
+ height: base.$el.find('.current-image').first().css('height'),
+ width: '100%'
+ });
+ }
+ };
+
+ /**
+ * Function to return with zero padding.
+ */
+ base.zeroPad = function (num) {
+ function pad(number, length) {
+ var str = number.toString();
+ if(AppConfig.zeroPadding) {
+ while (str.length < length) {
+ str = '0' + str;
+ }
+ }
+ return str;
+ }
+
+ var approximateLog = Math.log(AppConfig.totalFrames) / Math.LN10;
+ var roundTo = 1e3;
+ var roundedLog = Math.round(approximateLog * roundTo) / roundTo;
+ var numChars = Math.floor(roundedLog) + 1;
+ return pad(num, numChars);
+ };
+
+ base.browser = {};
+
+ /**
+ * Function to detect if the brower is IE
+ * @return {boolean}
+ *
+ * http://msdn.microsoft.com/en-gb/library/ms537509(v=vs.85).aspx
+ */
+ base.browser.isIE = function () {
+ var rv = -1;
+ if (navigator.appName === 'Microsoft Internet Explorer')
+ {
+ var ua = navigator.userAgent;
+ var re = new RegExp('MSIE ([0-9]{1,}[\\.0-9]{0,})');
+ if (re.exec(ua) !== null){
+ rv = parseFloat( RegExp.$1 );
+ }
+ }
+
+ return rv !== -1;
+ };
+
+
+ /**
+ * @method getConfig
+ * @method slow
+ * @method fast
+ * @method normal
+ * @method setOptions
+ * The function returns the extended version of config object the plugin is going to
+ * user.
+ *
+ * @public
+ *
+ * @return Object
+ */
+ base.getConfig = function() {
+ return AppConfig;
+ };
+
+ base.fast = function(){
+ if(AppConfig.playSpeed > 10)
+ AppConfig.playSpeed -= 10;
+ base.refresh();
+ }
- $.fn.ThreeSixty = function(options) {
- return Object.create(new $.ThreeSixty(this, options));
- };
-}(jQuery));
-/**
- *
- * Object.create method for perform as a fallback if method not available.
- * The syntax just takes away the illusion that JavaScript uses Classical Inheritance.
- */
-if(typeof Object.create !== 'function') {
- Object.create = function(o) {
- 'use strict';
+ base.normal = function(){
+ AppConfig.playSpeed = 100;
+ base.refresh();
+ }
- function F() {}
- F.prototype = o;
- return new F();
- };
-}
+ base.slow = function(){
+ if(AppConfig.playSpeed < 150)
+ AppConfig.playSpeed += 10;
+ base.refresh();
+ }
+
+ base.setOptions = function(option){
+ if(option.dir)
+ AppConfig.autoplayDirection = option.dir;
+
+ if(option.width)
+ AppConfig.width = option.width;
+
+ if(option.height)
+ AppConfig.height = option.height;
+
+ base.refresh();
+ }
+
+ $.ThreeSixty.defaultOptions = {
+ /**
+ * @cfg {Boolean} dragging [dragging=false]
+ * @private
+ * Private propery contains a flags if users is in dragging mode.
+ */
+ dragging: false,
+ /**
+ * @cfg {Boolean} ready [ready=false]
+ * @private
+ * Private propery is set to true is all assets are loading and application is
+ * ready to render 360 slider.
+ */
+ ready: false,
+ /**
+ * @cfg {Number} pointerStartPosX
+ * @private
+ * private property mouse pointer start x position when user starts dragging slider.
+ */
+ pointerStartPosX: 0,
+ /**
+ * @cfg {Number} pointerEndPosX
+ * @private
+ * private property mouse pointer start x position when user end dragging slider.
+ */
+ pointerEndPosX: 0,
+ /**
+ * @cfg {Number} pointerDistance
+ * @private
+ * private property contains the distance between the pointerStartPosX and pointerEndPosX
+ */
+ pointerDistance: 0,
+ /**
+ * @cfg {Number} monitorStartTime
+ * @private
+ * private property contains time user took in dragging mouse from pointerStartPosX and pointerEndPosX
+ */
+ monitorStartTime: 0,
+ monitorInt: 10,
+ /**
+ * @cfg {Number} ticker
+ * @private
+ * Timer event that renders the 360
+ */
+ ticker: 0,
+ /**
+ * @cfg {Number} speedMultiplier
+ * This property controls the sensitivity for the 360 slider
+ */
+ speedMultiplier: 7,
+ /**
+ * @cfg {Number} totalFrames
+ * Set total number for frames used in the 360 rotation
+ */
+ totalFrames: 180,
+ /**
+ * @cfg {Number} currentFrame
+ * Current frame of the slider.
+ */
+ currentFrame: 0,
+ /**
+ * @cfg {Array} endFrame
+ * Private perperty contains information about the end frame when user slides the slider.
+ */
+ endFrame: 0,
+ /**
+ * @cfg {Number} loadedImages
+ * Private property contains count of loaded images.
+ */
+ loadedImages: 0,
+ /**
+ * @cfg {Array} framerate
+ * Set framerate for the slider animation
+ */
+ framerate: 60,
+ /**
+ * @cfg {String} domains
+ * Set comma seprated list of all parallel domain from where 360 assets needs to be loaded.
+ */
+ domains: null,
+ /**
+ * @cfg {String} domain
+ * Domain from where assets needs to be loaded. Use this propery is you want to load all assets from
+ * single domain.
+ */
+ domain: '',
+ /**
+ * @cfg {Boolean} parallel
+ * Set to true if you want to load assets from parallel domain. Default false
+ */
+ parallel: false,
+ /**
+ * @cfg {Number} queueAmount
+ * Set number of calls to be made on parallel domains.
+ */
+ queueAmount: 8,
+ /**
+ * @cfg {Number} idle
+ * Mouse Inactivite idle time in seconds. If set more than 0 will auto spine the slider
+ */
+ idle: 0,
+ /**
+ * @cfg {String} filePrefix
+ * Prefix for the image file name before the numeric value.
+ */
+ filePrefix: '',
+ /**
+ * @cfg {String} ext [ext=.png]
+ * Slider image extension.
+ */
+ ext: 'png',
+ /**
+ * @cfg {Object} height [300]
+ * Height of the slider
+ */
+ height: 300,
+ /**
+ * @cfg {Number} width [300]
+ * Width of the slider
+ */
+ width: 300,
+ /**
+ * @cfg {Object} styles
+ * CSS Styles for the 360 slider
+ */
+ styles: {},
+ /**
+ * @cfg {Boolean} navigation[false]
+ * State if navigation controls are visible or not.
+ */
+ navigation: false,
+ /**
+ * @cfg {Boolean} autoplay[false]
+ * Autoplay the 360 animation
+ */
+ autoplay: false,
+ /**
+ * @cfg {number} autoplayDirection [1]
+ * Direction for autoplay the 360 animation. 1 for right spin, and -1 for left spin.
+ */
+ autoplayDirection: 1,
+ /**
+ * Property to disable auto spin
+ * @type {Boolean}
+ */
+ disableSpin: false,
+ /**
+ * Property to disable infinite wrap
+ * @type {Boolean}
+ */
+ disableWrap: false,
+ /**
+ * Responsive width
+ * @type {Boolean}
+ */
+ responsive: false,
+ /**
+ * Zero Padding for filenames
+ * @type {Boolean}
+ */
+ zeroPadding: false,
+ /**
+ * Zero based for image filenames starting at 0
+ * @type {Boolean}
+ */
+ zeroBased: false,
+ /**
+ * @type {Array}
+ * List of plugins
+ */
+ plugins: [],
+ /**
+ * @type {Boolean}
+ * Show hand cursor on drag
+ */
+ showCursor: false,
+ /**
+ * @cfg {Boolean} drag
+ * Set it to false if you want to disable mousedrag or touch events
+ */
+ drag: true,
+ /**
+ * @cfg {Function} onReady
+ * Callback triggers once all images are loaded and ready to render on the screen
+ */
+ onReady: function() {},
+ /**
+ * @cfg {Function} onDragStart
+ * Callback triggers when a user initiates dragging
+ */
+ onDragStart: function() {},
+ /**
+ * @cfg {Function} onDragStop
+ * Callback triggers when a user releases after dragging
+ */
+ onDragStop: function() {},
+ /**
+ * @cfg {String} imgList
+ * Set ul element where image will be loaded
+ */
+ imgList: '.threesixty_images',
+ /**
+ * @cfg {Array} imgArray
+ * Use set of images in array to load images
+ */
+ imgArray: null,
+ /**
+ * @cfg {Number} playSpeed
+ * Value to control the speed of play button rotation
+ */
+ playSpeed: 100
+ };
+ base.init();
+ };
+
+ $.fn.ThreeSixty = function(options) {
+ return Object.create(new $.ThreeSixty(this, options));
+ };
+ }(jQuery));
+ /**
+ *
+ * Object.create method for perform as a fallback if method not available.
+ * The syntax just takes away the illusion that JavaScript uses Classical Inheritance.
+ */
+ if(typeof Object.create !== 'function') {
+ Object.create = function(o) {
+ 'use strict';
+
+ function F() {}
+ F.prototype = o;
+ return new F();
+ };
+ }