ColbyDeHart.com :: Click for info about me

My name is Colby DeHart. I live in Nashville, Tennessee. I love dogs, music, programming, bikes, all games, solving problems, and learning new things. Feel free to get in touch!

 

DOM Collision Detection :: Permalink - 04 Dec 2014

I was working on a recreation of the Hasbro board game Battleship in the browser. I had to check and make sure that when I was placing my ships in the game that they could not overlap, therefore had to figure out collision detection in the DOM.

This is the function in its entirety.

function willCollide(block) {
  var top = block.offset().top,
      left = block.offset().left,
      right = left + block.width(),
      bottom = top + block.height(),
      result = false;
      
  $blocks.each(function(i, el){
    if($(this).attr('id') !== block.attr('id')){
      var blockLeft = $(this).offset().left,
          blockTop = $(this).offset().top,
          blockRight = shipLeft + $(this).width(),
          blockBottom = shipTop + $(this).height();
      if (!(top >= blockBottom || bottom <= blockTop ||
          left >= blockRight || right <= blockLeft)){
            result = true;
      }
    }
  });
  return result;
}

This function takes in a block, which is just a DOM element (I’m using jQuery here). My blocks are just divs in this case. willCollide will return true if the piece is colliding with another block.

The first few lines get the top, left, right, and bottom edges of the block and set them to variables using the element’s offset and dimensions.

After that, I’m looping through each block element in $blocks. Each block has a unique id, so the if statement will prevent me from checking my main block against the others. If it is a unique block, I get the top, left, right, and bottom exactly how I did at the top of the function. Then it gets a little weird with this if statement:

if (!(top >= blockBottom || bottom <= blockTop ||
    left >= blockRight || right <= blockLeft)){
      result = true;
}

Okay, so lets break this down. Since I’m comparing two blocks and saying ‘block’ over and over again is going to get confusing, i am going to call the main block that was passed into the function the mainBlock and the block that is currently being compared in the for loop the currentBlock. Alright.

top >= blockBottom || bottom <= blockTop

Keep in mind that height increases as it goes down in DOM coordinates. So we see if the top of the mainBlock is lower than the bottom of the currentBlock or if the bottom of the mainBlock is higher than the top of the currentBlock. If either of these are true, than there is no way that the blocks could overlap each other vertically, but we don’t know anything about horizontal collision. That’s where the next line comes in.

(!(top >= blockBottom || bottom <= blockTop ||
left >= blockRight || right <= blockLeft))

The left and right check do the same as the top and bottom then we wrap the whole conditional up in parenthesis a negate it, basically saying, ‘If there is no way that these two elements are not going to collide, then they collide’. Then we set the result accordingly and return it at the end of the function. It looks a little convoluted, but after you get a hang of the parts it is actually pretty simple.

Close

Gulp from 0 to 60 :: Permalink - 21 Nov 2014

Gulp is a JavaScript task runner. It can automate tasks in your development environment like running tests, linting code, compiling sass, and much, much, more. If all of that doesn’t make a ton of sense to you, don’t worrry. In this post, I plan on outlining how to get Gulp up an running for someone with no knowledge of task runners or node.

Tasks

In this example environment we are about to set up, we will have Gulp handle 4 tasks for us.

  1. Opening a local webserver.
  2. Processing our scss files into one style.css file.
  3. Watching our files for changes and running tasks accordingly.

These are just what I needed for a project I am working on. Gulp is capable of many dozens of tasks, but for right now we will stick with these.

Setup

The first necessary step is to install Node if you have not already. Their website has good instructions for installation through their site or a package manager like brew. If you are not familiar, Node is basically the innards of Google Chrome’s JavaScript interpreter in a standalone application. This allows us to write JavaScript programs that can perform console-style tasks like spinning up servers, parsing files, and editing their output.

Installing node will automatically install npm which stands for ‘Node package manager’. This program will allow you to install node modules (programs) from the npm repository. It is very similar to brew, apt-get, or ruby gems if you have ever used any of these.

After installing node, we need to make a configuration file in our current project for node. This is one simple command, npm init. Running this will ask a few questions and then output a file in your root directory called package.json. This file is how Node keeps track of your project and its dependency modules. If you get a project with a package.json, you can install all of its dependencies via npm install.

To install a single module with npm, you use the command npm install <options> <package-names>, where ‘package-names’ is a space-separated list of package names. There are quite a few options you can pass in, but the 3 that are important in this post are:

  • --global (or -g): will install the module globally so you can use it from anywhere, not just in a project.
  • --save (or -S): will save the module only on the current project and add it as a dependency in the package.json.
  • --save-dev (or -D): will save the module only on the current project and add it to the package.json, but as a development dependency.

Since this is our first time installing gulp, we will need to instal it globally so we can use the gulp command from the terminal and also locally on our project as a development dependency. So this far, we should have run these commands…

npm init
#Answer questions for package.json initialization
npm install --global gulp
npm install --save-dev gulp

That’s it as far as getting the basics set up for Node. Now we need to configure gulp with our Gulpfile

Gulpfile

Go ahead and make a file in your root directory called Gulpfile.js this is the file that gulp uses to configure its tasks. We can make a basic skeleton gulpfile that will look like this.

var gulp = require('gulp');

gulp.task('default', function(){
  console.log("Gulp is running!");
});

Now if you jump back into your console and run gulp, the console should print out

[10:26:12] Using gulpfile ~/myCoolSite/Gulpfile.js
[10:26:12] Starting 'default'...
Gulp is running!
[10:26:12] Finished 'default' after 72 μs

Awesome! We got Gulp to print out to the console. Now, let’s talk about that Gulpfile, because there is some Node-specific stuff that might be confusing. So here in the first line…

var gulp = require('gulp');

This require keyword is a Node method that will import a module. It will look in your node_modules folder (which was created when you npm installed gulp) for the module and put it into the gulp variable so that we can use the gulp methods in our JavaScript. Using and creating node modules is a pretty deep subject, but for now all you need to know is that require pulls in a module that we installed with npm install.

gulp.task('default', function(){
  console.log("Gulp is running!");
});

This is the way in which gulp will make tasks. The first argument it takes in is the name of the task we are defining and the second argument is the function that will run in the task. Here we are just calling a console.log. In browsers, console.log will output to the JavaScript console, but in node it will output to the terminal. Alright, time to start making this actually useful.

Webserver

To get our webserver running, we need to first install the module for doing so. Jump out to your terminal and run npm install -D gulp-webserver. This is a module that lets us spin up a localhost server from a directory and use livereload if we want. There are a multitude of server modules for gulp, but this is a dead simple one and you can always switch to a different one later.

Now to get the webserver accessible in our gulp we need to require it, so add the line var webserver = require('gulp-webserver'); at the top of your Gulpfile. note that I called the variable ‘webserver’ instead of ‘gulp-webserver’. This is a pretty common convention, and also just helps you avoid having to write ‘gulp-‘ all over the place.

Now change your default gulp task to be…

gulp.task('default', function(){
  console.log("Gulp is running!");
  gulp.src('./')
    .pipe(webserver());
});

So there are a couple new things here, first of all is gulp.src(). This is a gulp function that will take in one argument, a string, that will be a file or directory that can then feed in to other processes. This string can use glob matching so that *.js will match any .js file and app/**/*.js will match any .js in any folder in the app directory.

The second new thing is .pipe this is a method on the object that gulp.src returns. This will take the files and directories selected in src and then pass or ‘pipe’ them into a function. We pipe the source (which here ./ is our root directory) into the webserver function. So the basic gulp work flow looks like this:

gulp.src(files)
  .pipe(doStuffWithFiles())
  .pipe(doMoreStuffWithFiles());

Sass Processing

Next up is Sass. If you aren’t familiar, Sass is a language that looks like CSS with some added functionality which compiles down into CSS. So go ahead and install some more modules with npm install -D gulp-sass gulp-concat. ‘gulp-sass’ will translate our .scss files into .css and ‘gulp-concat’ lets us concatenate a bunch of files together into one. So we will take all of the .scss files we have and then smoosh them all together in one style.css file.

First make sure you require your new modules in your Gulpfile, so the beginning should now look like this.

var gulp = require('gulp');
var webserver = require('gulp-webserver');
var sass = require('gulp-sass');
var concat = require('gulp-concat');

alright, now we need to make a new task for compiling the Sass and then also include as part of our default task. This code will look like this.

gulp.task('sass', function(){
  gulp.src('sass/*.scss')
    .pipe(sass())
    .on('error', console.log)
    .pipe(concat('style.css'))
    .pipe(gulp.dest('.'));
});

gulp.task('default', ['sass'], function(){
  console.log("Gulp is running!");
  gulp.src('./')
    .pipe(webserver());
});

In the default task, we passed in an array after the first argument. This is an array of all of the tasks we have previously defined that we need to run before we run the task we are currently defining. In this case, gulp will run the task sass and create our stylesheet before running the default task and loading the server.

So in the sass task, after we pipe all of our .scss files (sass/*.scss as long as you are storing your .scss files in a directory called ‘sass’) we handle errors by passing any possible errors from the sass process into console.log so that we can see them. Then we pipe that into the concat function which takes one argument, the name of the file that the concatenated files should have. So our new file will be called style.css.

After this, we see a new function, gulp.dest(). This function is the yin to gulp.src’s yang. It will take all of the files from source, now modified by whatever they have been piped into, into a destination folder, in this case, our root folder. Now we are getting somewhere, but still have one more task to implement.

Watching Files

Watching files for changes and then running tasks is a key feature of a task runner, and it could not be simpler with gulp. We don’t even need a new module for this one, gulp includes its own watch method. All we have to do is add a single line to our default task.

gulp.task('default', ['sass'], function(){
  console.log("Gulp is running!");
  gulp.src('./')
    .pipe(webserver());
  gulp.watch('sass/*.scss', ['sass'] )
});

After our webserver, we call gulp.watch. The first argument here is a file glob like in our gulp.src call, and the second argument is an array of tasks to run when any of the files in the first argument change. So any time an .scss file in our sass directory gets changed, gulp will automatically render it to css, it’s pretty neat. So now our final gulpfile looks like this.

var gulp = require('gulp');
var webserver = require('gulp-webserver');
var sass = require('gulp-sass');
var concat = require('gulp-concat');


gulp.task('sass', function(){
  gulp.src('sass/*.scss')
    .pipe(sass())
    .on('error', console.log)
    .pipe(concat('style.css'))
    .pipe(gulp.dest('.'));
});

gulp.task('default', ['sass'], function(){
  console.log("Gulp is running!");
  gulp.src('./')
    .pipe(webserver());
  gulp.watch('sass/*.scss', ['sass'] );
});

From here there are limitless ways to use Gulp to make your life easier. It can compile coffeescript, lint your code, minify, prettify, optimize images, run test suites and probably 100 other things. And if there is something that you want to do that isn’t available, you can always build it.

Close

Hack Nashville 6 :: Permalink - 11 Nov 2014

I just got back from Hack Nashville this last weekend and had a blast. I ended up partnering up with Code for Nashville with a few of my cohort mates from Nashville Software School. We worked on a pretty neat app called NashViva.

The app was basically “A digital pocketknife for life in Nashville”. You pick an area in Nashville and it populates a map with information that you might find useful, like public wifi, parks, fire departments, and bus stops. I ended up spending most of the time that I could devote working with Leaflet, which is a JavaScript library for easily making and manipulating maps. Making a map is as simple as making a #map element in your HTML and then initializing.

//Initialize the map
var map = L.map('map').setView([36.165818, -86.784245], 13);
//Add the main layer so you can see the map
L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png').addTo(map);

There’s a way to add markers and shapes and a plethora of plugins for it from there, but those are the basics. You can check out the the project and code at NashViva. It’s not yet fully complete, but it’s got a start and we are hoping to build it out from here. A ton of other great projects got built over the weekend as well and it was great to be a part of it. I plan on going next year and would encourage anyone interested in coding, robotics, or anything creative in the digital realm to check it out also.

Close

Conditional Assignment with JavaScript :: Permalink - 04 Nov 2014

The other day while working on a recreation of chess with a few of my cohort mates here at the NSS, I had to constantly find out if, in a 2-dimensional array, if a cell exists. If the outer array did not exist though, the program would fail if I tried to grab the inner array from the undefined value.

So 2dArray[invalidValue][somOtherValue] would crash my JavaScript. Instead of setting up an if statement to check if they outer array exists and then the inner aray exists every time I wished to operate on the grid, i wrote the following little function.

function cellExists(x,y){
  return 2dArray[y] && 2dArray[y][x];
}

Now when this function receives an invalid grid cell, it will return false without crashing the program, but to my surprise it will return the actual cell of x and y instead of true if the cell exists. This actually ended up being more useful for me, because many times I was just checking to see if a cell exists so I could grab a property out of it. So grabbing that property could more simply be…

function getSomeProp(x,y){
  2dArray[y] && 2dArray[y][x] && 2dArray[y][x].someProp;
}

You can also use boolean values like this when assigning variables. If you && it will return the last value if both values of true and if you use || it will return the first value if it is true, or the second value if the first is false, or false if neither are. Below I have some examples.

var foo = someFlag && someVal;
//only sets foo to someVal if someFlag is true
var bar = falseValue || trueValue;
//falsValue is false, so it sets bar to trueValue
var baz = baz || "value not found"
//if baz is undefined or a false value,
//sets itself to "value not found"

Close

Infinite Arrays in JavaScript :: Permalink - 30 Oct 2014

Recently I was working on an implementation of Conway’s Game of Life and I had to create an infinite grid made up of nested arrays. The problem that I soon ran into was hooking the Array’s first element to its last element, or tying it together so it looped.

I came up with the following helper function that will make an Array behave like a fixed length loop of values.

Array.prototype.get(index){
  return this.slice(index%this.length)[0];
}

This might look a little confusing to you, so I’ll break it down. First let me address the two goals of this function for it to successfully make an array infinite.

  • Selecting an element where index is -1, or less than the first element, will give you the last element.
  • Selecting an element where index is array.length, or greater than the last element, will give you the first element.

So the first thing to look here is the argument being passed into slice. This is index%this.length. The modulo remainder of the index and the length of the array (referenced by this while we are inside of this function) will be equal to the index that is passed in, unless it is greater than the index of the last element, in which case it will loop back to the beginning of the array. Look at the following example to understand.

var arr = [1,2,3];
2%arr.length;
// returns 2
3%arr.length;
// returns 0
7%arr.length;
// returns 1

The next piece of this puzzle is the slice function here. Slice returns an array of the array it is called from starting at the first argument with an optional length argument which we will not use. The reason we need slice is it already implements getting elements at indexes that are less than the first element’s index. For example, arr.slice(-1) will return a substring starting at the last value of the array. Since this return value for slice is an array, we need to take the first value, which will be the one we want, by adding [0] at the end.

The one concern here is that the function will never return undefined, which is what we want, but just something to be wary about when using it. You can’t check if a value exists at a certain index with this because it will always return a value in the array. Hope you find this useful and a few demonstrations of its behavior is below.

var arr = ['My','very','eager','mother'];

arr.get(0);
//returns 'My'
arr.get(3);
//returns 'mother'
arr.get(4);
//returns 'My'
arr.get(-1);
//returns 'mother'
arr.get(6);
//returns 'eager'
arr.get(-3);
//returns 'very'

Close

About JavaScript argument passing :: Permalink - 23 Oct 2014

Recently while writing some funky JavaScript code, I noticed an interesting behavior in relation to function arguments. Passing in variables containing primitive values as arguments will not allow the function to change the value of the variable. However, a function that takes in an object as argument has the ability to alter its contents.

Take the following code for example…

var primitiveVariable = 1,
    objectVariable = {value:1};
function mutate(someVariable){
  someVariable.value ? someVariable.value +=1 : someVariable +=1;
}

mutate(primitiveVariable);
mutate(objectVariable);

console.log(primitiveVariable);
//  logs 1, the original value
console.log(objectVariable.value);
// logs 2, which has been changed

This behaves this way because JavaScript does not pass arguments as reference or value every time. It follows a convention called call by sharing. This basically means that the whole value of a variable passed in cannot be changed, but the properties of a variable passed in can be changed. It’s a bit confusing, but it basically boils down to two points.

  • If you attempt to replace the entire contents of an argument variable in a function, it will not change the variable outside of that function’s scope.
  • If you change a property or method on an argument variable in a function, it will propagate outside the functions scope and change the variable globally.

Close

Using Jekyll Collections :: Permalink - 16 Oct 2014

This blog is built on Jekyll which is a ruby static site generator. It compiles markdown and html into a bunch of flatfiles that I can throw up on GitHub, using GitHub pages and have a blog in no time at all. Jekyll provides a way to compile a collection of posts (in a _posts folder) into a list of posts using liquid, their ruby template engine. You can also make your own collections in jekyll with a little bit of configuration.

Jekyll’s liquid engine can iterate through properties in your site in a way similar to handlebars or erb and looks like this for the index of my blog:

<ul>
	{% for post in site.posts %}
		<li>{{ "{{ post.title" }} }}<li>
	{% endfor %}
</ul>

You can also make your own collections that work similarly to the way posts does. Jekyll is pretty well documented and their site shows how to get up and running with custom collections easily. First you need to alter your config.yml and add a line that defines a collections property and then the name of your collections preceded by a hyphen and space underneath. For example:

# Build settings
markdown: kramdown
highlighter: pygments

collections:
- projects

Note the hyphen and space before the collection name must be there or your config.yml will not be parsed. This is because of how yaml handles hashes and you can read about it more here. Now that this is done,you can create a folder in the root directory of your site with the same name as your collection in your config.yml preceded by an underscore, so for this example I would make my collection folder be _projects/

Now I can go ahead and start putting markdown files in my _projects folder and they will be accessible on my pages through the site.projects property as long as I have two sets of 3 hyphens at the beginning of the markdown files for the yaml frontmatter, so this would be an example file called _projects/example-project.md

---
title: "Example Project"
link: http://github.com/colbydehart/example-project
---
This is some text that explains what my cool project does and what technologies
i use to build it, this text is accessible through the `content` property and 
the properties in the front matter can be accessed via their names as well.

So now I have everything setup in my config and have made the collections in the correct folder folder. All that is left is to display the projects on a page. I can go ahead and make a new html file at portfolio/index.html (note the lack of an underscore before this filename) and then iterate through the projects like this:

---
permalink: /portfolio/
layout: default
title: Portfolio
---

<div class="portfolio">
  <h1 class="page-heading">Portfolio</h1>
	<p>These are some projects I have worked on in the past or am currently working on.</p>
	<ul>
		{% for project in site.projects %}
			<li>
				<a href="{{project.link}}">{{project.title}}</a>
				{{project.content}}
			</li>
		{% endfor %}
	</ul>
</div>

These collections are useful in that now, if I am working on a new project I want to share on my website, I would only have to make a simple markdown file for it to be shown with all the others. It also makes everything a little less cluttered in my markup which is something I am a big fan of.

Close

Vanilla Javascript Selecting :: Permalink - 14 Oct 2014

Last week was my first week at Nashville Software School and so far it has been great. We have started out going through some basic HTML, CSS, and JavaScript as well as VIM, git, and the command line and I’ve picked up a few new things so far. One of those, which I hadn’t before dealt with much, is using vanilla Javascript to select elements on the DOM

  • document.getElementById()

Before coming to school I had only used jQuery for DOM selection and manipulation and had completely skipped over any of the built-in document selection methods. The first of these that I learned was getElementById. This method is pretty self-explanatory, it traverses the DOM and grabs the first element with the matching id. The interesting part is the element object it returns. This object has properties like classList, innerHTML, and style that can be directly edited. Being used to setting properties with this with the abstracted jQuery functions like $('#nav-bar').toggleClass('hidden'), it feels a little dirty directly modifying DOM elements like this:

var el = document.getElementById('toggleElement'),
		classes = el.className.split(' '),
		existingIndex = classes.indexOf('hidden');
if (existingIndex >= 0)
	classes.splice(existingIndex, 1);
else
	classes.push('hidden');

el.className = classes.join(' ');

This code was taken from You Might Not Need jQuery, a site that shows vanilla Javascript replacements for simple jQuery functions.

  • document.getElementsByClassName()

This method grabs a group of elements that have the same class name, you can also use the similar function getElementsByTagName for grabbing tags instead of classes. The interesting part of this one is that the object that it returns is not an array, but an HTMLCollection object which does not have any of array’s methods. It can return the length and access objects with bracket notation like a normal array. This can be worked around with a few unattractive solutions (like [].splice.call(els, 0, 1); for example).

  • document.querySelector()

This is the real prize of document’s built-in selection functions. It grabs elements that match a CSS selector passed in as a string in the first argument much like jQuery’s $() function. It returns the same element object as getElementById and you can use querySelectorAll() to get a HTMLCollection instead. With these selectors and the properties of their objects, it is trivial to remove the need for jQuery quite a lot of the time it seems, which I suppose was the idea behind YMNNJ. This isn’t for every situation, but it’s certainly useful and was interesting to learn about.

Close