├── README.md
├── jquery.500px.layout.js
├── jquery.500px.layout.min.js
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | jquery-500px-layout
2 | ===================
3 |
4 | Jquery implementation of the old 500px layout:
5 |
6 | Credits and the detailed explanation:
7 | http://blog.vjeux.com/2012/image/image-layout-algorithm-500px.html
8 |
9 | This plugin is used on the landing page of:
10 | http://www.estudiovicencio.cl/
11 |
12 | ## Usage
13 |
14 | ```javascript
15 | $(function () {
16 | $("#layout").layout({
17 | patterns: ['o|--o|oo','|--o|o--','--o|ooo|','oo|o--|o'],
18 | specialPatterns: ['----','----','--oo','oooo','|--o|o--','o|--o|oo'],
19 | blockFillEl: $('')
20 | });
21 | })
22 | ```
23 | ### Options
24 |
25 | `patterns`: an array of string with the patterns to be repeatedly used. All available combinations are here http://jsfiddle.net/vjeux/L2NQ6 (credits to blog.vjeux.com). By default `["##--##oo"]`
26 |
27 | `specialPatterns`: are used on the ending conditions, each element from the array is used when remains 1,2,3,4 or 6 elements. By default `[]`
28 |
29 | `blockEl`: The element to be transformed. By default `"i"`,
30 |
31 | `blockFillEl`: a fill element used when in the last row there is only one element
32 |
33 |
--------------------------------------------------------------------------------
/jquery.500px.layout.js:
--------------------------------------------------------------------------------
1 | +function ($) {
2 |
3 | "use strict";
4 |
5 | window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
6 | || function(callback){ window.setTimeout(callback, 1000 / 60);};
7 |
8 | var Layout = function (element, options) {
9 | var self = this;
10 | this.$el = $(element);
11 | this.opts = $.extend({}, Layout.DEFAULTS, options);
12 | this.elementWidth = this.$el.width();
13 |
14 | $(window).resize(function (){
15 | this.resizeTo && clearTimeout(this.resizeWatcher);
16 | this.resizeWatcher = setTimeout(function() {
17 | $(this).trigger('v.resize');
18 | }, 400);
19 | });
20 |
21 | $(window).on('v.resize', function () {
22 | var currentWidth = self.$el.width();
23 | if (self.elementWidth !== currentWidth) {
24 | self.elementWidth = currentWidth;
25 | requestAnimationFrame(function () {
26 | self.render();
27 | });
28 | }
29 | });
30 | }
31 |
32 | Layout.DEFAULTS = {
33 | margin: 12, //pixels
34 | blockEl: 'i',
35 | patterns: ['##--##oo'],
36 | specialPatterns: []
37 | }
38 |
39 | Layout.prototype.setBlockWidth = function (size) {
40 | this.blockWidth = size ? size : (this.$el.innerWidth() - 4 * this.opts.margin) / 4;
41 | return this;
42 | }
43 |
44 | Layout.prototype.setBlocks = function () {
45 | this.blocks = this.$el.find(this.opts.blockEl).get().reverse();
46 | return this;
47 | }
48 |
49 | Layout.prototype.renderBlock = function (x, y, width, height) {
50 | var margin = this.opts.margin,
51 | size = this.blockWidth,
52 | block = this.blocks.pop();
53 |
54 | if(block !== undefined) {
55 | $(block).css({
56 | 'margin-left': x * size + (x + 1) * margin,
57 | 'margin-top': y * size + (y + 1) * margin,
58 | 'width': width * size + (width - 1) * margin,
59 | 'height': Math.ceil(height * size + (height - 1) * margin),
60 | 'display': 'inline'
61 | });
62 | }
63 | return this;
64 | }
65 |
66 | Layout.prototype.renderCanvas = function (height, pattern) {
67 |
68 | for (var i = 0, ll = pattern.length; i < ll; i++) {
69 |
70 | var x = i % 4,
71 | y = height + Math.floor(i / 4);
72 |
73 | if (pattern[i] === 'o') {
74 | this.renderBlock(x, y, 1, 1);
75 |
76 | } else if (pattern[i] === '#') {
77 | this.renderBlock(x, y, 2, 2);
78 | pattern[i] = pattern[i + 1] = pattern[i + 4] = pattern[i + 5] = 'x';
79 |
80 | } else if (pattern[i] === '|') {
81 | this.renderBlock(x, y, 1, 2);
82 | pattern[i] = pattern[i + 4] = 'x';
83 |
84 | } else if (pattern[i] === '-') {
85 | this.renderBlock(x, y, 2, 1);
86 | pattern[i] = pattern[i + 1] = 'x';
87 | }
88 | }
89 | return this;
90 | }
91 |
92 | Layout.prototype.render = function () {
93 |
94 | this.setBlocks().setBlockWidth();
95 |
96 | var h = 0,
97 | i = 0,
98 | lastEl;
99 |
100 | while (this.blocks.length) {
101 |
102 | var nBlocks = this.blocks.length,
103 | pattern = '';
104 |
105 | if (nBlocks === 1) {
106 | this.$el.append(this.opts.blockFillEl);
107 | this.blocks.push(this.opts.blockFillEl);
108 |
109 | this.blocks[1] = this.blocks[0];
110 | this.blocks[0] = this.opts.blockFillEl;
111 | }
112 |
113 | if (nBlocks < 6 && this.opts.specialPatterns[nBlocks-1]) {
114 | pattern = this.opts.specialPatterns[nBlocks-1];
115 | } else {
116 | pattern = this.opts.patterns[i];
117 | }
118 |
119 | this.renderCanvas(h, pattern.split(''));
120 |
121 | i = (i + 2) === (this.opts.patterns.length) ? 0 : (i + 1);
122 | h += 2;
123 | }
124 |
125 | /* fix the height */
126 | lastEl = $('i:last');
127 | this.$el.height(parseInt(lastEl.css('height')) + parseInt(lastEl.css('margin-top')));
128 | }
129 |
130 | // MODAL PLUGIN DEFINITION
131 | // =======================
132 |
133 | $.fn.layout = function (option) {
134 | return this.each(function () {
135 |
136 | var $this = $(this),
137 | data = $this.data('layout'),
138 | options = $.extend({}, Layout.DEFAULTS, $this.data(), typeof option == 'object' && option)
139 |
140 | !data && $this.data('layout', (data = new Layout(this, options)));
141 |
142 | requestAnimationFrame(function () {
143 | $this.data('layout').render();
144 | });
145 |
146 | });
147 | }
148 | $.fn.layout.Constructor = Layout;
149 | }(window.jQuery);
150 |
--------------------------------------------------------------------------------
/jquery.500px.layout.min.js:
--------------------------------------------------------------------------------
1 | +function(e){"use strict";window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)};var t=function(n,r){var i=this;this.$el=e(n);this.opts=e.extend({},t.DEFAULTS,r);this.elementWidth=this.$el.width();e(window).resize(function(){this.resizeTo&&clearTimeout(this.resizeWatcher);this.resizeWatcher=setTimeout(function(){e(this).trigger("v.resize")},400)});e(window).on("v.resize",function(){var e=i.$el.width();if(i.elementWidth!==e){i.elementWidth=e;requestAnimationFrame(function(){i.render()})}})};t.DEFAULTS={margin:12,blockEl:"i",patterns:["##--##oo"],specialPatterns:[]};t.prototype.setBlockWidth=function(e){this.blockWidth=e?e:(this.$el.innerWidth()-4*this.opts.margin)/4;return this};t.prototype.setBlocks=function(){this.blocks=this.$el.find(this.opts.blockEl).get().reverse();return this};t.prototype.renderBlock=function(t,n,r,i){var s=this.opts.margin,o=this.blockWidth,u=this.blocks.pop();if(u!==undefined){e(u).css({"margin-left":t*o+(t+1)*s,"margin-top":n*o+(n+1)*s,width:r*o+(r-1)*s,height:Math.ceil(i*o+(i-1)*s),display:"inline"})}return this};t.prototype.renderCanvas=function(e,t){for(var n=0,r=t.length;n