Last active
August 29, 2015 14:06
-
-
Save boertel/f4ee743a7cc523e14e1f to your computer and use it in GitHub Desktop.
Grid constructor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body { | |
| font-family: Helvetica; | |
| } | |
| .controls { | |
| margin-bottom: 20px; | |
| } | |
| .square { | |
| position: relative; | |
| } | |
| .square .row { | |
| overflow: hidden; | |
| } | |
| .square .column-1 { | |
| width: 40px; | |
| height: 40px; | |
| float: left; | |
| margin: 2px; | |
| background-color: #ccc; | |
| border-radius: 4px; | |
| border: 1px solid #ccc; | |
| text-align: center; | |
| } | |
| .square .column-1.active { | |
| border-width: 1px; | |
| border-style: solid; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $('#export').on('click', function () { | |
| $('#output').val(layout.export()); | |
| }); | |
| $('#import').on('click', function () { | |
| layout.import($('#output').val()); | |
| layout.selections.forEach(function (selection) { | |
| selection.select(); | |
| selection.blur(); | |
| }) | |
| }); | |
| $('#generate').on('click', function () { | |
| $('#html').val(layout.html()); | |
| }); | |
| var onerow = true; | |
| $('#one_row').on('change', function () { | |
| onerow = $(this).is(':checked'); | |
| }); | |
| var squareContent = function ($node) { | |
| for (var i = 0; i < 12; i += 1) { | |
| var $row = $('<div></div>').addClass('row'); | |
| for (var j = 0; j < 12; j += 1) { | |
| var column = $('<div></div>') | |
| .attr('data-x', j) | |
| .attr('data-y', i) | |
| .addClass('column-1') | |
| $row.append(column); | |
| } | |
| $node.append($row); | |
| } | |
| }; | |
| squareContent($('.square')) | |
| function Selection(x1, x2, y1, y2, index) { | |
| this.first = {x: x1, y: y1}; | |
| this.x1 = x1; | |
| this.x2 = x2; | |
| this.y1 = y1; | |
| this.y2 = y2; | |
| this.index = index; | |
| this.classes = '.column-1.box-' + index; | |
| } | |
| Selection.prototype.set = function (x, y) { | |
| this.x1 = x; | |
| this.y1 = y; | |
| }; | |
| Selection.prototype.sizex = function () { | |
| return Math.abs(this.x1 - this.x2) + 1; | |
| }; | |
| Selection.prototype.sizey = function () { | |
| return Math.abs(this.y1 - this.y2) + 1; | |
| }; | |
| Selection.prototype.minx = function () { | |
| return Math.min(this.x1, this.x2); | |
| }; | |
| Selection.prototype.miny = function () { | |
| return Math.min(this.y1, this.y2); | |
| }; | |
| Selection.prototype.remove = function () { | |
| var index = this.index | |
| $(this.classes) | |
| .removeAttr('style') | |
| .removeAttr('data-box') | |
| .removeClass('box') | |
| .removeClass('box-' + index) | |
| .html(''); | |
| }; | |
| Selection.prototype.focus = function () { | |
| $(this.classes).css({'opacity': 1}) | |
| }; | |
| Selection.prototype.blur = function () { | |
| $(this.classes).css({'opacity': 0.5}) | |
| }; | |
| Selection.prototype.select = function () { | |
| var index = this.index, | |
| selectors = []; | |
| this.remove(); | |
| var start = { | |
| x: Math.min(this.x1, this.x2), | |
| y: Math.min(this.y1, this.y2) | |
| }, | |
| end = { | |
| x: Math.max(this.x1, this.x2), | |
| y: Math.max(this.y1, this.y2) | |
| } | |
| for (var x = start.x; x <= end.x; x += 1) { | |
| for (var y = start.y; y <= end.y; y += 1) { | |
| selectors.push('.column-1[data-x=' + x + '][data-y=' + y + ']'); | |
| } | |
| } | |
| var first = '.column-1[data-x=' + this.first.x + '][data-y=' + this.first.y + ']'; | |
| $(first).html(this.sizex() + ', ' + this.sizey()); | |
| $(selectors.join(',')).css({ | |
| 'border-color': color(index), | |
| 'background-color': color(index, 0.1) | |
| }).addClass('box-' + index).addClass('box') | |
| .attr('data-box', index); | |
| }; | |
| Selection.attributes = ['x1', 'x2', 'y1', 'y2', 'first', 'index']; | |
| Selection.prototype.toJSON = function () { | |
| var out = {}; | |
| Selection.attributes.forEach(function (attr) { | |
| out[attr] = this[attr]; | |
| }, this); | |
| return out | |
| }; | |
| Selection.fromJSON = function (json) { | |
| var args = []; | |
| Selection.attributes.forEach(function (attr) { | |
| args.push(json[attr]); | |
| }); | |
| var selection = new Selection(json.x1, json.x2, json.y1, json.y2, json.index); | |
| selection.first = json.first; | |
| return selection; | |
| }; | |
| Selection.sortX = function (a, b) { | |
| return (a.minx() < b.minx()) ? -1 : 1; | |
| }; | |
| Selection.sortY = function (a, b) { | |
| return (a.miny() < b.miny()) ? -1 : 1; | |
| } | |
| function Layout (selections) { | |
| this.selections = selections || []; | |
| } | |
| Layout.prototype.length = function () { | |
| return this.selections.length; | |
| }; | |
| Layout.prototype.push = function (selection) { | |
| return this.selections.push(selection); | |
| }; | |
| Layout.prototype.get = function (i) { | |
| return this.selections[i]; | |
| }; | |
| Layout.prototype.remove = function (i) { | |
| return this.selections.splice(i, 1); | |
| }; | |
| Layout.prototype.indexOf = function (selection) { | |
| return this.selections.indexOf(selection); | |
| }; | |
| Layout.prototype.export = function () { | |
| return JSON.stringify(this.selections); | |
| }; | |
| Layout.prototype.import = function (str) { | |
| var json = JSON.parse(str); | |
| json.forEach(function (d) { | |
| this.selections.push(Selection.fromJSON(d)); | |
| }, this); | |
| return this.selections; | |
| }; | |
| Layout.prototype.layout = function () { | |
| var matrix = [], | |
| selections = this.selections.slice(0); | |
| selections.sort(Selection.sortY); | |
| selections.forEach(function (d) { | |
| matrix[d.miny()] = matrix[d.miny()] || [] | |
| matrix[d.miny()].push(d); | |
| }); | |
| matrix.forEach(function (d) { | |
| d.sort(Selection.sortX); | |
| }); | |
| return matrix; | |
| }; | |
| Layout.prototype.html = function () { | |
| var matrix = this.layout(), | |
| output = []; | |
| matrix.forEach(function (y) { | |
| output.push('<div class="row">'); | |
| y.forEach(function (x) { | |
| output.push('<div class="column large-' + x.sizex() + '"></div>'); | |
| }); | |
| output.push('</div>'); | |
| }); | |
| return output.join(''); | |
| }; | |
| var current, | |
| deactivated = true, | |
| colors = [ | |
| [255, 0, 0], | |
| [0, 255, 0], | |
| [0, 0, 255], | |
| [255, 255, 0], | |
| [255, 0, 255], | |
| [0, 255, 255], | |
| ]; | |
| function color (i, alpha) { | |
| var index = i % colors.length; | |
| var rgba = colors[index].slice(0); | |
| alpha = alpha || 1; | |
| rgba.push(alpha); | |
| return 'rgba(' + rgba.join(',') + ')'; | |
| } | |
| function draw() { | |
| var x = $(this).data('x'), | |
| y = $(this).data('y'); | |
| if (current === undefined) { | |
| current = new Selection(x, x, y, y, layout.length()); | |
| layout.push(current); | |
| } | |
| if (onerow && y !== current.first.y) { | |
| return; | |
| } | |
| current.set(x, y) | |
| current.select(); | |
| } | |
| function create () { | |
| deactivated = !deactivated; | |
| if (current === undefined) { | |
| // start | |
| draw.bind(this)(); | |
| } else { | |
| // end | |
| current.blur(); | |
| current = undefined | |
| } | |
| return false; | |
| } | |
| function edit () { | |
| deactivated = false; | |
| var i = parseInt($(this).attr('data-box')); | |
| current = layout.get(i); | |
| current.focus() | |
| return false; | |
| } | |
| function remove() { | |
| current.remove(); | |
| layout.remove(current.index); | |
| current = undefined; | |
| deactivated = true; | |
| } | |
| var layout = new Layout() | |
| $('.column-1').on('mouseover', function (e) { | |
| if (deactivated || ($(this).hasClass('box') && !$(this).hasClass('box-' + current.index))) { | |
| return; | |
| } | |
| draw.bind(this)(); | |
| }) | |
| $('.column-1').on('click', function () { | |
| if ($(this).hasClass('box')) { | |
| if (current === undefined) { | |
| edit.bind(this)() | |
| return false; | |
| } | |
| } | |
| create.bind(this)() | |
| }) | |
| $(document).on('keyup', function (e) { | |
| if (current !== undefined) { | |
| switch (e.which) { | |
| case 68: | |
| remove() | |
| break; | |
| case 27: | |
| create() | |
| break; | |
| } | |
| } | |
| return false; | |
| }); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title></title> | |
| <link rel="stylesheet" href="./grid-constructor.css"> | |
| </head> | |
| <body> | |
| <div class="controls"> | |
| <div style="overflow: hidden;"> | |
| <div class="square" style="float: left;"></div> | |
| <div class="output" style="float: left;"> | |
| <button id="export">Export</button> | |
| <button id="import">Import</button> | |
| <br> | |
| <textarea id="output" name="" cols="30" rows="10"></textarea> | |
| <hr> | |
| <button id="generate">Generate</button> | |
| <br> | |
| <textarea id="html" name="" cols="30" rows="10"></textarea> | |
| <hr> | |
| <label><input type="checkbox" id="one_row" checked="checked">1 row only</label> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> | |
| <script type="text/javascript" src="./grid-constructor.js"></script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment