2013-10-31

Node, Express, MongoDB

Intro

To write this post I used this tutorial. But I adapted it to my own needs. I'm trying to keep some kind of track on how much fuel I spend and what is an average consumption of my vehicle since I commute on a daily basis.

I've set a personal goal to finish this app in a couple of hours no matter what so this example might seem a bit hacky and that's because it is ;)

I won't cover the basics of installing stuff, that's available in the intro part of the above tutorial. Also, I used standard measurement units, perhaps in the next release it would be a nice feature to enable miles and gallons. Let's start

Basic setup

I removed the files that I don't need from the example above. But the basic setup remained pretty much the same.

Please make sure the mongoDB is running and use the testdatabase.js script to check it out, this script will also add some test data to display in the app.

Run it once with node and kill it if a success message is displayed. After getting the project under this link, make sure to run the commands:

 npm install
 node app.js
and see what appears under: http://localhost:3000/ don't forget the mongoDB start - it happend to me and I thought I had errors in jade files!

app.js

I've added register to handle new consumption registrations.

  var register = require('./routes/register');
The register mapping handles the post request to it.
  app.post('/register', register.register(routes.index));

register.js

I'm not sure what's the best way to display the index page after handling the post request, passing in the routes.index callback is probably a hack.

I was surprised how easy it is taking the parameters out of a post request:

        var km = req.body.km;
        var l = req.body.l;
        var d = req.body.d;
Also, monk is making doing stuff with the mongoDB a lot easier. Saving the data looks like:
  var mongo = require("mongodb");
  var monk = require('monk');
  var db = monk('connection_string');

  ...

  var collection = db.get('consumptions');

  collection.insert({
   "km" : km,
   "l" : l,
   "d" : d
  }, function (err, doc) {
   if (err) {
    console.log("Error adding to the database.");
   }
  });

index.jade

The jade templates look very distilled and I really like the easy looping i.e. history output looks like:

  table.history
  each consumption, i in consumptions
   tr
    td= consumption.d
    td= consumption.l + 'l'
    td= consumption.km + 'km'

conclusion

Hopefully I'll have some more free time to work on this technology stack and to make posts about it. As far as I can see a lot has changed since the beginning of the 2013 when I started to play around with node.js.

Anyway here's my example on gitHub, hope you'll like it!

P.S.

I switched to a new job this month. So far a very positive experience I'm learning a ton of new stuff. It has a slight side effect ... I didn't have any time to write any kind of javascript demos or blog posts about them.

I also had to finish the ongoing projects at the old company ... anyway, sorry! That's if there's even anybody reading my stuff :D

2013-09-28

Canvas plasma particles

Intro

One of the things I love the most about the HTML5 canvas are particle systems. For this post I prepared a small but good looking example. One of the colleagues from work even thought that I used some kind of graphical framework to do this and couldn't believe it's just plain old javascript.

The Particle definition

 var Particle = function (ind) {
  // remember the index inside array
  // faster performance on collisions
  this.ind = ind;

  // initial position
  this.x = randomMax(canvas.width);
  this.y = randomMax(canvas.height);

  // random direction vectors
  this.dy = -5 + randomMax(10);
  this.dx = -5 + randomMax(10);

  // radius (small flash in the beginning)
  this.r = randomMax(radiusmax);

  // give it a random color from the set
  this.color = colorSet[Math.floor(Math.random() * colorSet.length)];
 };

Particle draw method

 // reduce the size of the particle down to the minimal size
 // using log function - looks nicer and more organic
 this.r = this.r > miParticleSize ?
  flashfactor * (Math.log(this.r) / Math.LN10)
  : miParticleSize;

 // adjust particle position
 this.y += this.dy;
 this.x += this.dx;

 // check for collision with other particles
 // only on same color
 for (var i = this.ind + 1; i < particleSystem.particles.length; i++) {
  if (distance(this, particleSystem.particles[i]) < criticalDistance 
  && this.color === particleSystem.particles[i].color) {
   this.r = radiusmax;
   particleSystem.particles[i].r = radiusmax;
  }
 }

 // if the particle is outside of the canvas
 // or moving vectors are both 0
 if (this.x < 0 || this.x > canvas.width 
  || this.y < 0 || this.y > canvas.height
  || (this.dy === 0 && this.dx === 0)) {

  // initialize the particle again
  this.x = randomMax(canvas.width);
  this.y = randomMax(canvas.height);
  this.dy = -5 + randomMax(10);
  this.dx = -5 + randomMax(10);
 }

 ctx.beginPath();

 // this is the part that makes people thing it's a framework
 // simple radial gradient
 fillStyle = ctx.createRadialGradient(this.x, this.y, this.r * 0.001,
  this.x, this.y, this.r
 );
 fillStyle.addColorStop(0, this.color);
 fillStyle.addColorStop(1, particleBackground);

 // particle drawing code
 ctx.fillStyle = fillStyle;
 ctx.beginPath();
 ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
 ctx.fill();

Other than helper function and standard shims that's all there is to it.

Firefox issues

I couldn't find why firefox deals so bad with a larger number of particles, essentially everything freezes past 100 particles on firefox. Initialy I thought it's my draw method, but turned out that there's not much to be improved there.

Even when I removed the draw code and let the firefox "draw" the objects with an empty method the performace was still very poor (around 5-6 fps). If you perhaps figured it out or know about some issues please let me know!

And here's my example on:
Codepen

Pi to rad visualization

Intro

Remy Sharp organized a competition to celebrate JS Bin's 5th birthday. In short, there are animated gif images and the people have to write javascript / css to match the gifs. By the time I started trying to figure out the assignments most of the stuff was already solved by these wonderful, incredible and very smart people:

Analysis

An example that looked solvable to me was this one: When I saw it the first time I knew it's going to take a couple of tricks to get the timings right and since I wasn't completely satisfied with the way I solved the number Pi visualization I decided that I had to implement a state machine.

State machine

The usual state machine switches the states cycle by cycle. I modified the concept slightly so that each state checks and maintains the end conditions for the state but the switch happens with a timeout.

In it's end condition every state initiates the transition to the new state. Please not that the state will not be changed immediately and that the code for state change will be called multiple times. In order to avoid quirky behavior I used a simple flag named newState so that the timeout for the new state is actually set only once avoiding multiple timeouts.

An important feature of setTimeout function is that it doesn't maintain the this context so I had to apply the usual that equals this pattern.

 PiRad.prototype.changeState = function (newState, timeout) {
   var that = this;
   (function() {
     if (newState !== this.nextState) {
       setTimeout(function() {that.state = newState;}, timeout);
       this.nextState = newState;
     }
   })();
 };

Sticking the straight red line to the circle

