1 /** |
|
2 * Interface Elements for jQuery |
|
3 * 3D Carousel |
|
4 * |
|
5 * http://interface.eyecon.ro |
|
6 * |
|
7 * Copyright (c) 2006 Stefan Petre |
|
8 * Dual licensed under the MIT (MIT-LICENSE.txt) |
|
9 * and GPL (GPL-LICENSE.txt) licenses. |
|
10 * |
|
11 */ |
|
12 /** |
|
13 * Created a 3D Carousel from a list of images, with reflections and animated by mouse position |
|
14 * |
|
15 * @example window.onload = |
|
16 * function() |
|
17 * { |
|
18 * $('#carousel').Carousel( |
|
19 * { |
|
20 * itemWidth: 110, |
|
21 * itemHeight: 62, |
|
22 * itemMinWidth: 50, |
|
23 * items: 'a', |
|
24 * reflections: .5, |
|
25 * rotationSpeed: 1.8 |
|
26 * } |
|
27 * ); |
|
28 * } |
|
29 * HTML |
|
30 * <div id="carousel"> |
|
31 * <a href="" title=""><img src="" width="100%" /></a> |
|
32 * <a href="" title=""><img src="" width="100%" /></a> |
|
33 * <a href="" title=""><img src="" width="100%" /></a> |
|
34 * <a href="" title=""><img src="" width="100%" /></a> |
|
35 * <a href="" title=""><img src="" width="100%" /></a> |
|
36 * </div> |
|
37 * CSS |
|
38 * #carousel |
|
39 * { |
|
40 * width: 700px; |
|
41 * height: 150px; |
|
42 * background-color: #111; |
|
43 * position: absolute; |
|
44 * top: 200px; |
|
45 * left: 100px; |
|
46 * } |
|
47 * #carousel a |
|
48 * { |
|
49 * position: absolute; |
|
50 * width: 110px; |
|
51 * } |
|
52 * |
|
53 * @desc Creates a 3D carousel from all images inside div tag with id 'carousel' |
|
54 * |
|
55 * |
|
56 * @name 3D Carousel |
|
57 * @description Created a 3D Carousel from a list of images, with reflections and animated by mouse position |
|
58 * @param Hash hash A hash of parameters |
|
59 * @option String items items selection |
|
60 * @option Integer itemWidth the max width for each item |
|
61 * @option Integer itemHeight the max height for each item |
|
62 * @option Integer itemMinWidth the minimum width for each item, the height is automaticaly calculated to keep proportions |
|
63 * @option Float rotationSpeed the speed for rotation animation |
|
64 * @option Float reflectionSize the reflection size a fraction from items' height |
|
65 * |
|
66 * @type jQuery |
|
67 * @cat Plugins/Interface |
|
68 * @author Stefan Petre |
|
69 */ |
|
70 jQuery.iCarousel = { |
|
71 |
|
72 build : function(options) |
|
73 { |
|
74 return this.each( |
|
75 function() |
|
76 { |
|
77 var el = this; |
|
78 var increment = 2*Math.PI/360; |
|
79 var maxRotation = 2*Math.PI; |
|
80 if(jQuery(el).css('position') != 'relative' && jQuery(el).css('position') != 'absolute') { |
|
81 jQuery(el).css('position', 'relative'); |
|
82 } |
|
83 el.carouselCfg = { |
|
84 items : jQuery(options.items, this), |
|
85 itemWidth : options.itemWidth, |
|
86 itemHeight : options.itemHeight, |
|
87 itemMinWidth : options.itemMinWidth, |
|
88 maxRotation : maxRotation, |
|
89 size : jQuery.iUtil.getSize(this), |
|
90 position : jQuery.iUtil.getPosition(this), |
|
91 start : Math.PI/2, |
|
92 rotationSpeed : options.rotationSpeed, |
|
93 reflectionSize : options.reflections, |
|
94 reflections : [], |
|
95 protectRotation : false, |
|
96 increment: 2*Math.PI/360 |
|
97 }; |
|
98 el.carouselCfg.radiusX = (el.carouselCfg.size.w - el.carouselCfg.itemWidth)/2; |
|
99 el.carouselCfg.radiusY = (el.carouselCfg.size.h - el.carouselCfg.itemHeight - el.carouselCfg.itemHeight * el.carouselCfg.reflectionSize)/2; |
|
100 el.carouselCfg.step = 2*Math.PI/el.carouselCfg.items.size(); |
|
101 el.carouselCfg.paddingX = el.carouselCfg.size.w/2; |
|
102 el.carouselCfg.paddingY = el.carouselCfg.size.h/2 - el.carouselCfg.itemHeight * el.carouselCfg.reflectionSize; |
|
103 var reflexions = document.createElement('div'); |
|
104 jQuery(reflexions) |
|
105 .css( |
|
106 { |
|
107 position: 'absolute', |
|
108 zIndex: 1, |
|
109 top: 0, |
|
110 left: 0 |
|
111 } |
|
112 ); |
|
113 jQuery(el).append(reflexions); |
|
114 el.carouselCfg.items |
|
115 .each( |
|
116 function(nr) |
|
117 { |
|
118 image = jQuery('img', this).get(0); |
|
119 height = parseInt(el.carouselCfg.itemHeight*el.carouselCfg.reflectionSize); |
|
120 if (jQuery.browser.msie) { |
|
121 canvas = document.createElement('img'); |
|
122 jQuery(canvas).css('position', 'absolute'); |
|
123 canvas.src = image.src; |
|
124 canvas.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=60, style=1, finishOpacity=0, startx=0, starty=0, finishx=0)'; |
|
125 |
|
126 } else { |
|
127 canvas = document.createElement('canvas'); |
|
128 if (canvas.getContext) { |
|
129 context = canvas.getContext("2d"); |
|
130 canvas.style.position = 'absolute'; |
|
131 canvas.style.height = height +'px'; |
|
132 canvas.style.width = el.carouselCfg.itemWidth+'px'; |
|
133 canvas.height = height; |
|
134 canvas.width = el.carouselCfg.itemWidth; |
|
135 context.save(); |
|
136 |
|
137 context.translate(0,height); |
|
138 context.scale(1,-1); |
|
139 |
|
140 context.drawImage( |
|
141 image, |
|
142 0, |
|
143 0, |
|
144 el.carouselCfg.itemWidth, |
|
145 height |
|
146 ); |
|
147 |
|
148 context.restore(); |
|
149 |
|
150 context.globalCompositeOperation = "destination-out"; |
|
151 var gradient = context.createLinearGradient( |
|
152 0, |
|
153 0, |
|
154 0, |
|
155 height |
|
156 ); |
|
157 |
|
158 gradient.addColorStop(1, "rgba(255, 255, 255, 1)"); |
|
159 gradient.addColorStop(0, "rgba(255, 255, 255, 0.6)"); |
|
160 |
|
161 context.fillStyle = gradient; |
|
162 if (navigator.appVersion.indexOf('WebKit') != -1) { |
|
163 context.fill(); |
|
164 } else { |
|
165 context.fillRect( |
|
166 0, |
|
167 0, |
|
168 el.carouselCfg.itemWidth, |
|
169 height |
|
170 ); |
|
171 } |
|
172 } |
|
173 } |
|
174 |
|
175 el.carouselCfg.reflections[nr] = canvas; |
|
176 jQuery(reflexions).append(canvas); |
|
177 } |
|
178 ) |
|
179 .bind( |
|
180 'mouseover', |
|
181 function(e) |
|
182 { |
|
183 el.carouselCfg.protectRotation = true; |
|
184 el.carouselCfg.speed = el.carouselCfg.increment*0.1 * el.carouselCfg.speed / Math.abs(el.carouselCfg.speed); |
|
185 return false; |
|
186 } |
|
187 ) |
|
188 .bind( |
|
189 'mouseout', |
|
190 function(e) |
|
191 { |
|
192 el.carouselCfg.protectRotation = false; |
|
193 return false; |
|
194 } |
|
195 ); |
|
196 jQuery.iCarousel.positionItems(el); |
|
197 el.carouselCfg.speed = el.carouselCfg.increment*0.2; |
|
198 el.carouselCfg.rotationTimer = window.setInterval( |
|
199 function() |
|
200 { |
|
201 el.carouselCfg.start += el.carouselCfg.speed; |
|
202 if (el.carouselCfg.start > maxRotation) |
|
203 el.carouselCfg.start = 0; |
|
204 jQuery.iCarousel.positionItems(el); |
|
205 }, |
|
206 20 |
|
207 ); |
|
208 jQuery(el) |
|
209 .bind( |
|
210 'mouseout', |
|
211 function() |
|
212 { |
|
213 el.carouselCfg.speed = el.carouselCfg.increment*0.2 * el.carouselCfg.speed / Math.abs(el.carouselCfg.speed); |
|
214 } |
|
215 ) |
|
216 .bind( |
|
217 'mousemove', |
|
218 function(e) |
|
219 { |
|
220 if (el.carouselCfg.protectRotation == false) { |
|
221 pointer = jQuery.iUtil.getPointer(e); |
|
222 mousex = el.carouselCfg.size.w - pointer.x + el.carouselCfg.position.x; |
|
223 el.carouselCfg.speed = el.carouselCfg.rotationSpeed * el.carouselCfg.increment * (el.carouselCfg.size.w/2 - mousex) / (el.carouselCfg.size.w/2); |
|
224 } |
|
225 } |
|
226 ); |
|
227 } |
|
228 ); |
|
229 }, |
|
230 |
|
231 positionItems : function(el) |
|
232 { |
|
233 el.carouselCfg.items.each( |
|
234 function (nr) |
|
235 { |
|
236 angle = el.carouselCfg.start+nr*el.carouselCfg.step; |
|
237 x = el.carouselCfg.radiusX*Math.cos(angle); |
|
238 y = el.carouselCfg.radiusY*Math.sin(angle) ; |
|
239 itemZIndex = parseInt(100*(el.carouselCfg.radiusY+y)/(2*el.carouselCfg.radiusY)); |
|
240 parte = (el.carouselCfg.radiusY+y)/(2*el.carouselCfg.radiusY); |
|
241 |
|
242 width = parseInt((el.carouselCfg.itemWidth - el.carouselCfg.itemMinWidth) * parte + el.carouselCfg.itemMinWidth); |
|
243 height = parseInt(width * el.carouselCfg.itemHeight / el.carouselCfg.itemWidth); |
|
244 this.style.top = el.carouselCfg.paddingY + y - height/2 + "px"; |
|
245 this.style.left = el.carouselCfg.paddingX + x - width/2 + "px"; |
|
246 this.style.width = width + "px"; |
|
247 this.style.height = height + "px"; |
|
248 this.style.zIndex = itemZIndex; |
|
249 el.carouselCfg.reflections[nr].style.top = parseInt(el.carouselCfg.paddingY + y + height - 1 - height/2) + "px"; |
|
250 el.carouselCfg.reflections[nr].style.left = parseInt(el.carouselCfg.paddingX + x - width/2) + "px"; |
|
251 el.carouselCfg.reflections[nr].style.width = width + "px"; |
|
252 el.carouselCfg.reflections[nr].style.height = parseInt(height * el.carouselCfg.reflectionSize) + "px"; |
|
253 } |
|
254 ); |
|
255 } |
|
256 }; |
|
257 jQuery.fn.Carousel = jQuery.iCarousel.build; |
|