1 |
|
2 | (function() {
|
3 | var $, Li, Row, callQueue, debounce, methods, totalPlugins;
|
4 |
|
5 | $ = jQuery;
|
6 |
|
7 | totalPlugins = 0;
|
8 |
|
9 | callQueue = [];
|
10 |
|
11 | Li = (function() {
|
12 | function Li(el, settings) {
|
13 | var $el, $img;
|
14 | $el = $(el);
|
15 | this.originalWidth = this.width = $el.outerWidth(false);
|
16 | this.originalHeight = this.height = $el.height();
|
17 | this.originalMargin = this.margin = $el.outerWidth(true) - $el.outerWidth(false);
|
18 | $img = $el.find('img');
|
19 | this.imgRatio = $img.width() / $img.height();
|
20 | this.$el = $el;
|
21 | this.settings = settings;
|
22 | }
|
23 |
|
24 | Li.prototype.setHeight = function(h) {
|
25 | this.width = Math.round(h * (this.width / this.height));
|
26 | if (!this.settings.lockedHeight) {
|
27 | return this.height = h;
|
28 | }
|
29 | };
|
30 |
|
31 | Li.prototype.setWidth = function(w) {
|
32 | this.height = Math.round(w * (this.height / this.width));
|
33 | return this.width = w;
|
34 | };
|
35 |
|
36 | Li.prototype.decWidth = function() {
|
37 | return this.setWidth(this.width - 1);
|
38 | };
|
39 |
|
40 | Li.prototype.decHeight = function() {
|
41 | return this.setHeight(this.height - 1);
|
42 | };
|
43 |
|
44 | Li.prototype.incWidth = function() {
|
45 | return this.setWidth(this.width + 1);
|
46 | };
|
47 |
|
48 | Li.prototype.incHeight = function() {
|
49 | return this.setHeight(this.height + 1);
|
50 | };
|
51 |
|
52 | Li.prototype.updateDOM = function() {
|
53 | this.$el.css({
|
54 | width: this.width,
|
55 | height: this.height,
|
56 | 'margin-right': this.margin
|
57 | });
|
58 | return this.$el.find('img').height('auto');
|
59 | };
|
60 |
|
61 | Li.prototype.reset = function() {
|
62 | this.width = this.originalWidth;
|
63 | this.height = this.originalHeight;
|
64 | this.margin = this.originalMargin;
|
65 | return this.$el.css({
|
66 | width: this.width,
|
67 | height: this.height,
|
68 | 'margin-right': this.margin
|
69 | });
|
70 | };
|
71 |
|
72 | return Li;
|
73 |
|
74 | })();
|
75 |
|
76 | Row = (function() {
|
77 | function Row(frameWidth, settings) {
|
78 | this.frameWidth = frameWidth;
|
79 | this.settings = settings;
|
80 | this.lis = [];
|
81 | }
|
82 |
|
83 | Row.prototype.width = function() {
|
84 | var li, width, _i, _len, _ref;
|
85 | width = 0;
|
86 | _ref = this.lis;
|
87 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
88 | li = _ref[_i];
|
89 | width += li.width + li.margin;
|
90 | }
|
91 | return width;
|
92 | };
|
93 |
|
94 | Row.prototype.updateDOM = function() {
|
95 | var li, _i, _len, _ref, _results;
|
96 | _ref = this.lis;
|
97 | _results = [];
|
98 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
99 | li = _ref[_i];
|
100 | _results.push(li.updateDOM());
|
101 | }
|
102 | return _results;
|
103 | };
|
104 |
|
105 | Row.prototype.reset = function() {
|
106 | var li, _i, _len, _ref, _results;
|
107 | _ref = this.lis;
|
108 | _results = [];
|
109 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
110 | li = _ref[_i];
|
111 | _results.push(li.reset());
|
112 | }
|
113 | return _results;
|
114 | };
|
115 |
|
116 | Row.prototype.landscapeGroups = function() {
|
117 | var i, landscapeGroups, landscapes, li, ratio, _ref;
|
118 | landscapeGroups = [];
|
119 | _ref = this.settings.landscapeRatios;
|
120 | for (i in _ref) {
|
121 | ratio = _ref[i];
|
122 | landscapes = (function() {
|
123 | var _i, _len, _ref1, _results;
|
124 | _ref1 = this.lis;
|
125 | _results = [];
|
126 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
127 | li = _ref1[_i];
|
128 | if (li.imgRatio >= ratio) {
|
129 | _results.push(li);
|
130 | }
|
131 | }
|
132 | return _results;
|
133 | }).call(this);
|
134 | landscapeGroups.push(landscapes);
|
135 | }
|
136 | return landscapeGroups;
|
137 | };
|
138 |
|
139 | Row.prototype.resizeLandscapes = function() {
|
140 | var i, landscapes, li, _i, _j, _k, _len, _len1, _ref, _ref1;
|
141 | _ref = this.landscapeGroups(this.settings.landscapeRatios);
|
142 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
143 | landscapes = _ref[_i];
|
144 | if (!(landscapes.length !== 0)) {
|
145 | continue;
|
146 | }
|
147 | for (i = _j = 0, _ref1 = this.settings.resizeLandscapesBy; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
|
148 | for (_k = 0, _len1 = landscapes.length; _k < _len1; _k++) {
|
149 | li = landscapes[_k];
|
150 | li.decHeight();
|
151 | }
|
152 | if (this.width() <= this.frameWidth) {
|
153 | break;
|
154 | }
|
155 | }
|
156 | if (this.width() <= this.frameWidth) {
|
157 | break;
|
158 | }
|
159 | }
|
160 | return this;
|
161 | };
|
162 |
|
163 | Row.prototype.adjustMargins = function() {
|
164 | var i, li, _i, _j, _len, _ref, _ref1, _results;
|
165 | _results = [];
|
166 | for (i = _i = 0, _ref = this.settings.adjustMarginsBy; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
|
167 | _ref1 = this.lis.slice(0, +(this.lis.length - 2) + 1 || 9e9);
|
168 | for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
|
169 | li = _ref1[_j];
|
170 | li.margin--;
|
171 | if (this.width() <= this.frameWidth) {
|
172 | break;
|
173 | }
|
174 | }
|
175 | if (this.width() <= this.frameWidth) {
|
176 | break;
|
177 | } else {
|
178 | _results.push(void 0);
|
179 | }
|
180 | }
|
181 | return _results;
|
182 | };
|
183 |
|
184 | Row.prototype.resizeHeight = function() {
|
185 | var i, li, _results;
|
186 | i = 0;
|
187 | _results = [];
|
188 | while (this.width() > this.frameWidth && i < this.settings.resizeRowBy) {
|
189 | i++;
|
190 | _results.push((function() {
|
191 | var _i, _len, _ref, _results1;
|
192 | _ref = this.lis;
|
193 | _results1 = [];
|
194 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
195 | li = _ref[_i];
|
196 | _results1.push(li.decHeight());
|
197 | }
|
198 | return _results1;
|
199 | }).call(this));
|
200 | }
|
201 | return _results;
|
202 | };
|
203 |
|
204 | Row.prototype.roundOff = function() {
|
205 | var li, _i, _len, _ref, _results;
|
206 | _ref = this.lis;
|
207 | _results = [];
|
208 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
209 | li = _ref[_i];
|
210 | _results.push(li.setWidth(Math.floor(li.width)));
|
211 | }
|
212 | return _results;
|
213 | };
|
214 |
|
215 | Row.prototype.fillLeftoverPixels = function() {
|
216 | var diff, randIndex, _results;
|
217 | this.roundOff();
|
218 | diff = (function(_this) {
|
219 | return function() {
|
220 | return _this.frameWidth - _this.width();
|
221 | };
|
222 | })(this);
|
223 | _results = [];
|
224 | while (diff() !== 0) {
|
225 | randIndex = Math.round(Math.random() * (this.lis.length - 1));
|
226 | if (diff() < 0) {
|
227 | _results.push(this.lis[randIndex].decWidth());
|
228 | } else {
|
229 | _results.push(this.lis[randIndex].incWidth());
|
230 | }
|
231 | }
|
232 | return _results;
|
233 | };
|
234 |
|
235 | Row.prototype.removeMargin = function() {
|
236 | var lastLi;
|
237 | lastLi = this.lis[this.lis.length - 1];
|
238 | return lastLi.margin = 0;
|
239 | };
|
240 |
|
241 | Row.prototype.lockHeight = function() {
|
242 | var li, tallestHeight, tallestLi, _i, _len, _ref, _results;
|
243 | tallestLi = (this.lis.sort(function(a, b) {
|
244 | return b.height - a.height;
|
245 | }))[0];
|
246 | tallestHeight = Math.ceil(tallestLi.height);
|
247 | _ref = this.lis;
|
248 | _results = [];
|
249 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
250 | li = _ref[_i];
|
251 | _results.push(li.height = tallestHeight);
|
252 | }
|
253 | return _results;
|
254 | };
|
255 |
|
256 | Row.prototype.hide = function() {
|
257 | var li, _i, _len, _ref, _results;
|
258 | _ref = this.lis;
|
259 | _results = [];
|
260 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
261 | li = _ref[_i];
|
262 | _results.push(li.$el.hide());
|
263 | }
|
264 | return _results;
|
265 | };
|
266 |
|
267 | Row.prototype.show = function() {
|
268 | var li, _i, _len, _ref, _results;
|
269 | _ref = this.lis;
|
270 | _results = [];
|
271 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
272 | li = _ref[_i];
|
273 | _results.push(li.$el.show());
|
274 | }
|
275 | return _results;
|
276 | };
|
277 |
|
278 | return Row;
|
279 |
|
280 | })();
|
281 |
|
282 | debounce = function(func, wait) {
|
283 | var timeout;
|
284 | timeout = 0;
|
285 | return function() {
|
286 | var args, throttler;
|
287 | args = arguments;
|
288 | throttler = (function(_this) {
|
289 | return function() {
|
290 | timeout = null;
|
291 | return func(args);
|
292 | };
|
293 | })(this);
|
294 | clearTimeout(timeout);
|
295 | return timeout = setTimeout(throttler, wait);
|
296 | };
|
297 | };
|
298 |
|
299 | methods = {
|
300 | init: function(settings) {
|
301 | var i, _defaults;
|
302 | _defaults = {
|
303 | resizeLandscapesBy: 200,
|
304 | resizeRowBy: 30,
|
305 | landscapeRatios: ((function() {
|
306 | var _i, _results;
|
307 | _results = [];
|
308 | for (i = _i = 10; _i <= 50; i = _i += 3) {
|
309 | _results.push(i / 10);
|
310 | }
|
311 | return _results;
|
312 | })()).reverse(),
|
313 | fillLastRow: false,
|
314 | beforeFillWidth: null,
|
315 | afterFillWidth: null
|
316 | };
|
317 | this.settings = $.extend(_defaults, settings);
|
318 | return this.each((function(_this) {
|
319 | return function(i, el) {
|
320 | var $el, $imgs, imagesToLoad, initFillWidth;
|
321 | $el = $(el);
|
322 | methods.initStyling.call(_this, $el);
|
323 | initFillWidth = function() {
|
324 | methods.fillWidth.call(_this, $el);
|
325 | if (!(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/MSIE 8\.0/i))) {
|
326 | $(window).bind('resize.fillwidth', debounce((function() {
|
327 | var fn, _i, _len;
|
328 | callQueue.push((function() {
|
329 | return methods.fillWidth.call(_this, $el);
|
330 | }));
|
331 | if (callQueue.length === totalPlugins) {
|
332 | for (_i = 0, _len = callQueue.length; _i < _len; _i++) {
|
333 | fn = callQueue[_i];
|
334 | fn();
|
335 | }
|
336 | return callQueue = [];
|
337 | }
|
338 | }), 300));
|
339 | }
|
340 | return totalPlugins++;
|
341 | };
|
342 | $imgs = $el.find('img');
|
343 | if (_this.settings.imageDimensions != null) {
|
344 | return initFillWidth();
|
345 | } else {
|
346 | imagesToLoad = $imgs.length;
|
347 | return $imgs.load(function() {
|
348 | imagesToLoad--;
|
349 | if (imagesToLoad === 0) {
|
350 | return initFillWidth();
|
351 | }
|
352 | });
|
353 | }
|
354 | };
|
355 | })(this));
|
356 | },
|
357 | initStyling: function(el) {
|
358 | var $el;
|
359 | $el = $(el);
|
360 | $el.css({
|
361 | 'list-style': 'none',
|
362 | padding: 0,
|
363 | margin: 0
|
364 | });
|
365 | if (this.settings.initStyling != null) {
|
366 | $el.css(this.settings.initStyling);
|
367 | }
|
368 | $el.find('> li').css({
|
369 | 'float': 'left',
|
370 | 'margin-left': 0
|
371 | });
|
372 | $el.find('img').css({
|
373 | 'max-width': '100%',
|
374 | 'max-height': '100%'
|
375 | });
|
376 | if (this.settings && (this.settings.imageDimensions != null)) {
|
377 | return $el.find('> li').each((function(_this) {
|
378 | return function(i, el) {
|
379 | var $img;
|
380 | $img = $(el).find('img').first();
|
381 | $img.width(_this.settings.imageDimensions[i].width);
|
382 | return $img.height(_this.settings.imageDimensions[i].height);
|
383 | };
|
384 | })(this));
|
385 | }
|
386 | },
|
387 | destroy: function() {
|
388 | $(window).unbind('resize.fillwidth');
|
389 | return this.each(function() {
|
390 | var row, _i, _len, _ref;
|
391 | _ref = $(this).fillwidth('rowObjs');
|
392 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
393 | row = _ref[_i];
|
394 | row.reset();
|
395 | }
|
396 | return $(this).removeData('fillwidth.rows');
|
397 | });
|
398 | },
|
399 | fillWidth: function(el) {
|
400 | var $el, row, rows, _i, _j, _len, _len1, _ref;
|
401 | $el = $(el);
|
402 | $el.trigger('fillwidth.beforeFillWidth');
|
403 | if (this.settings.beforeFillWidth != null) {
|
404 | this.settings.beforeFillWidth();
|
405 | }
|
406 | if (this.fillwidthRows) {
|
407 | _ref = this.fillwidthRows;
|
408 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
409 | row = _ref[_i];
|
410 | row.reset();
|
411 | }
|
412 | }
|
413 | $el.width('auto');
|
414 | $el.trigger('fillwidth.beforeNewRows');
|
415 | if (this.settings.beforeNewRows != null) {
|
416 | this.settings.beforeNewRows();
|
417 | }
|
418 | this.frameWidth = $el.width();
|
419 | rows = methods.breakUpIntoRows.call(this, $el);
|
420 | this.fillwidthRows = rows;
|
421 | $el.width(this.frameWidth);
|
422 | $el.trigger('fillwidth.afterNewRows');
|
423 | if (this.settings.afterNewRows != null) {
|
424 | this.settings.afterNewRows();
|
425 | }
|
426 | for (_j = 0, _len1 = rows.length; _j < _len1; _j++) {
|
427 | row = rows[_j];
|
428 | if (!(row.lis.length > 1)) {
|
429 | continue;
|
430 | }
|
431 | row.removeMargin();
|
432 | row.resizeHeight();
|
433 | if (this.settings.adjustMarginsBy != null) {
|
434 | row.adjustMargins();
|
435 | }
|
436 | row.resizeLandscapes();
|
437 | if (!(row === rows[rows.length - 1] && !this.settings.fillLastRow)) {
|
438 | row.fillLeftoverPixels();
|
439 | }
|
440 | row.lockHeight();
|
441 | row.updateDOM();
|
442 | }
|
443 | $el.trigger('fillwidth.afterFillWidth');
|
444 | if (this.settings.afterFillWidth != null) {
|
445 | return this.settings.afterFillWidth();
|
446 | }
|
447 | },
|
448 | rowObjs: function() {
|
449 | var arr, rows;
|
450 | arr = [];
|
451 | rows = this.fillwidthRows;
|
452 | this.each(function() {
|
453 | return arr.push(rows);
|
454 | });
|
455 | if (arr.length === 1) {
|
456 | arr = arr[0];
|
457 | }
|
458 | return arr;
|
459 | },
|
460 | rows: function() {
|
461 | var arr, li, row, rows, _i, _len;
|
462 | rows = methods.rowObjs.call(this);
|
463 | arr = [];
|
464 | for (_i = 0, _len = rows.length; _i < _len; _i++) {
|
465 | row = rows[_i];
|
466 | arr.push((function() {
|
467 | var _j, _len1, _ref, _results;
|
468 | _ref = row.lis;
|
469 | _results = [];
|
470 | for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
471 | li = _ref[_j];
|
472 | _results.push(li.$el);
|
473 | }
|
474 | return _results;
|
475 | })());
|
476 | }
|
477 | if (arr.length === 1) {
|
478 | arr = arr[0];
|
479 | }
|
480 | return arr;
|
481 | },
|
482 | breakUpIntoRows: function(el) {
|
483 | var $el, i, rows;
|
484 | $el = $(el);
|
485 | i = 0;
|
486 | rows = [new Row(this.frameWidth, this.settings)];
|
487 | $el.find('> li').each((function(_this) {
|
488 | return function(j, li) {
|
489 | if ($(li).is(':hidden')) {
|
490 | return;
|
491 | }
|
492 | rows[i].lis.push(new Li(li, _this.settings));
|
493 | if (rows[i].width() >= $el.width() && j !== $el.find('> li').length - 1) {
|
494 | rows.push(new Row(_this.frameWidth, _this.settings));
|
495 | return i++;
|
496 | }
|
497 | };
|
498 | })(this));
|
499 | return rows;
|
500 | }
|
501 | };
|
502 |
|
503 | $.fn.fillwidth = function(method) {
|
504 | if (methods[method] != null) {
|
505 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
506 | } else if (typeof method === "object" || (method == null)) {
|
507 | return methods.init.apply(this, arguments);
|
508 | } else {
|
509 | return $.error("Method " + method + " does not exist on jQuery.fillwidth");
|
510 | }
|
511 | };
|
512 |
|
513 | }).call(this);
|