HTML5 Canvas Particle System (Pt. 3)

This is a Part 3 of a tutorial post HTML5 Canvas Particles System (Pt. 1). In this tutorial I will cover:

  1. Initialising Canvas (covered in Pt. 1)
  2. Drawing circles in Canvas (covered in Pt. 2)
  3. Simple animation for particle movement using SetInterval() (covered in Pt. 2)
  4. Improving the code using RequestAnimationFrame()

Using RequestAnimationFrame() instead of SetInterval()

Instead of using SetInterval() we can animate only when we need to using RequestAnimationFrame(). This helps improve performance as we re-draw only when something has changed. We can define to call spawn(), draw() and update() on load, after which we would have to modify the update() method to trigger the RequestAnimationFrame().

Here is what we are using instead of SetInterval():

1
2
3
4
5
6
7
8
window.requestAnimFrame = window.requestAnimationFrame ||
                          window.webkitRequestAnimationFrame ||
                          window.mozRequestAnimationFrame ||
                          window.oRequestAnimationFrame ||
                          window.msRequestAnimationFrame ||
                          function(e){
                            window.setTimeout(e,1e3)
                          };

And adding an on load function:

1
2
3
4
5
6
7
8
// We should create, draw and start updating on load. 
window.onload = function() {
    c.width = c.width;
    c.height = c.height;
    spawn();
    draw();
    update();
}

We can now modify update() to look like this which now:

1
2
3
4
5
6
7
8
9
10
11
12
13
function update() {
    reset();
    c.width = window.innerWidth;
    c.height = window.innerHeight;
    for(var i=0; i < ps.length; i++) {
        ps[i].y += 1 ;
        ps[i].x += -1 + (Math.random() * 3);
        //ps[i].r = Math.random()*5;
    }
    draw();
    window.setTimeout(requestAnimFrame(update),1e3);

}

And that is it!

🔥 If you enjoyed this post then you can keep up to date with my latests blogs posts & courses by following me on Twitter and checking out my code school for some hands on guided coding practice.

Cienfuegos, Cuba

Park Jose Marti Image

Getting There

We have kicked off our trip in a small city of Cienfuegos, Cuba. We landed in Varadero airport and from there Cienfuegos was a terryfying 2hr car trip. No seatbelts, no road signs and sparse road lights made every passing car seem like it was going to crash into us, but we arrived safely after all and this is simply something we would have to get used to (the buses turned out to be a similar experience). We could have taken a bus from Varadero to Cienfuegos, but since in Cuba there is a separation of transport for tourists and locals it makes taking the bus together with my family difficult and due to only 3 or 4 buses a day we would’ve had to spend the night in Varadero. The car seemed like a much better option.

Family Visa

I have lots of family in Cuba and we were staying with them on a Family Visa which was an adventure in itself to aquire on our first day here. While we entered the country on a Tourist Card, in order for us to stay in my family home we would have to change it to the Family Visa within 24hrs of arrival. Of course we could have done this back in London, but it seemed easier to do in Cuba (it was not). Not only did we have to sit in a scorching heat in the queue for ages, but to get everythign sorted required multiple trips to various places: bank, insurance office of some sort and the foreign exchange. After the lady giving out the visas had a long chat about what to do with us with her manager, apparently since I am a daughter of a Cuban citizen but do not have a cuban passport it was making things more complicated. In the end after some strange and personal questions, they agreed to give us the family visa an everything seemed to go well. That was until they demanded to see a printed copy of our travel insurance and since it is 26 pages long we obviously did not print it and bring it with us but instead had all the electonic copies on our phones. This did not go down well and we had to go to insurance office of some sort where they would “verify” our policy or simply make us buy a new one, which was actually more expensive for 2 weeks in Cuba than the entire 6 months backpacking insurance policy we already had! Luckily my dad talked to them in Spanish and we managed to convince them that electronic confirmations are the standard in UK and we were off to submit our travel insurance “verification” and collect a receipt in the bank to prove we have paid for the visa. After a full day of running around we had our visa. Success!

Accomodation

Our accomodation for the two weeks is my brothers house, which is currently in a complete renovation stage. We had the most “finished” room, but no running water. You don’t appreciate running water until you don’t have any! Simple things like brushing your teeth suddenly become difficult. Nothing could be accomplished without getting water first and storing it in buckets in our room. Separate drinking water had to be aquired as well, due to an outbreak of Cholera around Cuba. We managed to adapt quickly enough and now having a shower in the morning can be accomplished in the same amount of time as having a fully working bathroom. Thanks to water reservour under our room, a water pump, an industrial water heating element and multiple buckets we can have hot water within 5 minutes (unless the pump stops working!).

On a Tourist Card we could have stayed in a Casa Particular, which is most of the travellers here seem to do. This is basically a B&B but they would have to register you as staying with them to the goverment. Running water, sometimes even hot water 24/7. Usually the hosts offer breakfasts an even dinners if requested (would very much recommend this option, especially after trying very hard to find somewhere to eat but more on that later).

Photos

Aduana Immigration Building Image Cienfuegos Market Image Cienfuegos Melecon Image Cienfuegos White Bus

HTML5 Canvas Particle System (Pt. 2)

This is a Part 2 of a tutorial post HTML5 Canvas Particles System (Pt. 1). In this tutorial I will cover:

  1. Initialising Canvas (covered in Pt. 1)
  2. Drawing circles in Canvas
  3. Simple animation for particle movement using SetInterval()
  4. Improving the code using RequestAnimationFrame()

Drawing Circles in Canvas

Now that we have initialized a blank canvas, we can begin to draw in it. For our particle system we will need to draw the individual “particles”, each one will be drawn as a circle. In order to draw a circle in Canvas we need to first get the canvas element using GetElementById and set the width and height to the browser window, then specify that we are working in 2D using getContext:

1
2
3
4
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
c.width = window.innerWidth;
c.height = window.innerHeight;

We can now define our draw() function and then call it:

1
2
3
4
5
6
7
8
9
10
11
12
function draw() {
  x = 90; // x co-ordinate
  y = 70; // y co-ordinate
  r = 60; // radius of a circle
  c = "#ef5da1"; // fill colour

  ctx.beginPath();
  ctx.arc( x, y, r, 0, 6);
  ctx.fillStyle = c;
  ctx.fill();
}
draw();

And here is our first circle:

We can now create an array of particles for us to draw. First let’s initialise some variables that we will need available globally:

1
2
3
var ps = [];// initialize an empty particle array
var MAX_NUM = 500; // this is the maximum number of particles we want to generate and draw
var colors = [ '#69D2E7', '#A7DBD8', '#E0E4CC', '#F38630', '#FA6900', '#FF4E50', '#F9D423' ]; // this is an array of colour that the particles can be

In order to generate all particles we will create a spawn() function and call it. Here we are populating the empty ps[] array with randomly generated values, within the given bound (in this case the width and height of the browser window):

1
2
3
4
5
6
7
8
9
10
function spawn() {
  for(var i = 0; ps.length < MAX_NUM; i++) {
      ps[i] = { x: Math.random() * window.innerWidth,
                y: Math.random() * window.innerHeight,
                r: Math.random() * 5,
                c: colors[Math.floor(Math.random() * colors.length)]
              };
      }
}
spawn();

We now need to modify our draw() function to loop over all the particles and draw them:

1
2
3
4
5
6
7
8
9
function draw() {
  for(var i=0; i < ps.length; i++) {
  ctx.beginPath();
      ctx.arc( ps[i].x, ps[i].y, ps[i].r, 0, 6);
      ctx.fillStyle = ps[i].c;
      ctx.fill();
  }
}
draw();

If we run the code now, we should see something like this:

This is the full script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var ps = [];
var MAX_NUM = 500;
var colors = [ '#69D2E7', '#A7DBD8', '#E0E4CC', '#F38630', '#FA6900', '#FF4E50', '#F9D423' ];

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
c.width = window.innerWidth;
c.height = window.innerHeight;

// create the particles
function spawn() {
  for(var i=0; ps.length < MAX_NUM; i++) {
    ps[i] = { x: Math.random()*window.innerWidth,
              y: Math.random()*window.innerHeight,
              r: Math.random()*5,
              c: colors[Math.floor(Math.random()*colors.length)]
            };
   }
}
function draw() {
  for(var i=0; i < ps.length; i++) {
  ctx.beginPath();
      ctx.arc( ps[i].x, ps[i].y, ps[i].r, 0, 6);
      ctx.fillStyle = ps[i].c;
      ctx.fill();
  }
}
spawn();
draw();

Simple Animation Using SetInterval()

We are now ready to animate our particle system. We will need to write an update() function, which will update the x and y values of each particle on each frame. On each update we also need to reset the width and height to clear the canvas (Tip: remove this to see what happens if the canvas is not cleared):

1
2
3
4
5
6
7
8
function update() {
  c.width = window.innerWidth;
  c.height = window.innerHeight;
    for(var i=0; i < ps.length; i++) {
        ps[i].y += 1;
        ps[i].x += -1 + (Math.random() * 3);
    }
}

We can now call this function on each frame using SetInterval() and then draw the particles with the updated co-ordinates:

1
2
3
4
setInterval(function() {
  update();
  draw();
}, 30);

You may have noticed that the particles simply dissapear once they have reached the bottom of the brower window, if you would liek to animation to keep on running we could reset the x and y of each aprticles if it leaves the screen to start all over again:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function reset() {
    //reset the x and y coordinates if a particle leaves the canvas
    for(var i=0; i < ps.length; i++) {
        //reset if y or coordinate has left the canvas
        if(ps[i].y > c.height) {
            ps[i].y = Math.random()*window.innerHeight;
            ps[i].color = colors[Math.floor(Math.random() * colors.length)];
        }
        //reset if x or coordinate has left the canvas
        if(ps[i].x > c.width || ps[i].x < 0){
          ps[i].x = Math.random()*window.innerWidth;
          ps[i].color = colors[Math.floor(Math.random() * colors.length)];
        }
    }
}

Now we have to call this new reset() function on each frame:

1
2
3
4
5
setInterval(function() {
  update();
  draw();
  reset();
}, 30);

Now you have a never ending animation of colourful particles slowly making their way down the screen. The full particles.js can be found here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// declare vars
var ps = [];
var MAX_NUM = 500;
var colors = [ '#69D2E7', '#A7DBD8', '#E0E4CC', '#F38630', '#FA6900', '#FF4E50', '#F9D423' ];

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
c.width = window.innerWidth;
c.height = window.innerHeight;

spawn();

//create the particles
function spawn() {
  for(var i=0; ps.length < MAX_NUM; i++) {
    ps[i] = { x: Math.random()*window.innerWidth,
              y: Math.random()*window.innerHeight,
              r: Math.random()*5,
              c: colors[Math.floor(Math.random()*colors.length)]
            };
   }
}

function update() {
    c.width = window.innerWidth;
    c.height = window.innerHeight;
    for(var i=0; i < ps.length; i++) {
        ps[i].y += 1 ;
        ps[i].x += -1 + (Math.random() * 3);
        //ps[i].r = Math.random()*5;
    }
}

function reset() {
    //reset the x and y coordinates if leaves the canvas
    for(var i=0; i < ps.length; i++) {
        //reset if y or coordinate has left the canvas
        if(ps[i].y > c.height) {
            ps[i].y = Math.random()*window.innerHeight;
            ps[i].color = colors[Math.floor(Math.random() * colors.length)];
        }
        //reset if x or coordinate has left the canvas
        if(ps[i].x > c.width || ps[i].x < 0){
          ps[i].x = Math.random()*window.innerWidth;
          ps[i].color = colors[Math.floor(Math.random() * colors.length)];
        }
    }
}

function draw() {
  for(var i=0; i < ps.length; i++) {
    ctx.beginPath();
      ctx.arc( ps[i].x, ps[i].y, ps[i].r, 0, 6);
      ctx.fillStyle = ps[i].c;
      ctx.fill();
  }
}

setInterval(function() {
  update();
  draw();
  reset();
}, 30);

Live demo here.

In Pt.3, I will cover how we can improve our animation using RequestAnimationFrame()(Pt.3 can be found here).

🔥 If you enjoyed this post then you can keep up to date with my latests blogs posts & courses by following me on Twitter and checking out my code school for some hands on guided coding practice.

Backpacking 6 Months Packlist for Girls