Another challenge I had to face was transforming the straight line into a part of circumference. I gave this a lot of thought and came to a conclusion that this wood look best if I moved the end slowly to the destination on the circle and bind the beginning with a quadratic curve.

 // from stickRedLineToCircle state

 // move the dot to the destination
 this.movingCenter.x -= 2;
 this.movingCenter.y += 0.7;

 // from drawRedDotWithMovingCenterCurved function

 // end coordinates of a top
 var endx = ~~(cwidth / 2 + Math.cos(-1) * this.r);
 var endy = ~~(cheight / 2 + Math.sin(-1) * this.r);

 // calculate the distance 
 var distance = ~~(Math.sqrt(
  Math.pow(endx - this.movingCenter.x, 2) 
  +
  Math.pow(endy - this.movingCenter.y, 2))
 );

 // this factor came out from a lot of try and fail
 var factor = 1.12 + distance / 400;

 // Bézier control point
 var x = ~~(cwidth / 2 + Math.cos(-0.5) * this.r * factor);
 var y = ~~(cheight / 2 + Math.sin(-0.5) * this.r * factor);

 // drawing code
 ctx.lineWidth = 2;
 ctx.beginPath();
 ctx.moveTo(this.movingDot.x, this.movingDot.y);
 ctx.quadraticCurveTo(x, y, this.movingCenter.x, this.movingCenter.y);
 ctx.stroke();

And here's my example on:
JS Bin
Codepen

Number Pi visualization

Intro

Remy Sharp organized a competition to celebrate JS Bin's 5th birthday. By the time I started trying to figure out the assignments most of the stuff was already solved by these wonderful, incredible and very smart people:

Analysis

Another example that looked solvable to me was this one: This example is more about timings and matching colors and shapes while the math is pretty straight forward and relatively simple.

Drawing Markers

The markers on the animation all have pretty diamond shapes. To draw them I used this function:

  function drawMarker(x, y, color) {
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(x - 10, y - 20);
    ctx.lineTo(x, y - 40);
    ctx.lineTo(x + 10, y - 20);
    ctx.closePath();
    ctx.fillStyle = color;
    ctx.fill();
  }

Drawing the Wheel

To spin and move the wheel around I used simple HTML5 canvas constructs translate and rotate. I just pretty much had to draw the wheel once and the rest was handled with those functions. The tricky parts are drawing the circumference in red color and leaving the trail.

It turned out this wasn't that complicated. The wheel will spin for an angle of 2 * Pi so in each animation iteration the angle property was increased, the wheel was rotated and the circumference was just drawn up to the angle value that the wheel traveled. At the same time the trail is straighten and calculated to that angle. It's much better to show it with the code:

  var maxAngle = angle >= 2 * Math.PI ? 2 * Math.PI : angle;

  ctx.translate(startx + 2 * angle * r, fixedy);
  ctx.rotate(angle);

  // red trail around the circle
  ctx.beginPath();
  ctx.arc(0, 0, 73, Math.PI / 2, 2 * Math.PI - maxAngle + Math.PI / 2);
  ctx.stroke();

  // red trail on the ground
  ctx.beginPath();
  ctx.moveTo(fixedx, fixedy);
  ctx.lineTo(startx + 2 * maxAngle * r, fixedy);
  ctx.stroke();
 
other than that it's all try, analyze, draw again loop.

And here's my example on:
JS Bin
Codepen

tan function visualization

Intro

Remy Sharp organized a competition to celebrate JS Bin's 5th birthday. All of the details can be found under this link. A lot was going on in my life at the time when the competition was opened so I didn't think I'll even catch an opportunity to solve some of the assignments that were posted. By the time I started trying to figure out the examples most of the stuff was already solved by these wonderful, incredible and very smart people:

Tan function

I started looking at the posted assignments and crosschecking if some of them were already solved. I found that this one still wasn't solved. Since it looked solvable to me I gave it a go. I've spent most of the evening analyzing the movement, drawing triangles, calculating the angles, making canvas experiments. At one point I came to a conclusion that the moving dot is nothing more than a representation of a tan function and felt a bit stupid because it should have been obvious!

Implementation

After I figured out it was a tan function the hard way, everything was pretty easy. All of the code is essentially here:

   // spin the circle around
   angle = (angle + dangle) % ( 2 * Math.PI);  

   // calculate the green dot position
   anglex = Math.cos(angle) * circlehalf;
   angley = Math.sin(angle) * circlehalf;
   drawdotx = circlex + anglex;
   drawdoty = circley + angley;
   
   // calculate the connecting points on the graph
   linex = circlehalf / Math.tan(angle);
   linex2 = circlehalf / Math.tan(angle + Math.PI);

The trick

The only tricky part was with drawing the graph. Because connecting the graph algorithmically caused the unexpected line to appear every time the dot switched from positive to negative infinity. But it turned out it could all be solved with a simple if statement:

     for (var i = cheight; i > 0; i-- ) {
      ctx.beginPath();

      ctx.moveTo(circlex - linex, cheight - hsplit - i - 1);

      linex = circlehalf / Math.tan(angle - i * dangle);

      ctx.lineTo(circlex - linex, cheight - hsplit - i);

      // avoids drawing a connection between +/- infinity
      if ((circlex - linex) < cwidth) {
        ctx.stroke();
      }

    }
 

And here's my example on:
JS Bin
Codepen

2013-08-11

Canvas Disco Rain

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers
  7. DIY Canvas Fountain
  8. Canvas Random Spherical Effects
  9. Canvas Ant Colony Optimization
  10. Canvas Space Battle
  11. Canvas Simple Game

Canvas Disco Rain

The idea behind it is pretty random. I saw a couple of demos about rain falling and stars moving in the space and thought ... why not make it a bit more "funky" :) Every drop is glowing while falling and there is an option to show all drops in the same color or display them random.

Flash math

The flash is modeled with a help of a logarithmic function. The flash starts at it's maximum size and then decays reaching 0. When the flash reaches 0 it starts to glow again. To add a bit more noise to example it expands to a random width. There is also a Flash Factor so that we can influence the general length of a burst.

 this.r = flashfactor * (Math.log(this.r) / Math.LN10);

 if (this.r <= 0) {
  this.r = randomMax(radiusmax);
 }

Flash looks

Every flash is brightest at it's middle and then darker the further away from the center. To achieve this effect a gradient is used:

 ctx.beginPath();

 var fillStyle = ctx.createRadialGradient(
  this.x,
  this.y, 
  this.r * 0.2, 
  this.x, 
  this.y, 
  this.r
 );
 
 fillStyle.addColorStop(0, this.color);
 fillStyle.addColorStop(1, particleBackground);

 ctx.fillStyle = fillStyle;
 ctx.beginPath();
 ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
 ctx.fill();

The light properties of flash emitting body, human eye or camera lens cause us to perceive the flashes with a cross centered in the middle of the flash. This animation rotates this angle to add a bit more randomness to the example (it looks nicer). The cross drawing code looks like this:

 ctx.strokeStyle = this.color;
 
 ctx.beginPath();
 ctx.moveTo(
  this.x - Math.cos(this.angle) * this.r,
  this.y - Math.sin(this.angle) * this.r
 );
 ctx.lineTo(
  this.x + Math.cos(this.angle) * this.r,
  this.y + Math.sin(this.angle) * this.r
 );
 ctx.stroke();

 ctx.beginPath();
 ctx.moveTo(
  this.x - Math.cos(this.angle + Math.PI / 2) * this.r,
  this.y - Math.sin(this.angle + Math.PI / 2) * this.r
 );
 ctx.lineTo(
  this.x + Math.cos(this.angle + Math.PI / 2) * this.r,
  this.y + Math.sin(this.angle + Math.PI / 2) * this.r
 );
 ctx.stroke();

We use gradients, but the flash is in the end just a circle shrinking. That causes one flashes light to "cover" the light of the other flash and we all know this is not happening in the real world. To compensate for that we use the globalCompositeOperation on the 2d canvas context. Explaining this is a bit out of the scope of this post, put there is a very nice code pen explaining that made by aptary. Disco rain uses 'lighter' mode:

 ctx.globalCompositeOperation = 'lighter';

And here's my example on:
CSSDeck
Codepen

Canvas Simple Game

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers
  7. DIY Canvas Fountain
  8. Canvas Random Spherical Effects
  9. Canvas Ant Colony Optimization
  10. Canvas Space Battle

Canvas Simple Game

I hope I'll develop some kind of "serious" game in the future, but as always the first steps are pretty modest. The Canvas Simple Game is sort of a testing playground for a Shoot 'Em Up Game type. Also, @loktar00 had an idea about growing this example to "online shmup creator". Most of the techniques used in this example are described in the previous posts. So I won't cover the basics as much. The stuff I researched the most for this example is javascript keyboard event handling. So I'll concentrate on that.

Keyboard events javascript style

Since the games usually require more of the keys pressed at the same time I've developed a simple example. Every key has it's state stored in an associative array. The keydown and keyup events can have multiple keys pressed at once, so on every key up or down the key state is changed:

  var activeKeys = [];

  function setKeysTo(e, state) {

   if(e.keyCode == 37) {
     activeKeys['left'] = state;
   } else if(e.keyCode == 39) {
     activeKeys['right'] = state;
   }  else if(e.keyCode == 38) {
     activeKeys['up'] = state;
   } else if(e.keyCode == 40) {
     activeKeys['down'] = state;
   } else if (e.keyCode == 32) {
     activeKeys['shoot'] = state;
   }

   return false;
  }

  document.onkeydown = function(e) {
   return setKeysTo(e, true);
  };

  document.onkeyup = function(e) {
   return setKeysTo(e, false);
  };

Now the application logic can check for key combinations and update stuff in the animation loop. The displayed code might be a bit redundant but it's down to the point. Perhaps this blog entry name could be javascript multiple key events handling :)

And here's my example on:
Codepen

CSS Windmill

CSS Windmill

I always wanted to make a pen with pure css and I always wanted to make a pen about windmills. So, I've created the CSS windmill.

Animation parts

I'll just show HAML code used to crate the animation:

 #windmill
  .post
  .engine
  .flaps
   .flap
   .flap
   .flap
  .head
  .bulb
 

Flaps

Flaps is a big div containing the flaps. It moves around with this simple animation (I just love css animations):

 @keyframes "rotatemill" {
  0% {
     transform:rotate(0deg);
  }
  100% {
     transform:rotate(-360deg);
  }
 }

Rounding flap tops

This is so much easier with the css (just one line of code and so much magic):

 border-top-left-radius: 5px 20px;

Light

The light on top is an ordinary circle. To keep it simple, I've put it in the back so that it looks like a half circle :) and all the magic is contained in this animation:

 @keyframes "lightbulblight" {
  0% {
     background: $bulbcolor;
     box-shadow: 0 0 0 $bulbcolor;
  }
  50% {
     background: lighten($bulbcolor, 60%);
     box-shadow: 0 0 $bulbLight lighten($bulbcolor, 60%);
  }
 }

And here's my example on:
Codepen

Canvas Space Battle

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers
  7. DIY Canvas Fountain
  8. Canvas Random Spherical Effects
  9. Canvas Ant Colony Optimization

Canvas Space Battle

I always liked watching Star Trek. The thing I love the most are space battle scenes. Especially the ones that are on the epic scales :)

Ship types

The battle is between the Cardassian, the United Federation of Planets and the Romulans. Every race has it's own ship property, for instance:

 shipTypes.push({
  color : '#CAD8DB',
  warpTrailColor : 'rgba(141, 189, 240, 0.5)',
  trailLife : 30,
  impulseSpeedMax : 3,
  newDirectionCycle : 40,
  warpCycleMin : 350,
  warpCycleVar : 900,
  range : 33,
  fireColor : 'rgba(237, 209, 133, 0.8)',
  fireRecharge : 40,
  fireDischarge : 10
 });

Why Warp trails?

The tactical warp jumps are inspired by the following wiki:

In 2355, the Stargazer was seriously damaged in a battle with an unknown enemy vessel, later discovered to be a Ferengi ship. Picard managed to destroy the enemy vessel using the Stargazer's warp engines in a unique tactical maneuver (later named the "Picard Maneuver").

Ship movement

Ship movement is based upon a counter, every time the counter drops to zero the ship selects new direction to move to and resets the counter. There is a second counter (with substantially greater value) that's in charge for the warp jump. Upon jumping to warp the ship moves to random new coordinates and leaves a warp trail.

Warp trails

Warp trails are stored in linked list because storing them in arrays would perhaps be to operation heavy especially if the number of the ships would increase or the warp jumping interval would shorten for a certain race. The other advantage is that every trail can remove itself from the animation loop upon its end of life.

Phaser fire

Phaser firing is determined by counters. There is impulse duration counter and time between phaser pulse counter. It's race specific and configurable. When shooting there is small random offset so that if the other ship is shooting back the trail is still visible.

And here's my example on:
Codepen

Canvas Ant Colony Optimization

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers
  7. DIY Canvas Fountain
  8. Canvas Random Spherical Effects

Canvas Ant Colony Optimization

The inspiration for this animation came from a youtube video. In short, the ants explore various paths and leave pheromone trails. Over time the most efficient trails have the greatest amount of pheromones and the ants tend to follow that paths.

Graph creation

I've spent most of the development time for this example on the graph creation part. I wanted to create an algorithm that would turn an imaginary table into graph. Every joint has to have at least one exit point and no connections should cross over. Also, the connections are formed just between the neighbouring imaginary columns. In the development process I've found two variations of connection knitting. To keep the post as short as possible, I'll just show the upper knitting:

 var minPossible = 0;

 for (i = 0; i < jointsBefore.length; i++) {

  selection = randomInInterval(minPossible, possibleNodes.length - 1);

  if (selection > minPossible) {
   minPossible = selection;
  }

  jointsBefore[i].connections[0] = possibleNodes[selection];
  newConnectedNodes[selection] = true;

  selection = randomInInterval(minPossible, possibleNodes.length - 1);

  if (selection > minPossible) {
   minPossible = selection;
  }

  if (jointsBefore[i].connections[0].id !== selection) {
   jointsBefore[i].connections[1] = possibleNodes[selection];
   newConnectedNodes[selection] = true;
  }
 }

