Recent Entries 10
- pattern minor 112d agoMerge values of the objects properties with the same name into arrayI have such input: ``` [ { name: 'timezone', value: 'EST' }, { name: 'interval', value: 'day' }, { name: 'metrics[]', value: 1}, { name: 'metrics[]', value: 2} ] ``` As you may already notice - these are parameters from POST request. What I need to do is to get such output: ``` [ { name: 'timezone', value: 'EST' }, { name: 'interval', value: 'day' }, { name: 'metrics[]', value: [ 1, 2 ] }, { name: 'metrics[]', value: [ 1, 2 ] } ] ``` My code does everything it needs to do, but I'm not sure if it is written in the optimal way, am I overlooking some bugs, etc. ``` arrayify = (params) -> arrayifiedParams = {} for param in params paramName = param.name arrayifiedParams[paramName] = arrayifiedParams[paramName] || [] arrayifiedParams[paramName].push param.value params.map (param) -> paramName = param.name if arrayifiedParams[paramName].length > 1 param.value = arrayifiedParams[paramName] param ``` Here is the corresponding JSFiddle.
- pattern minor 112d agoHTML5 Video playerI do HTML5 Video player with some controls. I have a button, where I change classname for make play, pause or replay button. I have a mute/unmute button, volume range slider, timer and fullscreen mode button. Maybe I can do some functions better or faster, and also, maybe I need to change comments? Logic: ``` "use strict" doc = document video = doc.getElementById("video") video.controls = false ###* Video controls ### play_button = doc.getElementById("play-button") progress_bar = doc.getElementById("progress-bar") progress_load = doc.getElementById("progress-load") current_time_block = doc.getElementById("time-current") duration_block = doc.getElementById("time-duration") volume_button = doc.getElementById("volume-button") volume_range = doc.getElementById("volume-range") screen_button = doc.getElementById("screen-button") ###* # A video DOM currentTime property formatting. # @param {current_time} Video currentTime property. # @return {string} Time in the format 00:00. #### video_time_format = (current_time) -> seconds = Math.floor(current_time) minutes = Math.floor(current_time / 60) if minutes >= 10 then minutes = minutes else minutes = "0" + minutes if seconds >= 10 then seconds = seconds else seconds = "0" + seconds minutes + ":" + seconds ###* Get a video DOM duration property. ### video_duration = null get_video_duration = -> if video.duration video_duration = video.duration ###* Set video duration to video controls panel. ### video.addEventListener("loadedmetadata", -> duration_block.textContent = video_time_format(get_video_duration()) ) ###* # A helper function for update progress bar events. # Set video current time in video controls panel and progress bar. # @param {position} Percentage of progress. ### current_time_update = (position) -> current_time_block.textContent = video_time_format(video.currentTime) progress_load.style.width = position ###* # The value is converted into a p
- pattern minor 112d agoRegex for curly quotes and apostrophesAfter years of fear and procrastination I decided to learn regular expressions. This is the result: CoffeScript: ``` str = "#{chapter.title}\n\n#{chapter.content}\n\n" str.replace(/>([^>]+) r.replace(/(>|\s)"/g, "$1“") .replace(/"/g, "”") .replace(/("|\s)'/g, "$1‘") .replace(/'/g, "’") ) ``` JavaScript: ``` var str = "" + chapter.title + "\n\n" + chapter.content + "\n\n"; str.replace(/>([^>]+)|\s)"/g, "$1“") .replace(/"/g, "”") .replace(/("|\s)'/g, "$1‘") .replace(/'/g, "’"); }); ``` As you can see, the code turns all "straight" quotation characters (plus apostrophe) to “curly” ones. It was a bit hard because the input had stuff like this: ``` "Yes," he said, "I met her. She's very 'friendly.'" ``` So I had to make sure the quotes inside the HTML tags were not being included. And make the code know that quotations wouldn't always be preceded by a space (sometimes by an `>`). I welcome any suggestion to make the code shorter, more efficient/readable.
- pattern minor 112d agoPeriodic Table generatorI've been playing around with Jekyll and CoffeeScript the last few days and made a Periodic Table to learn those two. Now, to create the Periodic Table, I take an array of `li`s as input which then replaces itself with a table using a custom format like so: ``` periodicTable = [ [1, "s:16", 2], [3, 4, "s:10", 5, "-", 10], [11, 12, "s:10", 13, "-", 18], [19, "-", 36], [37, "-", 54], [55, 56, "*", 72, "-", 86], [87, 88, "**", 104, "-", 118], ["s:18"], ["s:2", "*", 57, "-", 71], ["s:2", "**", 89, "-", 103] ] ``` - `s:n` means that the next `td` should be empty with a `colspan` of n - `"-"` is a range indicator, meaning the next and previous items are the start and end of the range respectively To create the actual table, the following CoffeeScript file is used: ``` window.PeriodicTable = {} periodicTable = [ [1, "s:16", 2], [3, 4, "s:10", 5, "-", 10], [11, 12, "s:10", 13, "-", 18], [19, "-", 36], [37, "-", 54], [55, 56, "*", 72, "-", 86], [87, 88, "**", 104, "-", 118], ["s:18"], ["s:2", "*", 57, "-", 71], ["s:2", "**", 89, "-", 103] ] spacerIdentifier = "s" rangeSymbol = "-" # Get a list item searching by atomic number PeriodicTable.getListItemByAtomicNumber = (list, atomicNumber) -> i = 0 while i table = document.createElement "table" table.className = "periodic-table" ul = list[0].parentNode for i of periodicTable row = PeriodicTable.createRow list, periodicTable[i] table.appendChild row ul.parentNode.insertBefore table, ul return true # Create a table row PeriodicTable.createRow = (list, items) -> row = document.createElement "tr" i = 0 skipNext = false while i col = document.createElement "td" if !isNaN atomicNumber listContent = PeriodicTable.getContentFromListItem(list, atomicNumber) if typeof listContent == "string" content = listContent else c
- pattern minor 112d agoFlood game implementationThere is the implementation of flood game on my GitHub. The app.coffee is the main part of project: ``` class Square colors = [ 'orange', 'green', 'red', 'blue', 'violet', 'yellow', ] constructor: (@game, @node)-> @node.on 'click', => @game.flood(@color) reset: -> @controlled = false color = colors[Math.floor(Math.random() * colors.length)] @setColor(color) setColor: (color)-> @node.removeClass(@color) @color = color @node.addClass(@color) class Game DIMENSION = 14 SIZE = DIMENSION * DIMENSION constructor: ($tbody)-> @limit = 25 @grid = [] for i in [0...DIMENSION] $tr = $ '' $tbody.append $tr @grid.push [] for j in [0...DIMENSION] $td = $('').html(' ') $tr.append $td @grid[i].push(new Square(@, $td)) @top = @grid[0][0] @reset() reset: -> for i in [0...DIMENSION] for j in [0...DIMENSION] @grid[i][j].reset() @top = @grid[0][0] @top.controlled = true @flood(@top.color) @setTurnCounter(0) setTurnCounter: (counter)-> $counter = $ '#count' @turn = counter $counter.toggleClass 'bad', @turn > @limit $('#counter-used').text(@turn) flood: (color)-> if @top.color is color return @setTurnCounter(@turn + 1) @_flood(0, 0, color, []) if @hasWon() setTimeout( => @decreaseLimit() @reset() 2000 ) decreaseLimit: ()-> @expected-- _flood: (i, j, color, checked)-> if i for i in [0...DIMENSION] for j in [0...DIMENSION] if not @grid[i][j].controlled return false return true (($, Game)-> tbody = $('tbody') game = new Game(tbody) btnRestart = $('#btn-restart') btnRestart.on 'click', (e)-> e.preventDefault() game.reset() )(jQuery, Game) ``` I build assets with Grunt and use grunt-serve as a simple HTTP server. P.S.: I use styles from another implementation
- pattern minor 112d agoGet <TH> texts into a tab separated string``` table_with_headers = $(this.dom.table).find("thead tr th").map(-> $(this).text() ).get().join("\t") ``` Can one write it nicer? I especially don't like the inner function in map syntax enforced by CoffeeScript and jQuery.
- pattern minor 112d agoEnglish-Russian irregular words testerCould you please offer some suggestions about my self learning project? It is really hard-coded, but I have no idea what to do next. I'm using `angular` (only few features for now) and `grunt + bower`. tester.html ``` First form Second form Third form Translation {{ verb }} {{ verb }} {{ val[$index] }} {{ verb }} Check Next ``` iwt.coffee ``` angular.module('IWTTester', []) .controller('IWTTesterController', [ '$http' '$scope' ($http, $scope) -> $http.get 'js/words.json' .success (data, status, headers, config) -> console.log data, status, config, 'good' $scope.irregulars = data $scope.init() .error (data, status, headers, config) -> console.log data, status, config, 'bad' $scope.isActive = (formIndex) -> formIndex is $scope._activeForm $scope.isStage = (value) -> value is $scope._stage $scope.init = -> ROWS = $scope.irregulars.length COLS = $scope.irregulars[0].length create_counter = (module) -> i = 0 -> (i++) % module rowCounter = create_counter(ROWS) colCounter = create_counter(COLS) $scope.val = [] $scope._stage = 'input' update = -> $scope.verbs = $scope.irregulars[rowCounter()] $scope._activeForm = colCounter() update() $scope.isSuccess = (i) -> $scope.val[i] is $scope.verbs[i] $scope.isDanger = (i) -> $scope.val[i] isnt $scope.verbs[i] and not $scope.isActive(i) $scope.check = -> $scope._stage = 'validation' $scope.next = -> $scope.val = [] update() $scope._stage = 'input' ]) .directive('iwtTester', -> restrict: 'AE' templateUrl: 'templates
- pattern minor 112d agoMathematical boundaries (audio meter)I've just been putting together an audio meter by stacking bootstrap progress bars, and thought there was probably a better way, mathematically / logically, of achieving this. ``` levels = (vumeter) -> green = if vumeter % 50 < vumeter then 50 else vumeter yellow = if vumeter % 85 < vumeter then 35 else vumeter - 50 red = if vumeter % 100 < vumeter then 15 else vumeter - 85 'green': green 'yellow': yellow 'red': red ```
- pattern minor 112d agoTick module for the gameI tried to look up and suck in most of the information about optimizing this operation and this is what I came up with. As it's pretty much core of the game, I really would like to have it performant as much as I can. I would appreciate if someone can take a look at this and possibly find weak spots. Note: I am using Browserify, hence that `module.exports`. Don't get confused, it is supposed to run in the browser. ``` module.exports = (tickModule, app) -> # Function to retrieve current timestamp, hopefully using window.performance object getTime = if (perf = window.performance)? then -> perf.now() else Date.now # Store the reference so there is no need for scope lookup in every tick raf = window.requestAnimationFrame # Indicates if module is running running = false # Holds identifier for cancelAnimationFrame call requestId = null # Timestamp of the last run of the tick previous = 0 # Run the tick loop tick = -> return unless running # Request frame and store identifier requestId = raf tick # Retrieve current timestamp timestamp = getTime() # Calculate number of seconds from last tick delta = (timestamp - previous) * 0.001 # Store the timestamp for the next round previous = timestamp # Emit event with delta app.land.emit 'tick', delta, timestamp # Start ticking when module start tickModule.addInitializer -> previous = getTime() running = true tick() # Stop ticking when module stops tickModule.addFinalizer -> running = false window.cancelAnimationFrame requestId ``` I am thinking about removing that `requestId` and `running`, since I am not really planning to stop the ticking once it starts. It was made merely like nice gesture, but it's not that useful for the game I suppose.
- pattern minor 112d agoRuby on Rails text editorI'm currently building a text editor using contenteditable and RoR back end. As the editor is WYSIWYG and trying to follow DRY, I used only one file to 3 actions: Show, Edit and New. Edit and new will pretty much be the same, however, show won't be editable and won't show the Subtitle if it's empty. I was doing it all through JavaScript, but it didn't feel right to me, so I decided to make it using rails. This is the final result. 0 Javascript, all rails. It is working now, but it's not DRY. There are lots of repeated conditions. How can this code be more DRY and human-readable? ``` %section#text-editor-container %article#new-text %section#text-header.new-text-container.row{style: ("background: url('#{@text.text_images.last.photo.url}') center center no-repeat transparent; background-size: cover;" unless @text.text_images.empty?)} - if (current_page?(edit_text_url(@text)) || current_page?(new_text_url)) .picture-icon.hidden-xs.col-sm-1.col-md-1.col-lg-1 = render 'direct_upload', callback: text_cover_url %h1#title.col-xs-12.col-sm-11.col-md-11.col-lg-11.placeholdify{class: ('editable' if current_page?(edit_text_url(@text)) || current_page?(new_text_url)), contenteditable: (true if current_page?(edit_text_url(@text)) || current_page?(new_text_url)), data: {placeholder: t(:title)}}= raw(@text.title) unless @text.title.nil? - if (((@text.subtitle.nil? || @text.subtitle.empty?) && (current_page?(edit_text_url(@text)) || current_page?(new_text_url))) || !@text.subtitle.empty?) %h2#subtitle.col-xs-12.col-sm-11.col-md-11.col-lg-11.placeholdify{class: ('editable' if current_page?(edit_text_url(@text)) || current_page?(new_text_url)), contenteditable: (true if current_page?(edit_text_url(@text)) || current_page?(new_text_url)), data: {placeholder: t(:sub_title)}}= raw(@text.subtitle) unless @text.subtitle.nil? %section#text-commands-bar.new-text-container -if @text.is_draft %span.pull-left= t(:text_stil