Trying to fit everything you may need for 6 months into a 65L bag is not easy, especially as a girl. I had to consider hot climates, farming in the jungle, camping on the beach as well as the colder mountain areas of Peru and some parts of Bolivia. It took me 3 or 4 packing attempts to see what fits and what can be discarded. In the end this is what I ended up with in my bag:

Important documents and info

  1. Backpackers Insurance
  2. Tourist Card/Visas
  3. Important info on paper/laptop/phone. I had all the info saved on all 3, carrying paper around is annoying, but I could access any info I needed on my phone with printed out version used as a backup in case I am unable to charge my phone/laptop.
    1. Your country’s embassy addresses and numbers in each country you are visiting
    2. Lost/Stolen card bank numbers
    3. Your insurance numbers and policy number
    4. Printed out insurance policy confirmation with countries covered and names clearly visible (certain countries require proof of insurance)
    5. Relatives and friends, also emergency contacts
    6. Accomodation addresses and numbers
    7. List of credit card numbers and bank account numbers
    8. Passport number
    9. Passport photocopies
    10. Flight details
  4. Yellow fever certificate (if required)
  5. Vaccines booklet

Required vaccines (covering Cuba, Mexico, Belize, Peru, Bolivia, Argentina, Brazil and Chile)

We had to start all vaccinations at least 6 weeks before the trip as some of them require multiple shots at certain intervals (ie 7, 14 days). Most of these were free from a GP but the rest were from a Travel Clinic.

  1. Hep A
  2. Hap B
  3. Typhoid
  4. Yellow Fever
  5. Rabies
  6. Tetanus
  7. Diphtheria
  8. Polio
  9. Malaria - had to bring antimalarians with us, we bought these at a travel clinic for the number of days that we may be present in a malaria zone)
  10. Cholera - for the affected areas the advice was to use water purifying tables, wash hands, wash and peel all fruit and vegetables before consuming, avoid ice creams and ice or any drinks with questionable water. We bougt water purifying bottles to make things easier.

Camping/Backpacking gear:

For certains parts of our trip it will be possible for us to camp, so far we have arranged to camp on a beach in Mexico and it is considerably cheaper than other accomodation. Certain farms however may be unfinished an not have any helper accomodation, so it was advisable to have our own tent just in case. Without all this gear the bag would have been considerably smaller and lighter, but this is what we have in terms of gear:

  1. Mosquito Net
  2. Season 1 Sleeping Bag (I used Vango Planet 50)
  3. Tent
  4. Insect repellent with no DEET (to be used in cities and places with less insects as well as organic farms)
  5. Insect repellent with DEET (jungle and malaria high risk areas)
  6. Travel detergent/general cleaner (I used DR Bronner)
  7. Backpack (I used Osprey Ariel 65L)
  8. Travel Towel (quick drying)
  9. Inflatable Pillow
  10. Silk Sleeping Bag Sheet
  11. Rain cover for the backpack
  12. Small face/hands towel
  13. Water Bottle
  14. Head torch
  15. Swiss army knife (Victorinox)
  16. Dry bags (keep clothes and eletronics dry, but I also used them as organisers)
  17. Plastic bags for wet things and rubbish
  18. Garnening gloves (for farming)
  19. Sleeping mask

Toiletries:

I am sure I could have done without a few of these, but I simply was not brave enough to come abroad for 6 months without moisturiser or makeup! Here is what is in my makeup/shower bag:

  1. Nail clippers/ small scissors
  2. Sun Block (SPF 50 for face and body)
  3. Toothpaste with fluoride
  4. Natural toothpaste (for when satying on organic farms)
  5. Face moisturiser (Dr Haushka)
  6. Body moisturiser (Shea butter)
  7. Shaving Gel (I used Dr Bronner Shaving Gel)
  8. Shampoo/Shower Gel (I used Dr Bronner Peppermint Liquid Soap)
  9. Conditioner
  10. Face Wash (I used laidbare DIY!)
  11. Eye gel
  12. Makeup
  13. Shaving razor (and spare blades)
  14. Tweezers
  15. Hair bands and hair pins
  16. Hairbrush
  17. Toothbrush
  18. Couple of face masks

Clothes:

Packing for a range of temperatures between 10C and 35C is a challenge, especially that while we are away it is rain season in most of the countries we are visiting. In the end I decided on lighter layers as I can add/take away as needed. Mostly I aimed for silk, wool and quick drying fabrics. They are lighter, dry much faster and keep you comfortable in any weather. This is what I packed:

  • Shoes:
    1. Flip Flops
    2. Walking sandals
    3. Every day shoes (converse)
    4. Hiking/Working boots (doc martens)
  • Warm weather:
    1. Bikini
    2. Light jeans/leggings
    3. Sun hat
    4. Day dress x 2
    5. Night/go out dress x 2
    6. Warm jumper/hoodie
    7. Every day skirt
    8. Long skirt
    9. Shorts x 3
    10. Bra x 3 (cream/black/white and 1 of these is a is multiway bra for any occasion)
    11. Sports bra x 2
    12. T-shirt x 2
    13. Tank top
    14. Evening/go out top
    15. Silk top x 3 (keeps you comfotanble in any weather and dries quickly)
    16. Farming trousers (I used running leggings to keep dry and cool) - ideally long to protect from the sun and the weeds scrathing your legs
    17. Quick dry top (any top that wicks away moisture from the body)
    18. Long sleeve top (to protect from the sun, but also as an extra warm layer)
    19. Silk undewear x 5 (silk dries very quickly)
    20. Hiking socks
    21. Every day socks x 3
  • Rain:
    1. Rain Jacket
    2. Waterproof trousers
  • Cold weather:
    1. Warm coat (Uniqlo down, foldable coat)
    2. Tights
    3. Wool/warm long socks

Electronics/Gadgets:

  1. GoPro
  2. USB chargeable external battery (to charge devices on the go)
  3. Travel adaptors
  4. Cables
  5. Headphones
  6. Laptop and charger
  7. Phone
  8. Cheap backup phone
  9. External hard drive (to backup pictures)
  10. Kindle
  11. Re-chargable batteries and charger (AAA, AA)
  12. Shaver/depilator

Medicine:

  1. Anti-itch/bite cream
  2. Allergy medicines
  3. Antiseptic cream/spray/wash
  4. Painkillers
  5. Tea tree oil
  6. Rehydration salts
  7. Ear plugs (sleeping on buses/flights)
  8. Imodium or any diarrhoea medication
  9. Laxative
  10. Anifungal creams
  11. First Aid kit
  12. Neem oil (skin, bites, insect repellent)
  13. Antimalarians

Other:

I am hoping to make my own coffee on the way if needed, I will report my attempts in a different post. Random extras:

  1. Notebook and pencils (for sketching)
  2. Reading materials/entertainment (on the laptop)
  3. Tea (It is hard to get tea in Cuba and Belize)
  4. Travel coffee grinder and nut bag (used as a coffee filter bag)

6 Months Backpacking Around South America

Today is a first day of a 6 months incredible journey, me and my fiance are going backpacking around South America, Mexico and Cuba in the hopes to learn more about unfamiliar to us culture of each country but mostly to gain experience in Organic Farming. This is not quite a WOOF adventure, while it may have started out as an idea to go around South America WOOFing we quickly realised that not every country has a huge choice of farms to stay on but also how much there is to do in general on the way that simply cannot be missed. Our first farm stay will be to learn the basics of organic farming in Belize, after which we hope to find farms in Argentina and Chile to stay on on the way to Brazil.

Itenary

So far this is our planned route (will update it as we go along):

  1. London, UK -> Cienfuegos, Cuba [flight+ car]
  2. Cienfuegos, Cuba -> Havana, Cuba [bus]
  3. Havana,Cuba -> Cancun, Mexico [flight]
  4. Cancun, Mexico -> Belize City, Belize [bus]
  5. Belize City, Belize -> Punta Gorda, Belize [bus]
  6. Punta Gorda, Belize -> San Pedro Columbia Village, Belize [bus]
  7. San Pedro Columbia, Belize -> Maya Mountain Research Farm [dory]
  8. Maya Mountain Research Farm -> San Pedro Columbia, Belize [dory]
  9. San Pedro Columbia Village, Belize -> Punta Gorda, Belize [bus]
  10. Punta Gorda, Belize -> Belize City, Belize [bus]
  11. Belize City, Belize -> Tullum, Mexico [bus]
  12. Tullum, Mexico -> Cancun, Mexico [bus]
  13. Cancun, Mexico -> Mexico City, Mexico [flight]
  14. Mexico City, Mexico -> Lima, Peru [flight]
  15. Lima, Peru -> Cuzco, Peru [bus]
  16. Cuzco, Peru -> Machu Pichu, Peru
  17. Cuzco, Peru -> Bolivia

