Created
June 29, 2014 04:52
-
-
Save egorvinogradov/9328b080e1591624cdd3 to your computer and use it in GitHub Desktop.
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
| html, body { | |
| padding: 0; | |
| margin: 0; | |
| height: 100%; | |
| } | |
| body { | |
| font-family: Verdana, sans-serif; | |
| } | |
| .container { | |
| display: table; | |
| width: 100%; | |
| height: 100%; | |
| text-align: center; | |
| } | |
| .container__inner { | |
| display: table-cell; | |
| vertical-align: middle; | |
| } | |
| .colors { | |
| margin: 40px 0; | |
| } | |
| .colors__label { | |
| text-transform: uppercase; | |
| display: inline-block; | |
| padding: 0 18px; | |
| font-size: 14px; | |
| color: #555; | |
| } | |
| .table { | |
| background: #eee; | |
| width: 340px; | |
| height: 340px; | |
| margin: 0 auto; | |
| padding: 10px 0 0 10px; | |
| box-sizing: border-box; | |
| position: relative; | |
| -webkit-user-select: none; | |
| -moz-user-select: none; | |
| user-select: none; | |
| } | |
| .table__cell { | |
| background: #ccc; | |
| float: left; | |
| width: 100px; | |
| height: 100px; | |
| line-height: 100px; | |
| margin: 0 10px 10px 0; | |
| box-sizing: border-box; | |
| font-size: 42px; | |
| cursor: pointer; | |
| transition: top 700ms, left 700ms, transform 700ms, border-radius 700ms; | |
| -webkit-transition: top 700ms, left 700ms, -webkit-transform 700ms, border-radius 700ms; | |
| -moz-transition: top 700ms, left 700ms, -moz-transform 700ms, border-radius 700ms; | |
| -ms-transition: top 700ms, left 700ms, -ms-transform 700ms, border-radius 700ms; | |
| } | |
| .table__cell_animation { | |
| transform: scale(0.7); | |
| -webkit-transform: scale(0.7); | |
| -moz-transform: scale(0.7); | |
| -ms-transform: scale(0.7); | |
| border-radius: 25px; | |
| } | |
| .table__cell:hover { | |
| border: 1px dashed #000; | |
| line-height: 98px; | |
| } | |
| .buttons { | |
| margin: 20px 0; | |
| } | |
| .buttons__button { | |
| margin: 0 10px; | |
| } |
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
| var App = function(params){ | |
| if ( !params ) { | |
| throw new Error('Params are not passed'); | |
| } | |
| this.container = $(params.container); | |
| this.templates = params.templates; | |
| if ( typeof this.templates !== 'object' ) { | |
| throw new Error('Templates are not provided'); | |
| } | |
| if ( !this.container.length ) { | |
| throw new Error('Container is not provided'); | |
| } | |
| }; | |
| App.prototype = { | |
| selectors: { | |
| colors: '.colors', | |
| colorsRadio: '.colors__radio', | |
| table: '.table', | |
| tableCell: '.table__cell', | |
| reset: '.buttons__reset', | |
| randomize: '.buttons__randomize' | |
| }, | |
| classes: { | |
| tableCellAnimation: 'table__cell_animation' | |
| }, | |
| animationDuration: 700, // ms | |
| isAnimating: false, | |
| currentColor: null, | |
| defaultColor: null, | |
| colors: { | |
| red: null, | |
| blue: null, | |
| green: null | |
| }, | |
| initialize: function(){ | |
| this.colorsContainer = $(this.selectors.colors, this.container); | |
| this.tableContainer = $(this.selectors.table, this.container); | |
| this.delegateEvents(); | |
| this.render(); | |
| this.defineColors(); | |
| }, | |
| defineColors: function(){ | |
| this.defaultColor = this.container | |
| .find(this.selectors.tableCell) | |
| .eq(0) | |
| .css('backgroundColor'); | |
| for ( var color in this.colors ) { | |
| var colorElement = $('<i></i>') | |
| .appendTo(this.container) | |
| .css({ | |
| backgroundColor: color | |
| }); | |
| this.colors[color] = colorElement.css('backgroundColor'); | |
| colorElement.remove(); | |
| } | |
| }, | |
| template: function(string, params){ | |
| var match; | |
| var re = /<%\s([^%>]+)?\s%>/g; | |
| while( match = re.exec(string) ) { | |
| string = string.replace(match[0], params[match[1]]) | |
| } | |
| return string; | |
| }, | |
| render: function(){ | |
| var colorsHTML = []; | |
| var tableHTML = []; | |
| for ( var name in this.colors ) { | |
| colorsHTML.push( | |
| this.template(this.templates.colorsLabel, { | |
| color: name | |
| }) | |
| ); | |
| } | |
| for ( var i = 1; i < 10; i++ ) { | |
| tableHTML.push( | |
| this.template(this.templates.tableCell, { | |
| number: i | |
| }) | |
| ); | |
| } | |
| this.colorsContainer.html(colorsHTML.join('\n')); | |
| this.tableContainer | |
| .html(tableHTML.join('\n')) | |
| .find(this.selectors.tableCell) | |
| .each(function(i, cell){ | |
| var cell = $(cell); | |
| cell.css(cell.position()) | |
| }); | |
| setTimeout($.proxy(function(){ | |
| this.tableContainer | |
| .find(this.selectors.tableCell) | |
| .css({ position: 'absolute' }); | |
| }, this), this.animationDuration); | |
| }, | |
| delegateEvents: function(){ | |
| this.container.delegate(this.selectors.colorsRadio, 'click', $.proxy(function(e){ | |
| var target = $(e.currentTarget); | |
| this.currentColor = target.data('color'); | |
| }, this)); | |
| this.container.delegate(this.selectors.tableCell, 'click', $.proxy(this.onTableCellClick, this)); | |
| this.container.delegate(this.selectors.reset, 'click', $.proxy(function(){ | |
| this.currentColor = null; | |
| this.render(); | |
| }, this)); | |
| this.container.delegate(this.selectors.randomize, 'click', $.proxy(this.onRandomizeButtonClick, this)); | |
| }, | |
| onTableCellClick: function(e){ | |
| var target = $(e.currentTarget); | |
| var targetColor; | |
| for ( var name in this.colors ) { | |
| if ( target.css('backgroundColor') === this.colors[name] ) { | |
| targetColor = name; | |
| break; | |
| } | |
| } | |
| if ( targetColor && targetColor !== this.currentColor ) { | |
| alert('Already applied ' + targetColor + ' color.'); | |
| } | |
| else { | |
| if ( this.currentColor ) { | |
| target.css({ | |
| backgroundColor: this.currentColor | |
| }); | |
| } | |
| else { | |
| alert('Please select a color before clicking on boxes.') | |
| } | |
| } | |
| }, | |
| onRandomizeButtonClick: function(){ | |
| if ( this.isAnimating ) { | |
| return false; | |
| } | |
| this.isAnimating = true; | |
| setTimeout($.proxy(function(){ | |
| this.isAnimating = false; | |
| }, this), this.animationDuration * 1.5); | |
| var cells = this.container.find(this.selectors.tableCell); | |
| var positions = []; | |
| cells | |
| .addClass(this.classes.tableCellAnimation) | |
| .each(function(i, cell){ | |
| positions.push( | |
| $(cell).position() | |
| ) | |
| }); | |
| positions = this.shuffleArray(positions); | |
| cells.each(function(i, cell){ | |
| $(cell).css(positions[i]); | |
| }); | |
| setTimeout($.proxy(function(){ | |
| cells.removeClass(this.classes.tableCellAnimation) | |
| }, this), this.animationDuration / 2); | |
| }, | |
| shuffleArray: function(array){ | |
| // Fisher-Yates shuffle algorithm | |
| var currentIndex = array.length; | |
| var temporaryValue; | |
| var randomIndex; | |
| while (0 !== currentIndex) { | |
| randomIndex = Math.floor(Math.random() * currentIndex); | |
| currentIndex -= 1; | |
| temporaryValue = array[currentIndex]; | |
| array[currentIndex] = array[randomIndex]; | |
| array[randomIndex] = temporaryValue; | |
| } | |
| return array; | |
| } | |
| }; | |
| $(function(){ | |
| window.app = new App({ | |
| container: '.container', | |
| templates: { | |
| colorsLabel: $('#colors-label').html(), | |
| tableCell: $('#table-cell').html() | |
| } | |
| }); | |
| app.initialize(); | |
| }); |
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> | |
| <head> | |
| <title>App</title> | |
| <link rel="stylesheet" href="app.css"> | |
| <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script> | |
| <script src="app.js"></script> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="container__inner"> | |
| <div class="colors"></div> | |
| <div class="table"></div> | |
| <div class="buttons"> | |
| <button class="buttons__reset buttons__button">Reset</button> | |
| <button class="buttons__randomize buttons__button">Randomize</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Templates --> | |
| <script type="text/template" id="colors-label"> | |
| <label class="colors__label"> | |
| <input class="colors__radio" type="radio" name="color" data-color="<% color %>"> | |
| <% color %> | |
| </label> | |
| </script> | |
| <script type="text/template" id="table-cell"> | |
| <div class="table__cell"><% number %></div> | |
| </script> | |
| <!-- / Templates --> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment