This repository has been archived by the owner on Jan 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 87
/
ui.coverflow.js
156 lines (94 loc) · 4.62 KB
/
ui.coverflow.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
* jQuery UI CoverFlow
Re-written for jQueryUI 1.8.6 by Addy Osmani with adjustments
Original Component: Paul Bakaus for jQueryUI 1.7 series
*/
(function($){
var browserVersion = $.browser.version.replace(/^(\d+\.)(.*)$/, function() { return arguments[1] + arguments[2].replace(/\./g, ''); });
var supportsTransforms = !($.browser.mozilla && (parseFloat(browserVersion) <= 1.9)) && !$.browser.opera;
$.easing.easeOutQuint = function (x, t, b, c, d) {
return c*((t=t/d-1)*t*t*t*t + 1) + b;
};
$.widget("ui.coverflow", {
options: {
items: "> *", //> *
orientation: 'horizontal',
item: 0,
trigger: 'click',
center: true, //If false, element's base position isn't touched in any way
recenter: true //If false, the parent element's position doesn't get animated while items change
},
_create: function() {
var self = this, o = this.options;
this.items = $(o.items, this.element);
this.props = o.orientation == 'vertical' ? ['height', 'Height', 'top', 'Top'] : ['width', 'Width', 'left', 'Left'];
//For < 1.8.2: this.items['outer'+this.props[1]](1);
this.itemSize = 0.73 * this.items.innerWidth();
this.itemWidth = this.items.width();
this.itemHeight = this.items.height();
this.duration = o.duration;
this.current = o.item; //initial item
//Bind click events on individual items
this.items.bind(o.trigger, function() {
self.select(this);
});
//Center the actual parent's left side within it's parent
this.element.css(this.props[2],
(o.recenter ? -this.current * this.itemSize/2 : 0)
+ (o.center ? this.element.parent()[0]['offset'+this.props[1]]/2 - this.itemSize/2 : 0) //Center the items container
- (o.center ? parseInt(this.element.css('padding'+this.props[3]),10) || 0 : 0) //Subtract the padding of the items container
);
//Jump to the first item
this._refresh(1, 0, this.current);
},
select: function(item, noPropagation) {
this.previous = this.current;
this.current = !isNaN(parseInt(item,10)) ? parseInt(item,10) : this.items.index(item);
//Don't animate when clicking on the same item
if(this.previous == this.current) return false;
//Overwrite $.fx.step.coverflow everytime again with custom scoped values for this specific animation
var self = this, to = Math.abs(self.previous-self.current) <=1 ? self.previous : self.current+(self.previous < self.current ? -1 : 1);
$.fx.step.coverflow = function(fx) { self._refresh(fx.now, to, self.current); };
// 1. Stop the previous animation
// 2. Animate the parent's left/top property so the current item is in the center
// 3. Use our custom coverflow animation which animates the item
var animation = { coverflow: 1 };
animation[this.props[2]] = (
(this.options.recenter ? -this.current * this.itemSize/2 : 0)
+ (this.options.center ? this.element.parent()[0]['offset'+this.props[1]]/2 - this.itemSize/2 : 0) //Center the items container
- (this.options.center ? parseInt(this.element.css('padding'+this.props[3]),10) || 0 : 0) //Subtract the padding of the items container
);
//Trigger the 'select' event/callback
if(!noPropagation) this._trigger('select', null, this._uiHash());
this.element.stop().animate(animation, {
duration: this.options.duration,
easing: 'easeOutQuint'
});
},
_refresh: function(state,from,to) {
var self = this, offset = null;
this.items.each(function(i)
{
var side = (i == to && from-to < 0 ) || i-to > 0 ? 'left' : 'right',
mod = i == to ? (1-state) : ( i == from ? state : 1 ),
before = (i > from && i != to),
css = { zIndex: self.items.length + (side == "left" ? to-i : i-to) };
css[($.browser.safari ? 'webkit' : 'Moz')+'Transform'] = 'matrix(1,'+(mod * (side == 'right' ? -0.2 : 0.2))+',0,1,0,0) scale('+(1+((1-mod)*0.3)) + ')';
css[self.props[2]] = ( (-i * (self.itemSize/2)) + (side == 'right'? -self.itemSize/2 : self.itemSize/2) * mod );
if(!supportsTransforms) {
css.width = self.itemWidth * (1+((1-mod)*0.5));
css.height = css.width * (self.itemHeight / self.itemWidth);
css.top = -((css.height - self.itemHeight) / 2);
}
$(this).css(css);
});
this.element.parent().scrollTop(0);
},
_uiHash: function() {
return {
item: this.items[this.current],
value: this.current
};
}
});
})(jQuery);