Some rough plans after Peru are to travel to the Bolivian Jungle and then generally around Bolivia, before moving on to Chile, Argentina and Brazil.

First stop is Cienfuegos, Cuba (via Varadero).

Flight Tickets Image

Fixed on Scroll Animated Header With CSS and JavaScript

In this post I will explain how to create an animated sticky header, with CSS3 and JavaScript. So we are going to have a header that will behave normally until we have to scroll and then it will become smaller but still stick to the top of the viewport.

The HTML

For this example all we need is a header with an h1 and the main div which holds the content that we can scroll over.

1
2
3
4
5
6
7
8
<body>
  <header>
    <h1>Animated Sticky Header</h1>
  </header>
  <div id="main">
      <p> Curabitur quam neque, malesuada sit amet justo ut, posuere pretium quam. In laoreet nunc velit. Nam mattis erat et leo mollis, sed pulvinar lectus volutpat. Phasellus mi eros, sollicitudin non elit sed, molestie viverra eros. Nullam facilisis mauris ante, sed vulputate sapien efficitur quis. Curabitur vitae lorem eros. Fusce orci odio, eleifend et sem luctus, bibendum viverra nibh. Proin vitae libero egestas, consequat orci id, facilisis ex. Quisque lectus dui, mattis non lectus ac, finibus facilisis velit. Integer mauris nibh, suscipit eu egestas nec, placerat scelerisque purus. Nulla facilisi. Proin eleifend, lectus eget rutrum luctus, dolor nunc luctus ex, sed consequat urna nisi ac ipsum.In hac habitasse platea dictumst.<p>
  </div>
</body>

The CSS

In order to make the header sticky we have to fix it’s position to the top of the viewport, hide any overflow and make sure it is always visible by setting the z-index of the header:

1
2
3
4
5
overflow: hidden;
position: fixed;
top: 0;
left: 0;
z-index: 999;

This will now keep the header always at the top and visible.

The animation of the header can be achived by having a different style rule for when the user has scrolled down -.smaller class. We cna detect if the user has scrolled down using JavaScript (described below) and apply the .smaller class to the <header>. When the header is smaller, we are reducing its height and the font size of the <h1>. This is now the full CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  min-height: 100%;
}

header {
  background: #F58065;
  padding: 0.75em;
  height: 4em;
  color: #fcfcfc;
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  width: 100%;
}

h1 {
  max-width: 70%;
  margin: 0 auto;
  font-size: 2em;
}

.smaller {
  height: 2em;
}

.smaller h1 {
  font-size: 1em;
}

p {
  max-width: 70%;
  margin: 0 auto;
  min-height:700px; /**this is just to force scrolling since we don't have much content**/
}

#main {
  display: block;
  padding-top: 8em;
}

The JavaScript

As mentioned above, in order to animate the header we have to detect of the user is scrolling. This can be achieved by checking if the pageYOffset or the value received from the document.documentElement.scrollTop the returned value is the distance scrolled in pixels.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function init() {
window.addEventListener('scroll', function(e){
  var distanceY = getScrollTop(),
      shrinkOn = 20,
      header = document.querySelector("header");
  if (distanceY > shrinkOn) {
    header.setAttribute("class","smaller");
  } else {
      header.removeAttribute("class");
  }
});
}

function getScrollTop() {
  if(typeof pageYOffset != 'undefined'){
      //most browsers except IE before 9
      return pageYOffset;
  }
  else {
      var B = document.body; //IE 'quirks'
      var D = document.documentElement; //IE with DOCTYPE
      D = (D.clientHeight)? D: B;
      return D.scrollTop;
  }
}
window.onload = init();