Ant path selection

Upon every node selection we're checking if the ant is exploring (going to path with lesser pheromones level) or taking the more visited path. And that's all:

 var selectedNode;

 if (joint.connections.length > 1) {

  if (Math.random() > globals.explorationProbability) {
   selectedNode = joint.selections[0] >= joint.selections[1] ? 0 : 1;
  } else {
   this.exploring = true;
   selectedNode = joint.selections[0] <= joint.selections[1] ? 0 : 1;
  }
  
 } else {
  selectedNode = 0;
 }

 this.destination = joint.connections[selectedNode];
 joint.selections[selectedNode]++;
 this.orientToPoint(this.destination);

And here's my example on:
Codepen

Canvas Random Spherical Effects

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers
  7. DIY Canvas Fountain

Canvas Random Spherical effects

The main motivation for this was making demo with particles that leave trails. To move the particles around a simple sphere equation is used. An important part of this demo is "dat.gui".

Leaving particle trails

There are several techniques for the particles to leave trails. I won't go into them now but one of the simplest is using transparent rectangles to clear the canvas in the animation loop. The transparent rectangle has a color of the desired background. The more the clearing rectangle is transparent the longer particles trails are. Just two lines of code in the animation loop do all the magic (usually it's a very small number and one has to experiment with it):

 var trailLength = 0.08;
 (function animloop(){
  requestAnimFrame(animloop);
  ctx.fillStyle = 'rgba(1, 1, 1, ' + trailLength + ')';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

Sphere math

To make the things as simple as possible the particles are moved around with the help of angle coordinates. The drawing of particles is from then on just a couple of equations:

 this.xangle += angleSpeedx;
 this.yangle += angleSpeedy;
 // size factor is responsible for 3d effect
 var sizeFactor = (0.5 + (Math.cos(this.xangle) + 1) / 2);
 ctx.arc(
  centerx +
    ~~((Math.sin(this.xangle) * Math.cos(this.yangle)) * sphereRadius),
  centery +
    ~~((Math.sin(this.xangle) * Math.sin(this.yangle)) * sphereRadius),
  particleSize * sizeFactor, 
  0,
  Math.PI * 2
 );

And here's my example on:
Codepen

DIY Canvas Fountain

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers

DIY Canvas Fountain

Particle fountains are very common inspiration for the graphical demos. To be honest I didn't feel I had much to contribute to this area. Then It came to me that perhaps it would be a nice demo to build an interface that would enable the users to construct their very own fountain. An important part of this demo is "dat.gui".

Mouse events

Handling the mouse events is the backbone of this demo. Two basic events are mousedown and mousemove. First, we have to register our functions to the events:

 canvas.addEventListener.apply(canvas, ['mousedown', mouseClick, false]);
 canvas.addEventListener.apply(canvas, ['mousemove', mouseMove, false]);

Mouse coordinates

As a parameter to the above registered function an event is passed. The event has coordinates clientX and clientY, but the coordinates are not corresponding to the coordinates on the canvas, so there is a short pattern that we have to apply to convert event coordinates to canvas coordinates:

 var mouseX = event.clientX - document.documentElement.scrollLeft 
     - canvas.offsetLeft;
    var mouseY = event.clientY - document.documentElement.scrollTop 
        - canvas.offsetTop;

Particle physics

Every particle is fired at an angle with initial speed. This is 2D space, so we'll split the speed into two parts. After that on every draw call we'll update the coordinates.

 this.dx = speed * Math.cos(angle - Math.PI / 2);
 this.dy = speed * Math.sin(angle - Math.PI / 2);
 // and then in the draw function
 this.x += this.dx;
 this.y += this.dy;

Gravity

Gravity is an important part of this example. I've given a lot of thought on how to simulate it and found a simple solution. Since the gravity is a force the falling speed has to increase over time. The simplest method is to increase the y speed with a gravity constant ... as simple as one line:

 this.dy += fountainProps.gravity;

And here's my example on:
Codepen

2013-06-02

Canvas Wipers

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks

Canvas Wipers

The inspiration for this animation came from a wiki page about windscreen wipers. In short, there is one central motor and both wipers are connected to it. The motion range of a single wiper is influenced by the positioning, linkage length and leaver radius. The real wipers contain a lot more parts than this abstracted version does, but none the less, it makes for a pretty interesting animation. Getting all the lengths and positions for elements in this animation was the hacky part of the whole story and this blog entry won't be about that.

Motor to leaver

The motor arm has two linkages connected to the leavers of both wipers. Determining the motor arm position is pretty straight forward and we only need the sin and cos function to do that. But connecting the linkages to wiper leavers requires a bit more math. Basically the motor arm position becomes center of a circle with a radius equal to the length of a linkage. The second circle is the one with the wiper body screw in the center and a radius equal to the wiper leaver length. The leaver and then the wiper position is determined by the intersection of the two circles. In short it's very well explained in the "Intersection of two circles" section of this article.

Leaver to wiper

There is an offset in the angle from leaver position to the wiper position. At the moment the only known data is the intersection of the two circles mentioned above. Turning this into an angle requires two steps.

  • Calculating the distance from the 0 point to the connecting point
  • Calculating the angle

In the code it looks like this (2x is because of the triangle relations and Math.PI * 4 / 5 is the angle delta):

 var circledist = distance(
  leftWiperX - leftWiperLowerHandleR,
  leftWiperY,
  joinLeftX,
  jointLeftY
 );

 var dAngleL = 2 * Math.acos(circledist / (2 * leftWiperLowerHandle)) 
  + Math.PI * 4 / 5;

Wiper blade

After getting the angle getting the the wiper blade is pretty much a parallel line to the wiper carrier. That's just plain old math. To reduce the complexity of an example, a small trick is used. The coordinates of top and bottom of the wiper blade are calculated relative to the wiper carrier length, it's described with this code:

 var wiperFlipLTopX = leftWiperX 
  + Math.cos(dAngleL) 
   * (wiperCarrierLength * wiperFlipUpperRatio);

 var wiperFlipLTopY = leftWiperY 
  + Math.sin(dAngleL) 
   * (wiperCarrierLength * wiperFlipUpperRatio);

 var wiperFlipLBottomX = leftWiperX 
  + Math.cos(dAngleL) 
   * (wiperCarrierLength * wiperFlipLowerRatio);

 var wiperFlipLBottomY = leftWiperY 
  + Math.sin(dAngleL) 
   * (wiperCarrierLength * wiperFlipLowerRatio);

And here's my example on:
CSSDeck
Codepen

2013-05-25

Canvas, circular motions and networks

Intro

Here's another post in the "canvas drawing series". The previous posts usually had only one example, this one will be about three examples. You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains

Oil pump jack

The parts are named after this wiki page describing the functioning of an oil pump jack. On every animation frame the angle of an engine is increased by a fixed amount making the circular motions of the engine. The engine rotation is pretty simple and is using just the cos and the sin mathematical function.

Determining the height of a walking beam is a bit more complicated and needs to be done in two steps. In the first one the joint on the engine crank is found by this code:

  var crankJoinX = engineX + Math.cos(angle) * engineCrankL * 0.7;
  var crankJoinY = engineY + Math.sin(angle) * engineCrankL * 0.7;
The second is to determine the pitman arm position. With engineX and engineY being the center of the rotation for the crank. The pitman arm always has a fixed x coordinate. With having a fixed rod length the height is determined by this formula:
  var pitmanY = crankJoinY - Math.sqrt(Math.pow(rodLength, 2) 
   - Math.pow(crankJoinX - engineX, 2));

Pump jack's head has a certain curve enabling it to always pull the polished rod straight up. The math behind it is a bit more complicated than calculating the pitman arm position:

  ctx.arc(
   samsonPostX,
   samsonPostY,
   beamHalfLength + headWidth,
   Math.asin((samsonPostY - pitmanY) / beamHalfLength),
   Math.asin((samsonPostY - pitmanY + headNoseHeight) / beamHalfLength)
  );

Oil pump jack - Codepen
Oil pump jack - GitHub

Particle Tornado

This one seems to be a very popular example. It even got mentioned on twitter by David Walsh:

Believe it or not it's actually quite easy to code. Everything we need is contained in this function:

  Particle.prototype.draw = function () {

   // change particle position
   this.angle += angleSpeed;
   this.h -= verticalSpeed;

   // if the particle is outside of canvas
   //make it appear back on random position
   if (this.h < 0 || this.h > canvas.height) {
    this.h = Math.floor(canvas.height * Math.random());
   }

   ctx.beginPath();
   ctx.fillStyle = singlecolor ? defaultColor : this.color;
   // single line of code makes it look like 3d
   var sizeFactor = 0.5 + (Math.sin(this.angle) + 1) / 2;
   ctx.arc(
    canvas.width / 2 + Math.cos(this.angle) 
     * (canvas.height - this.h) / widthFactor,
    this.h,
    particleSize * sizeFactor, 0, Math.PI * 2);
   ctx.fill();
  };
The rest of the code is just fancy stuff mentioned in the previous posts.

Particle Tornado - Codepen
Particle Tornado - GitHub

Neurons

The neurons have random placing on the canvas. But connecting them at random makes a very "noisy" and ugly example. To avoid this mess a simple algorithm is used. One by one we're finding the nearest neuron having no connection to the current neuron:

  for (i = 0; i < this.neurons.length; i++) {
   for (var j = 0; j < this.neurons.length; j++) {

    if (i !== j) {

     // take first neuron not being the current one
     if (typeof pickedNeuron === 'undefined') {
      pickedNeuron = this.neurons[j];
     }

     // compare the distances to other neurons
     if (distance(this.neurons[i], this.neurons[j]) <
       distance (this.neurons[i], pickedNeuron)) {
       
      if (this.neurons[j].soma && this.neurons[j].id !== i) {
       pickedNeuron = this.neurons[j];
      }
     }
    }

   }
   this.neurons[i].soma = pickedNeuron;
   pickedNeuron = undefined;
  }

Every neuron has its own counter making it switch between active and inactive state. To make the example more interesting a firing neuron also fires the neuron connected to it.

Neurons - Codepen
Neurons - GitHub

2013-04-29

Canvas Trains

Intro

This is the fourth post in the "canvas drawing series". This one is about a small railway system and the trains directed by the control tower. I won't cover the basics of drawing etc. because it's done in the previous posts on the canvas:

  1. Canvas Bus
  2. Canvas Crossroad
  3. Canvas Balloons
Most of the techniques and patterns are also described in the previous posts, so I'll kind of concentrate only on the specifics of this example.

Rotating cars depending on the current rail line

Calculating the car angle depending on the current rail line:

  Rail.prototype.toAngle = function (x) {

   for (var i = 0; i < this.railLines.length; i++) {
    // find the rail line
    if (this.railLines[i].x1 <= x && x <= this.railLines[i].x2) {
     // calculate the angle
     var dy = (this.railLines[i].y2 - this.railLines[i].y1);
     var dx = (this.railLines[i].x2 - this.railLines[i].x1);
     
     return Math.atan2(dy, dx);
    }
   }

   return 0;
  };

Canvas text output

There are a couple of catches when working with canvas text. The first one is using the textBaseline property. The other is calculating the actual text width on a canvas used to center the text about train queue in the middle:

  ctx.fillStyle = textColor;
  ctx.font = '20px arial';
  var text = 'Sample text';
  var metrics = ctx.measureText(text);
  console.log(metrics.width);

The rail system

The rail system is made relative to the available canvas space:

  var RailSystem = function () {
   this.rails = [

   new Rail(0, [
    new RailLine(0, height/2, width/9, height/2)
   ]),
   new Rail(1, [
    new RailLine(width/9, height/2, width * 2/9, height/3),
    new RailLine(width * 2/9, height/3, width * 3/9, height/3),
    new RailLine(width * 3/9, height/3, width * 4/9, height/2)
   ]),
   new Rail(2, [
    new RailLine(width/9, height/2, width * 4/9, height/2)
   ]),
   new Rail(3, [
    new RailLine(width/9, height/2, width * 2/9, height * 2/3),
    new RailLine(width * 2/9, height * 2/3, width * 3/9, height * 2/3),
    new RailLine(width * 3/9, height * 2/3, width * 4/9, height/2)
   ]),
   new Rail(4, [
    new RailLine(width * 4/9, height/2, width * 5/9, height/2)
   ]),
   new Rail(5, [
    new RailLine(width * 5/9, height/2, width * 6/9, height/3),
    new RailLine(width * 6/9, height/3, width * 7/9, height/3),
    new RailLine(width * 7/9, height/3, width * 8/9, height/2)
   ]),
   new Rail(6, [
    new RailLine(width * 5/9, height/2, width * 8/9, height/2)
   ]),
   new Rail(7, [
    new RailLine(width * 5/9, height/2, width * 6/9, height * 2/3),
    new RailLine(width * 6/9, height * 2/3, width * 7/9, height * 2/3),
    new RailLine(width * 7/9, height * 2/3, width * 8/9, height/2)
   ]),
   new Rail(8, [
    new RailLine(width * 8/9, height/2, width, height/2)
   ])

   ];
  };

Train states

Every train goes trough the following states:

  • Creation - dat.gui controlled (counter) on every drop to zero and free entry rail
  • firstTurn - takes random free rail and goes into queue for the middle rail
  • waitingForMiddle - remains in this state until the middle rail is free for it to pass
  • goIntoMiddle - goes to the middle rail and passes trough
  • pickWayOut - waits on the trains going out and picks a rail going out of the rail system
  • goToExit - performs the exit, cleans the data describing the train

The states are self explanatory but the transitioning logic is a bit complex and it'll not be listed. But feel free to look the states up in the source code provided.


And here's my example on:
Codepen
GitHub

2013-04-13

Canvas Bus

Intro

This is the third post in the "canvas drawing series". This one is about bus picking up passengers and distributing them to their destinations. I won't cover basics of drawing etc. because it's done in the previous posts on the canvas:

  1. Canvas Crossroad
  2. Canvas Balloons
The main difference to the previous examples is that this one makes a complete redraw every time because there would be a lot of sprite redrawing and recalculating to remove all of the last states of sprites. Also, keep in mind that the browser does a very good job of repainting and keeps an internal off-screen canvas so you don't have to. The animation loop and sprite drawing of this example is in fact pretty simple:
  (function animloop(){
   requestAnimFrame(animloop);

   ctx.clearRect(0, 0, canvas.width, canvas.height);

   sim.draw();
  })();
There are four main entities involved in this simulation:
  • Passengers
  • Bus
  • Stations
  • Simulation master

Passengers appear on the stations in regular intervals and wait in the queue for the bus to pick them up. Their destination is denoted by their color, so the passenger appearing on the station always have a color different then the color of the station. The algorithm for color picking is listed at the end of this post.

Bus is drawn with simple geometric shapes and has an aisle and seats for the passengers. There is a separate space for the driver, the door and blinkers for signalization to the rest of the traffic. The bus has fixed loading time, but if it becomes full it's going to leave the station.

Stations are represented by their waiting queues plus the loading and unloading spot. As mentioned before the new passenger arrival interval is linear, but can be very easily configured to take some kind of arrival event time distribution, since the main focus is on the canvas drawing it's just plain simple linear time. Every station has a capacity, so no new passengers arrive when the station is full.

Simulation master is the god object of this simulation and directs the bus around and tells it when to load, unload passengers and syncs it with the stations. It's the usual way of doing this type of simulations.

Passengers loading

The standard bus has an aisle and seats. In every draw cycle while loading the passengers the simulation checks if the station has passengers to load. Before the passenger enters, the bus assigns a seat to the passenger by using this function:

  function toXY(seat) {
   var x = this.rightLine;

   if (seat % 2 === 0) {
    x = this.leftLine;
   }
   var y = this.startingRow + Math.floor(seat / 2) * passengerSize;

   return {
    x : x,
    y : y
   };
  }

The loading passenger then goes trough the following states:

  • outside - ends by going to the beginning of the aisle
  • upTheLane - ends by reaching the destination row
  • takeSeat - the passenger takes the left or the right seat

It's all better described with the following code listing:

  if (state == 'outside') {
   if (loadingPassenger.x + passengerSpeed <= middleLine) {
    loadingPassenger.x = middleLine;
    loadingPassenger.state = 'upTheLane';
   } else {
    loadingPassenger.x -= passengerSpeed;
   }

  } else if (state == 'upTheLane') {
   if (loadingPassenger.y + passengerSpeed >= 
     toXY(loadingPassenger.destinationSeat).y) {
    loadingPassenger.y = toXY(loadingPassenger.destinationSeat).y;
    loadingPassenger.state = 'takeSeat';
   } else {
    loadingPassenger.y += passengerSpeed;
   }

  } else if (state == 'takeSeat') {
   var dx = passengerSpeed;
   var destinationSeat = toXY(loadingPassenger.destinationSeat);
   if (destinationSeat.x == leftLine) {
    dx = -dx;
   }
   if (loadingPassenger.x + dx <= leftLine 
     || loadingPassenger.x + dx >= rightLine) {
    loadingPassenger.x = destinationSeat.x;
    passengers[loadingPassenger.destinationSeat] = loadingPassenger;
    loadingPassenger = null;
   } else {
    loadingPassenger.x += dx;
   }
  }

Unloading passengers

In every draw cycle while the bus is in the station there is a check for unloading passengers, basically a check if there are passengers in the bus with the color of the current station. Every unloading passenger goes trough the following states:

  • stepToLineL or stepToLineR - depending on the taken seat
  • goToDoor
  • getOut
The code is similar to the unloading code so theres no need to list it here.

Bus and Station

Drawing a bus and a station is pretty straight forward. To make the object drawing as simple as possible and to keep everything relative to the front left corner of a bus and to the loading unloading spot of the station we rotate and translate the whole canvas context. After that all of the drawing is done relative regardless of the current object orientation and position. The alternative would be complex 2d computation but thanks to the canvas it's pretty simple and one can concentrate on the drawing logic. The pattern enabling relative drawing with rotation is listed bellow:

  ctx.save();

  ctx.translate(this.x, this.y);
  ctx.rotate(this.angle);

  // relative drawing code

  ctx.restore();

Simulation master

The simulation master has the following states:

  • busInStation
  • busLeaving
  • busTraveling
  • unloadPassangers
  • waitForUnload

The states are self explanatory but the transitioning logic is a bit complex and it'll not be listed. But feel free to look the states up in the source code provided.

The one important thing that should be mentioned is the way the initial passenger color is chosen. Basically it depends on the current station color and all other station colors are all right. Then we are picking a random color from a set until we pick the color that isn't the color of the station. Note that a couple of cycles might pass since we have a new color but writing a complex pseudo random function would just complicate things so the simulation uses the following function:

  function randomColor(differentThan) {
   if (differentThan) {
    do {
     var color = stationColors[
      Math.floor(Math.random() * stationColors.length)
      ];
     if (color !== differentThan) {
      return color;
     }
    } while (true);
   }

   return stationColors[Math.floor(Math.random() * stationColors.length)];
  }
 

dat.gui

When experimenting with graphics and simulations it's best practice to provide a user with some kind of interface for changing variables. There is a small library for creating variable modifying interfaces called "dat.gui". I've found a very interesting and short tutorial about it under dat.gui.


And here's my example on:
Codepen
GitHub

2013-03-30

Canvas Balloons

Canvas

Basic usage of the HTML canvas element is covered in the Canvas Crossroad post.


Picking colors

Balloons in the night look pretty awesome, although it's generally not advisable to fly them at night. The Balloons are displayed in various random colors, but the basic color has to be dark. The RGB color code describes the intensity of each color component. In order to keep the colors dark, one has to limit the amount of each color intensity to a rather low level. (in this case up to 50 from possible 255).

 function getBalloonColor() {

  var r = randomInt(50).toString(16);
  var g = randomInt(50).toString(16);
  var b = randomInt(50).toString(16);

  r = r.length < 2 ? '0' + r : r;
  g = g.length < 2 ? '0' + g : g;
  b = b.length < 2 ? '0' + b : b;

  return '#' + r + g + b;
 }

While the balloon changes climbing state it's color has to be darken or lighten by some percentage to simulate the flame. It's done by this function:

 function shadeColor(color, percent) {

  var num = parseInt(color.slice(1),16),
   amt = Math.round(2.55 * percent),
   R = (num >> 16) + amt,
   B = (num >> 8 & 0x00FF) + amt,
   G = (num & 0x0000FF) + amt;

   return "#" + (0x1000000 +
    (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
    (B < 255 ? B < 1 ? 0 : B : 255) * 0x100 +
    (G < 255 ? G < 1 ? 0 : G : 255)).toString(16).slice(1);
 }

The color of a climbing balloon should be darker further away from the flame. So a gradient is used. The HTML canvas gradient works only within a predefined range on a canvas. The example bellow shows a linear gradient from the top to the bottom of a balloon. Notice that the horizontal component is set to 0 (this is a vertical linear gradient):

 var linGrad = ctx.createLinearGradient(0, this.y, 0, this.y + this.height);

 linGrad.addColorStop(0, ballonColor);
 linGrad.addColorStop(1, shadeColor(ballonColor, ballonFlameLighter));

 ballonColor = linGrad;


Balloon shape

The balloon shape is drawn with

  • half circle
  • triangle
  • flame - small circle
  • basket - small rectangle
Since the balloons are moving, we have to repaint the sprite. I've simply used the same function for drawing with canvas background color instead of the balloon parts colors. If a clearRect method had been used the transition of a balloon over a star would look unnatural.
  // top balloon circle
  ctx.beginPath();
  ctx.arc(this.x + this.width / 2, this.y + this.radius,
    this.radius, Math.PI, 0, false);
  ctx.fill();

  // triangle
  ctx.beginPath();
  ctx.moveTo(this.x, this.y + this.radius - 1);
  ctx.lineTo(this.x + this.width / 2, this.y + this.height - this.boxHeight);
  ctx.lineTo(this.x + this.width / 2 + 1, this.y + this.height - this.boxHeight);
  ctx.lineTo(this.x + this.width, this.y + this.radius - 1);
  ctx.lineTo(this.x, this.y + this.radius - 1);
  ctx.fill();

  // flame
  if (this.climbing) {
   ctx.fillStyle = canvasBackground;
   ctx.beginPath();
   ctx.arc(this.x + this.width / 2, this.y + this.height - this.boxHeight,
     flameSize, 0, 2 * Math.PI, true);
   ctx.fill();
  }

  // basket
  ctx.fillStyle = gondolaColor;
  ctx.fillRect(
   this.x + this.width / 4 + this.width / 8,
   this.y + this.height - this.boxHeight,
   this.width / 4,
   this.boxHeight
  );


Collision detection

The collision detection between two balloons is bounding rectangles based. Before every balloon movement there is a collision check to the current positions of the other balloons. To detect collision between two rectangles I've used the following function:

 function checkCollision(obj1, obj2) {
  return !(
    (obj1.y + obj1.height < obj2.y) ||
    (obj1.y > obj2.y + obj2.height) ||
    (obj1.x > obj2.x + obj2.width) ||
    (obj1.x + obj1.width < obj2.x)
  );
 }


Detecting keyboard keyes

In order to make the simulation interactive the parameters can be controlled with the keyboard keys. The key detection in JavaScript is pretty straight forward:

 document.onkeydown = function(e) {
  if(e.keyCode == 37) {
   // left
  } else if(e.keyCode == 39) {
   // right
  }  else if(e.keyCode == 38) {
   // up
  } else if(e.keyCode == 40) {
   // down
  } else if (e.keyCode == 13) {
   // enter key
  }

  return false;
 };


And here's my example on:
Codepen
GitHub

2013-03-20

Canvas Crossroad

Canvas context

The canvas element is part of HTML5 and allows for dynamic, scriptable rendering of shapes and images. The actual drawing happens within a context. In this example we'll use 2d context for drawing:

 var canvas = document.createElement('canvas');

 canvas.width = window.innerWidth;
 canvas.height = window.innerHeight;

 var ctx = canvas.getContext('2d');
 document.body.appendChild(canvas);


Drawing shapes and lines

In order to make the changes to the context as easy as possible the best practice is to save the context before doing any changes and restoring it after we are done with drawing. Especially if we change context rotation, colors and fill styles:

  ctx.save();
  ...
  ctx.restore();

The crossroad canvas example uses these constructs for drawing shapes:

  • arc
  • fillRect
  • moveTo + lineTo


Circle

There's no method named circle, instead we use arc and make one from 0 to 2 * Pi:

 ctx.fillStyle = 'red';
 ctx.beginPath();

 ctx.arc(x, y, radius, startAngle, endAngle, antiClockwise);

 // ctx.stroke() would draw circumference, fill makes a circle
 ctx.fill();


Rectangle

Drawing rectangles is pretty straight forward. One must set coordinates, width and height:

 ctx.fillRect (x, y, width, height);


Lines

When working with lines we can move starting point and then make a line to some other position:

 ctx.beginPath();

 ctx.moveTo(x1, y1);
 ctx.lineTo(x2, y2);

 ctx.closePath();
 
 ctx.stroke();


Clearing the drawing

Very important when doing animations because calculating what pixels to clear every time would be pretty complicated to code. Changing a small piece of canvas takes less time than clearing everything and then drawing it again. In the past developers kept an off screen canvas and did drawing on it and then at the end of the animation loop they copied the off screen canvas to the on screen canvas.

Most of the browser vendors started to do this automatically so in modern browsers keeping an off screen canvas actually degrades performance.

 ctx.clearRect (x, y, width, height);


Collision detection

All objects in the crossroad animation are represented as circles. The formula for collision detection between two circles is:

 function collision(c1, c2) {
 
  var dx = c1.x - c2.x;
  var dy = c1.y - c2.y;
  var dist = c1.radius + c2.radius;
   
  return (dx * dx + dy * dy <= dist * dist);
 }
If the movement happens along a single axis line it's even simpler we just need to check the coordinate on the relevant axis (in this case x):
  Math.abs(x1 - x2) > (radius + safety_distance)


requestAnimationFrame

The browser vendors optimized the usual timer animation loop and provided api for it. But since some vendors don't support it or the users have older browsers we use this pattern:

 // shim layer with setTimeout fallback
 window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame    ||
    function( callback ){
     window.setTimeout(callback, 1000 / 60);
    };
 })();
 
 (function animloop(){
  requestAnimFrame(animloop);
  // call drawing functions here
 })();


requestAnimationFrame

And here's my example on:
CSSDeck
Codepen
GitHub

2013-03-09

Git

Introduction

Git is a distributed source code management system working with a complete repository copied and detached from some central server.

Git system stores complete file snapshots in it's database whereas traditional systems store initial file and differences made to them over time. Once the file is in Git's database, it stays there forever.

Git operates on top of a simple database containing project files as binaries. Every binary in this database is represented with a key.

Key is calculated by running SHA-1 hash function on file's content and that results in a 40 characters unique string key. Most of the time first 7 characters are enough to identify something in the project.

Every snapshot contains information about:

  • what binary objects are included (id's from internal database)
  • info about previous snapshot (pointer)
  • data describing the change

Global setting

Enable the Git to fill the data about the author of the change by providing this basic info:

   git config --global user.name "Your Name"
   git config --global user.email "email@example.com"

Creating a repository

  • new local repository (creates a folder with .git folder inside it):
         git init project_name
  • clone a repository from a remote system:
         git clone http://example.com/project.git

Basic workflow:

  1. edit files
  2. define files going in the next snapshot with specific file name or simply by "."
         git add .
  3. review changes
         git status
         git diff
  4. commit (make snapshot)
         git commit -m "message describing new snapshot"
Git doesn't track empty folders, if needed, users usually put empty .gitkeep file into it. If some files don't need to be under version control there is a special file .gitignore with a list of files and directories not under version control. One can use special character " * " and "." in this file.

Branches

Branches are lightweight pointers to snapshots (commits), to list branches use:

   git branch
Initially every project has one branch called master (created in the init). Nothing special about the name master, it's default. To make a new branch and start working in it use:
   git checkout -b newbranch master

If you want to switch to existing branch use:

    git checkout existingbranch

Merging

To merge something into a branch that you are currently working on use:

   git merge coolbranch
If there are same files changed in both branches, Git will inform us about a merge conflict, then we have to resolve the conflict manually and commit the changes. This results with a new snapshot and the branch pointer moves to this new snapshot.

Collaboration

In order to do the collaboration, we need location names of remote repositories. Usually we make a short alias for them. The most common alias is origin refering to some "central" repository, but we can add other physical repositories for instance by team member name.

   git remote add tom git://...project.git

Branches in other repositories are referred to as tom/master, origin/master... To get the remote snapshots and remote branching info we use fetch command.

Fetch doesn't change our branch pointers or changes our existing snapshot data, it only adds the information to the database from the remote system. This is why Git is called distributed. To get tom's Git database and merge our current branch to his superbranch we use:

   git fetch tom
   git merge tom/superbranch

Remote branch pointers are moved with push command. But, if the branch pointer on the server points to a newer snapshot than our local one, we'll get an error. Then we have to fetch the remote database, do the merge and then tell to remote to point the branch to a new snapshot:

   git push origin master

Log

To get the history of snapshots use the log command. The oneline option prints just the basic information, and the graph option shows snapshot connections.

   git log --oneline --graph

The log command above shows only the snapshots leading up to the current branch pointer. Some snapshots from other branches might not be visible.

If we would like to see what's in the master and not in the coolbranch we would use:

   git log master ^coolbranch

http://git-scm.com/


@msvaljek

2013-03-07

Modernizr

Introduction

Modernizr is a small JavaScript library for detecting browser capabilities.

  • creates an object Modernizer with boolean properties about available features
  • provides a script loader for pulling scripts to backfill functionality (polyfills)

Keep in mind that polyfills sometimes decrease user expirience because of poor performance.

Modernizr Download is usually customized and contains only specific checks.

It's a best practice to include the Modernizr script before the end of a head tag to avoid browser (IE) compatibility issues.

Modernizr.load function

Loads a script asynchronously based on a test result, it's not a default Modernizr feature and has to be checked for in the download. Load function usage example:

   Modernizr.load({
    test: Modernizr.geolocation,
    yep : 'geo.js',
    nope: 'geo-polyfill.js'
   });

Usually Modernizr loads more than one script, an has more than one test.

   Modernizr.load([
    {
     // run a test, include script when capability missing
     test : Modernizr.fontface && Modernizr.canvas && Modernizr.cssgradients,
     nope : ['presentational-polyfill.js', 'presentational.css']
    },
    {
        test : Modernizr.websockets && window.JSON,
        nope : 'functional-polyfills.js',
        // scripts under both are always loaded
        both : [ 'app.js', 'extra.js' ],
     complete : function () {
         // this function runs when all of the previous scripts are loaded
         // and when all scripts from this secion are loaded.
         myApp.init();
        }
    },
    // this script is included without checking any conditions
    'post-analytics.js'
   ]);

CSS for the unsupported features

CSS markup can be adapted to the availability of features. For instance, if css gradients are not supported, perhaps we want to include background image instead. But be careful, browser usually preloads images, so this could cause unwanted http requests. Note that the missing class has a no-missing_feature name:

   .no-cssgradients {
    background: url("images/glossybutton.png");
   }

Detecting css prefixes from javascript

When using css animations and transitions in javascript, it's useful to know how the browser prefixes certain css features.

   Modernizr.prefixed('boxSizing')

http://modernizr.com/docs/


@msvaljek

2013-03-05

compass

Introduction

Compass is a CSS Authoring Framework with a lot of reusable patterns. Developers spend less time on browser prefixes, css2 opacity, browser checking, IE hacks, reset stylesheets and so on...

Installation:

   gem install compass
Create new project (this command creates a folder and a substructure):
   compass create myproject
After creating project tell the compass to watch the project for changes:
   compass watch myproject

Pattern usage

In order to find out available constructs in the framework use compass documentation

Before using any compass patterns, we have to declare them:

   @import "compass/css3/border-radius";
Declaring a higher level group gives acces to all child patterns (same as above):
   @import "compass/css3";
Actually using a declared border-radius import:
   .box {
    @include border-radius(5px);
   }
The stylesheets get compiled into the stylesheets folder, the compiled css files contain references to scss file lines.
   /* line 8, ../sass/screen.scss */
   #elem {
     -webkit-box-shadow: red, 2px, 5px, 10px;
     -moz-box-shadow: red, 2px, 5px, 10px;
     box-shadow: red, 2px, 5px, 10px;
   }

Best practice

Best practice is to make base.scss with includes, global variables and pattern variable overrides:

   @import "compass/reset";
   @import "compass/css3";
   @import "compass/utilities";

   $default-box-shadow-color: red;

Import the base.scss in the custom scss files:

   @import 'base';

   .box {
    @include border-radius(5px);
   }

   #myelemid {
    @include box-shadow(blue, 1px, 3px, 5px);
   }

