github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/abplayer/demos/coverflow/coverflow.js (about)

     1  /*jslint devel: true, bitwise: true, regexp: true, browser: true, confusion: true, unparam: true, eqeq: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
     2  /*globals jQuery */
     3  
     4  /*!
     5   * Coverflow
     6   *
     7   * Copyright (c) 2013 Martijn W. van der Lee
     8   * Licensed under the MIT.
     9   */
    10  /* Lightweight and flexible coverflow effect using CSS3 transforms.
    11   * For modern browsers with some amount of graceful degradation.
    12   * Optional support for jQuery.interpolate() plugin.
    13   * Optional support for .reflect() plugins.
    14   *
    15   * Requires jQuery 1.7+ and jQueryUI 1.9+.
    16   * Recommended jQuery 1.8+ and jQueryUI 1.9+.
    17   */
    18  
    19  ;(function($, undefined) {
    20  	"use strict";
    21  
    22  	var sign	= function(number) {
    23  					return number < 0 ? -1 : 1;
    24  				},
    25  		scl		= function(number, fromMin, fromMax, toMin, toMax) {
    26  					return ((number - fromMin) * (toMax - toMin) / (fromMax - fromMin)) + toMin;
    27  				};
    28  
    29  	$.widget("vanderlee.coverflow", {
    30  		options: {
    31  			animateComplete:	undefined,
    32  			animateStep:		undefined,
    33  			density:			1,
    34  			duration:			'normal',
    35  			easing:				undefined,
    36  			index:				0,
    37  			innerAngle:			-75,
    38  			innerCss:			undefined,
    39  			innerOffset:		100 / 3,
    40  			innerScale:			0.75,
    41  			outerAngle:			-30,
    42  			outerCss:			undefined,
    43  			outerScale:			0.25,
    44  			selectedCss:		undefined,
    45  			visible:			'density',		// 'density', 'all', NNN (exact)
    46  			width:				undefined,
    47  
    48  			change:				undefined,		// Whenever index is changed
    49  			confirm:			undefined,		// Whenever clicking on the current item
    50  			select:				undefined		// Whenever index is set (also on init)
    51  		},
    52  
    53  		_create: function() {
    54  			var that = this;
    55  
    56  			// Internal event prefix
    57  			that.widgetEventPrefix	= 'vanderlee-coverflow';
    58  
    59  			that.hovering			= false;
    60  			that.pagesize			= 1;
    61  			that.currentIndex		= that.options.index;
    62  
    63  			// Fix height
    64  			that.element.height(that._getCovers().first().height());
    65  
    66  			// Hide all covers and set position to absolute
    67  			that._getCovers().hide().css('position', 'absolute');
    68  
    69  			// Enable click-jump
    70  			that.element.on('click', '> *', function() {
    71  				var index = that._getCovers().index(this);
    72  				if (index === that.currentIndex) {
    73  					that._callback('confirm');
    74  				} else {
    75  					that._setIndex(index, true);
    76  				}
    77  			});
    78  
    79  			// Refresh on resize
    80  			$(window).resize(function() {
    81  				that.refresh();
    82  			});
    83  
    84  			// Mousewheel
    85  			that.element.on('mousewheel', function(event, delta) {
    86  				event.preventDefault();
    87  				that._setIndex(that.options.index - delta, true);
    88  			});
    89  
    90  			// Swipe
    91  			if ($.isFunction(that.element.swipe)) {
    92  				that.element.swipe({
    93  					swipe: function(event, direction, distance, duration, fingerCount) {
    94  						var count = Math.round((direction === 'left' ? 1 : -1) * 1.25 * that.pagesize * distance / that.element.width());
    95  						that._setIndex(that.options.index + count, true);
    96  					}
    97  				});
    98  			}
    99  
   100  			// Keyboard
   101  			that.element.hover(
   102  				function() { that.hovering = true; }
   103  			,	function() { that.hovering = false; }
   104  			);
   105  
   106  			$(window).on('keydown', function(event) {
   107  				if (that.hovering) {
   108  					switch (event.which) {
   109  						case 36:	// home
   110  							event.preventDefault();
   111  							that._setIndex(0, true);
   112  							break;
   113  
   114  						case 35:	// end
   115  							event.preventDefault();
   116  							that._setIndex(that._getCovers().length - 1, true);
   117  							break;
   118  
   119  						case 38:	// up
   120  						case 37:	// left
   121  							event.preventDefault();
   122  							that._setIndex(that.options.index - 1, true);
   123  							break;
   124  
   125  						case 40:	// down
   126  						case 39:	// right
   127  							event.preventDefault();
   128  							that._setIndex(that.options.index + 1, true);
   129  							break;
   130  
   131  						case 33:	// page up (towards home)
   132  							event.preventDefault();
   133  							that._setIndex(that.options.index - that.pagesize, true);
   134  							break;
   135  
   136  						case 34:	// page down (towards end)
   137  							event.preventDefault();
   138  							that._setIndex(that.options.index + that.pagesize, true);
   139  							break;
   140  					}
   141  				}
   142  			});
   143  
   144  			// Initialize
   145  			that._setIndex(that.options.index, false, true);
   146  			that.refresh();
   147  
   148  			return that;
   149  		},
   150  
   151  		/**
   152  		 * Returns the currently selected cover
   153  		 * @returns {jQuery} jQuery object
   154  		 */
   155  		cover: function() {
   156  			return $(this._getCovers()[this.options.index]);
   157  		},
   158  
   159  		/**
   160  		 *
   161  		 * @returns {unresolved}
   162  		 */
   163  		_getCovers: function() {
   164  			return $('> *', this.element);
   165  		},
   166  
   167  		_setIndex: function(index, animate, initial) {
   168  			var covers = this._getCovers();
   169  
   170  			index = Math.max(0, Math.min(index, covers.length - 1));
   171  
   172  			if (index !== this.options.index) {
   173  				this.refresh();		// pre-correct for reflection/mods
   174  
   175  				if (animate === true) {
   176  					this.currentIndex	= this.options.index;
   177  					this.options.index	= Math.round(index);
   178  
   179  					var that		= this,
   180  						duration	= typeof that.options.duration === "number"
   181  									? that.options.duration
   182  									: jQuery.fx.speeds[that.options.duration] || jQuery.fx.speeds._default,
   183  						timeout		= null,
   184  						step		= that.options.index > that.currentIndex ? 1 : -1,
   185  						doStep		= function() {
   186  										var steps	= Math.abs(that.options.index - that.currentIndex),
   187  											time	= duration / Math.max(1, steps) * 0.5;
   188  										if (that.options.index !== that.currentIndex) {
   189  											that.currentIndex += step;
   190  											that.refresh.call(that, time, that.currentIndex);
   191  											timeout = setTimeout(doStep, time);
   192  										}
   193  										that._callback('change');
   194  										that._callback('select');
   195  									};
   196  					if (timeout) {
   197  						clearTimeout(timeout);
   198  					}
   199  					if (that.currentIndex !== this.options.index) {
   200  						doStep();
   201  					}
   202  				} else {
   203  					this.currentIndex = this.options.index = Math.round(index);
   204  					this.refresh(this.options.duration);
   205  					this._callback('change');
   206  					this._callback('select');
   207  				}
   208  			} else if (initial === true) {
   209  				this.refresh();
   210  				this._callback('select');
   211  			}
   212  		},
   213  
   214  		_callback: function(callback) {
   215  			this._trigger(callback, null, this._getCovers().get(this.currentIndex), this.currentIndex);
   216  		},
   217  
   218  		index: function(index) {
   219  			if (index === undefined) {
   220  				return this.options.index;
   221  			}
   222  			this._setIndex(index, true);
   223  		},
   224  
   225  		refresh: function(duration, index) {
   226  			var that		= this,
   227  				target		= index || that.options.index,
   228  				count		= that._getCovers().length,
   229  				parentWidth	= that.element.innerWidth(),
   230  				coverWidth	= that.options.width || that._getCovers().first().outerWidth(),
   231  				visible		= that.options.visible === 'density'	? Math.round(parentWidth * that.options.density / coverWidth)
   232  							: $.isNumeric(that.options.visible)		? that.options.visible
   233  							: count,
   234  				parentLeft	= that.element.position().left - ((1 - that.options.outerScale) * coverWidth * 0.5),
   235  				space		= (parentWidth - (that.options.outerScale * coverWidth)) * 0.5;
   236  
   237  			duration		= duration || 0;
   238  
   239  			that.pagesize	= visible;
   240  
   241  			that._getCovers().removeClass('current').each(function(index, cover) {
   242  				var position	= index - target,
   243  					offset		= position / visible,
   244  					isVisible	= Math.abs(offset) <= 1,
   245  					sin			= isVisible ? Math.sin(offset * Math.PI * 0.5)
   246  								: sign(offset),
   247  					cos			= isVisible ? Math.cos(offset * Math.PI * 0.5)
   248  								: 0,
   249  					isMiddle	= position === 0,
   250  					zIndex		= count - Math.abs(position),
   251  					left		= parentLeft + space + (isMiddle ? 0 : sign(sin) * scl(Math.abs(sin), 0, 1, that.options.innerOffset * that.options.density, space)),
   252  					scale		= !isVisible? 0
   253  								: isMiddle	? 1
   254  								: scl(Math.abs(cos), 1, 0, that.options.innerScale, that.options.outerScale),
   255  					angle		= isMiddle	? 0
   256  								: sign(sin) * scl(Math.abs(sin), 0, 1, that.options.innerAngle, that.options.outerAngle),
   257  					state		= {},
   258  					css			= isMiddle ? that.options.selectedCss || {}
   259  								: ( $.interpolate && that.options.outerCss && !$.isEmptyObject(that.options.outerCss) ? (
   260  									isVisible ? $.interpolate(that.options.innerCss || {}, that.options.outerCss, Math.abs(sin))
   261  											  : that.options.outerCss
   262  									) : {}
   263  								),
   264  					transform;
   265  
   266  				if (isVisible) {
   267  					$(cover).show();
   268  				}
   269  
   270  				$(cover).stop().css({
   271  					'z-index':	zIndex
   272  				}).animate($.extend(css, {
   273  					'left':		left,
   274  					'_sin':		sin,
   275  					'_cos':		cos,
   276  					'_scale':	scale,
   277  					'_angle':	angle	// must be last!
   278  				}), {
   279  					'easing':	that.options.easing,
   280  					'duration': isVisible ? duration : 0,
   281  					'step':		function(now, fx) {
   282  						// Store state
   283  						state[fx.prop] = now;
   284  
   285  						// On last of the states, change all at once
   286  						if (fx.prop === '_angle') {
   287  							transform = 'scale(' + state._scale + ',' + state._scale + ') perspective('+(parentWidth * 0.5)+'px) rotateY(' + state._angle + 'deg)';
   288  							$(this).css({
   289  								'-webkit-transform':	transform,
   290  								'-ms-transform':		transform,
   291  								'transform':			transform
   292  							});
   293  
   294  							// Optional callback
   295  							that._trigger('animateStep', cover, [cover, offset, isVisible, isMiddle, state._sin, state._cos]);
   296  						}
   297  					},
   298  					'complete':		function() {
   299  						$(this)[isMiddle ? 'addClass' : 'removeClass']('current');
   300  						$(this)[isVisible ? 'show' : 'hide']();
   301  
   302  						// Optional callback
   303  						that._trigger('animateComplete', cover, [cover, offset, isVisible, isMiddle, sin, cos]);
   304  					}
   305  				});
   306  			});
   307  		}
   308  	});
   309  }(jQuery));