🔥 If you enjoyed this post then you can keep up to date with my latests blogs posts & courses by following me on Twitter and checking out my code school for some hands on guided coding practice.

HTML5 Canvas Particles System (Pt. 1)

Learning to make a simple particle system using HTML5 Canvas and Javascript.

In this tutorial I will cover:

  1. Initialising Canvas
  2. Drawing circles
  3. Simple animation for particle movement using SetInterval()
  4. Improving the code using RequestAnimationFrame()

Initialising Canvas

Introduced in HTML5, the HTML <canvas> element can be used to draw graphics via scripting in JavaScript. The <canvas> element isn’t supported in some older browsers, but is supported in recent versions of all major browsers. More information can be found here: http://caniuse.com/#feat=canvas. <canvas> element requires the closing tag, like so:

1
<canvas id="myCanvas"></canvas>

This creates a blank canvas for us to use. You can set the with and height at this point:

1
<canvas id="myCanvas" width="500" height="300"> JavaScript Particles Canvas </canvas>

If not specified, width defaults to 300px and height defaults to 150px.

Some older versions of browsers do not support the <canvas> element, we can provide fallback content. We just provide alternate content inside the <canvas> element. Browsers which don’t support <canvas> will ignore the container and render the fallback content inside it, otherwise they will render the canvas normally:

1
<canvas id="myCanvas" width="500" height="300"></canvas>

You can even include a different element inside the canvas element:

1
<canvas id="myCanvas" width="500" height="300"><img src="img/example.png" width="500" height="300" alt="Example Image"></canvas>

We have now initialized a blank canvas and are ready to draw something. I will cover drawing circles in the next blog post.

🔥 If you enjoyed this post then you can keep up to date with my latests blogs posts & courses by following me on Twitter and checking out my code school for some hands on guided coding practice.

How to Create a Simple HTML Form

For my first web page I wanted to create something simple, but also challenging for myself. I created some web pages whilst at university and have attempted it a few times since but lack of understanding was holding me back, and I found it very discouraging not getting far. So after a couple of courses on Codeacademy and some patient tutoring from my boyfriend (who is a web developer), I finally feel like I am getting somewhere.

I have never in the past managed to use forms or manipulate data using JavaScript on a web page so these were elements I wanted to include in my first project. I should mention that I am not new to coding or scripting, but am a complete noob to web development. In the end I wanted a page that was reminiscent of Lorem Ipsum text generators, but much simpler: here is the result. The user can enter some text and in return get a “Meow” filled paragraph.

So how did I do it? After some franctic googling and trying desperately to remember what I have learned at university about HTML, I have found that we need two main things to make a webpage: HTML and CSS. But in this example we will also need Javascript to be able to process user input.

HTML - HyperText Markup Language.

First things first is to create a file index.html and insert the basic HTML5 structure of a web page:

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
    <head>
        <title>Page title goes here</title>
    </head>
    <body>
    </body>
</html>

So lets explain each tag:

  1. <!DOCTYPE html> - here we are declaring that the document contains HTML5 markup.
  2. <head> - here you will store links to or definitions of scripts and stylesheets. Any description of the page content goes here, such as page title. Search engines will use this to add the page to their search index. This must be the first element in the <html> element.
  3. <title> - this defines the page title, which will be shown in the browser tab or title bar.
  4. <body> - this holds the content of the HTML page. This must be the second element in the <html> element.

At this stage opening index.html in the browser will produce an empty page with the tab title “Page title goes here”.

Earlier I mentioned that I wanted the page to have an input field and a button to process the input on click. Looking at the HTML 5 Element List, we can see that within the <form> we have <input> and <button> elements available to us. We will also need a <label> to caption the <input>. Here is them all added:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
    <head>
        <title>Meow</title>
    </head>
    <body>
    <div class="form-container">
        <form id="meow-form">
            <label>Type Anything:</label>
            <input id="meow-input" name="field" maxlength="255" type="text" autocomplete="off">
            <button type="submit">Go!</button>
            </form>
        </div>
    </body>
</html>