compass and 960

Installation:

   gem install compass-960-plugin
Create new project:
   compass create -r ninesixty my_project960 --using 960


http://compass-style.org/


@msvaljek

2013-03-04

Sass

Intro

Sass is an extension of CSS3 with nested rules, variables, mixins, selector inheritance and more.

Installation:

   gem install sass

Edit .scss files and they get "compiled" into output css files. To do this use:

   sass --watch style.scss:style.css

Before going into production, it's a good practice to compress the output css files:

   sass --style compressed --watch style.scss:style.css

Variables

Variables are declared with $variable_name:

   $my-color: blue;
   body {
    background: $my-color;
   }

Nested rules

Nicer style organization (ie. avoid repeating ul li selector):

   ul {
       background: red;
       li {
           display: inline;
       } 
   }

Mixins

Mixins behave like functions, use them when applying block of information to multiple properties like repeating vendor prefixes for rounded corners.

Declare a mixin with @mixin, specify the variables in the Parentheses, assign them a default value with ":". Call the mixin with @include mixin_name:

   @mixin rounded ($radius : 5px) {
       -webkit-border-radius: $radius;
       border-radius: $radius;
   }

   #mybox {
       @include rounded(10px);
   }

Selector inheritance

It's pretty much like classes in the OO programming, uses @extend keywoard:

   .myrounded {
       -webkit-border-radius: 5px;
       border-radius: 5px;
   }

   #box3 {
       @extend .myrounded;
       color: yellow;
   }


http://sass-lang.com/


@msvaljek