The form is within a container <div>, it can also be called a content <div>. Placing the form in the container will allow for more sophisticated CSS styling and to place the elements anywhere we want on the page with ease. There are a couple of thigs to explain here:

  1. class and id attributes. The class attribute in the <div> element assigns the element to a named class (in this case form-container). Multiple elements in the document can have the same class value, for any unique elements id is more appropriate. (Note: id must be unique in the document). However in this case, id could have also been used. I found a simple explanation of where to use which here. Both id and class are used as selectors in the stylesheet to style the elements (more on this later).
  2. <label> - simply has text to be used as a caption.
  3. <input> - we have given the input an id so that it can be styled later on.
  4. <button> - setting the type="submit" will submit form data when the button is pressed. This is the default option if nothing is specified.

Loading the index.html in the browser now gives us this:

CSS - Cascading Style Sheets.

CSS describes how a structured element (HTML or XML) must be rendered on screen.CSS can be:

  1. inline - using the style attribute in HTML elements.
  2. internal - using the <style> element in the <head> section.
  3. external - using an external .css file.

I am putting all CSS in an external style.css:

First we can set the body of the page to have a background image:

1
2
3
body {
    background: url(images/lined_paper.png);
}

The whole expression is a rule, and body is a selector, which selects which element the rules apply to.

Now we want to give the whole form a width and set the font. Earlier we have made the div that contained the form be of class “form-container”, in order to select elements of that class we have to put a . in front of the class name:

1
2
3
4
5
.form-container {
    margin: 90px auto;
    width: 400px;
    font-family: "Roboto Condensed";
}

We can give the input a desired width:

1
2
3
input {
    width: 200px;
}

And style the button:

1
2
3
4
5
6
7
button {
  background-color:#ED518A;
  height:37px;
  border: 3px solid #fff;
  color: #fff;
  display: inline-block;
}

By saying display the button as an inline-block we are actually telling it to stay on the same line.

Now we need to add a line in the <head> to load the external .css file and to load the custom Google font (the Google font link can be generated on Google Fonts website):

1
2
3
4
5
6
<head>
    <title>Meow</title>
    <link href="normalize.css" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <link href='http://fonts.googleapis.com/css?family=Roboto+Condensed:700,400' rel='stylesheet' type='text/css'>
</head>

After applying all the changes, our web page should now look like this:

Trying this in a few different browsers may yield a different result, but we can help the page to render consistently across different browsers by using something called Normalize.css. You can see that I have already included normalize.css in the <head>. There is also a project called reset.css, there are many different versions you can try, but here an overview of the main differences between reset.css and normalize.css.

JavaScript

Javascript is an (quasi) object-oriented language, widely used as a scripting language for web pages. To add javascript to our page we will create an external script called meow.js which we can include in the index.html:

1
<script type="text/javascript" src="meow.js"></script>

This is the full meow.js:

1
2
3
4
5
6
7
8
9
10
11
12
function send(event) {
    var input_text = document.getElementById("meow-input").value;
    document.getElementById("meow-output").value = meow(50,input_text);
    event.preventDefault();
};
function meow(times, input_text){
    var output = new Array(times);
    for (i=0; i< times; i++){
        output[i] = " meow " + input_text;
    }
    return output;
};

To explain briefly what is being done here: the function send(event) is called once the button is clicked. We are extracting the user input from the button with id meow-input and using it to calculate the output. The function meow(times, input_text) repeats the user input x number of times with the word “meow” in between.

We also need to tell the button to submit the information once it is clicked and use the function send (which is above), this I have done with some internal javascript:

1
2
3
4
<script type="text/javascript">
  var form = document.getElementById("meow-form");
  form.addEventListener('submit', send, true);
</script>

And that’s it!

Some useful resources:

  1. MDN - Mozilla Developer Network
  2. Can I Use…
  3. color.hailpixel.com
  4. StackOverflow

🔥 If you enjoyed this post then you can keep up to date with my latests blogs posts & courses by following me on Twitter and checking out my code school for some hands on guided coding practice.

Hello World!

This blog is intended as a place to document my progress as I attempt to learn web development. From HTML to python and everything in between, the goal is to try everything and try to do it using different tools and technologies to gain a better understanding of web development. I will try to explain everything I have learned and used as I go along in as much detail as possible in the hope that it will help to cement the knowledge in my brain. The list of the work so far can be found here.

I am also a keen traveller, so time to time I will write about my adventures around the world and anythng related.