Laser eye surgery: my experience


I'd been considering getting laser eye surgery for a while, and while the idea appealed there wasn't any major incentive for me to do it.

But eventually I got frustrated. My glasses were always getting dirty, falling off, fogging up (while cycling, working out, or once getting off a bus). At work in particular I was finding myself taking them on and off all day since I don't need glasses for working at my desk but whenever someone would come over they'd be just outside my focal distance and I'd have to put them on again.

So having reached perhaps a vague not-quite-quarter-life crisis I decided to just do it and hang the consequences.

Table of Contents đź‘“

This post is a bit long, so here's a table of contents.

And some updates:


The Tech

There's a few types of laser eye surgeries and they're all pretty squeamish. The ABC has a high level overview of the various types.

I chose IntraLASIK (also known as Femto-LASIK) which uses a laser to create a corneal flap (as opposed to the dark ages when they used a miniature angle grinder), then another excimer laser to evaporate bits of the eye until it's the optimal shape. Amazing, totally terrifying technology, but it works amazingly well.

The alternatve, PRK, doesn't involve a "flap" but has a much longer recovery period since it effectively melts away the top layer of your cornea instead. This one probably isn't for you unless you have a special condition or are at particular risk of head injuries.

Some newer technologies are coming out that show promise, but ultimately IntraLASIK is the best, most mature option out there.


What to expect before laser eye surgery

I initially booked appointments at two places in Brisbane, but only Lasersight got back to me which was strange. The have offices in a number of major urban areas including Sydney, Melbourne, the Gold and Sunshine Coasts so it seemed reputable.

I arrived for my initial appointment not really knowing what to expect, but they were really good. I'd already researched most of the technology, caveats and read countless accounts of other people's success (and failure) stories, so none of the information was particularly new.

Lasersight offer PRK, LASIK and IntraLASIK, but only really do PRK and IntraLASIK as the traditional LASIK (angle-grinder) technology has been pretty much superseded. The nurse I spoke to in my initial consult had PRK himself due to his corneas being too thin for IntraLASIK, and was very happy with the results. Generally a good salesman.

In the initial consult I was taken through a number of machines that scanned my eyes, mapping out the various distortions and measuring the thickness of my corneas. I have a mild astigmatism as well as a mildish shortsightedness, and the machines picked this up and spat out a bunch of graphs and figures saying such. I was also given an eye exam like you get at the optometrist, which confirmed all this as well.

After all the measurements I was told about the payment options and booked in for the procedure the following week.


Lasik prices & extras

Prices I was quoted were:

  • $6600 for IntraLASIK, or $5400 for PRK (Divide by two for costs per-eye)
  • A $200 consult fee and
  • A $200 discount for payment upfront.

This includes all the drugs, consults within a year and the “for life” program in which any subsequent surgeries are free of charge (though consult fees still apply).

It's not the cheapest and some people on various forums have flown interstate or overseas to have it done, but I personally consider that to be a little far out.


On the day

Due to a mistake on the little card they gave me, I showed up expecting a consult but was actually being prepped for the full-on surgery. Thankfully there's not much you need to do to prepare other than not wearing eye makeup or fragrances, neither of which I'm wont to do in day to day affairs.

The initial consult was with Doctor Peter Stewart, director of surgery, who was friendly, answered all my questions and seemed to know what he was doing. He ran me through some of the same tests again to make sure everything was right, before sending me out to fill in some waivers.

The actual surgery was planned for a few hours after the consult, so I had lunch and sat in the stinking Brisbane heat sipping cola across the road.

O Bar mini review: they had inexplicable table service for the bar section, and it took forever to get a drink. The guy was kinda rude but the girl was nice.

At 2:30 I want back in and was ushered into the secret surgery area out the back.


The LASIK procedure

I was dressed up in a robe and hair net, given a bunch of pills to take and administered anaesthetic eye drops which stung like crazy until my eyes were completely numb and could no longer feel anything.

When it was time I was ushered into the room and laid out on the first of two beds at the femtosecond laser. There were three specialists which was really comforting, each presumably had a job to do. One wore fluorescent sneakers.

I don't remember much about the first part, although the general gist was having my eyes propped open, being slid under a machine and having it take a flap cut into my corneas. It was terrifying but vaguely surreal; there was no pain, just sensations of pressure and a primal urge to freeze and not move a muscle.

I was surprised to find they performed this on both eyes right away; the documentation suggested they would do one at a time in case something went terribly wrong, but I wasn't going to quibble because my eyeball was hanging open and I was more concerned about making sure i didn't make things worse.

Overall the procedure took a handful of seconds per eye, though it felt like an age.

After this they ushered me to the second bed. It was an interesting experience; I could still see at that point but everything was cloudy, apparently due to the microscopic bubbles the femtolaser had created.

The second bed was the hardcore stuff: the excimer laser. For each eye they propped open my eyelids and popped on a suction ring to keep the eyeball relatively in place. This was probably the most uncomfortable part, and I later found was the part that left a little bruising.

I was told to stare into the light and not to move while the doctor lifted the flap with a squidgy looking utensil. It was completely painless but silently horrifying to watch my vision distort as my optics bent and shifted with the flap. It also made it difficult to stare in the one spot since the spot kept moving.

The actual excimer laser took literally ten seconds to operate on each eye, during which there was a smell not entirely unlike cooked hair. After that, a bunch of cold water, eye drops and flap-replacement took place. The second eye seemed to require a bit more smoothing out but ultimately everything was fine.

After this I was given the all clear and ushered through another doorway.


IntraLASIK after-effects

I immediately noticed the difference. Having just had my eyes cut up and laserbeamed I expected perhaps to be completely out of it, but I was surprised that I could actually see everything. There was a very strong haze in my vision, but I could see the detail in the surgeon's eyes which would ordinarily be a complete blur without my glasses.

The nurse took me, did a bunch of tests, explained my drop regime, attached some goggles to stop inadvertent touching and suggested strongly that I go home and sleep straight away.

The initial six or so hours are the worst, so it's best to sleep through it. Basically your eyes feel really scratchy like you've got sand in them, but you can't touch or your corneas will most likely fall out (that's my nightmware anyway). They also get very watery and it's generally unpleasant. So go to sleep.

Thanks to some fantastic drugs included in the package, I ended up sleeping until midnight at which point I woke up and took a walk outside for the first time to find something to eat. Greasy pizza outlet was the best I could find, but honestly it was the best greasy pizza I've ever had. It looked good too. So did everything, really.

At this point my eyes still felt somewhat gritty, but there was no pain and most of the haze had cleared up.


The next day

The next day was pretty amazing. Even more of the haze had cleared up and everything was getting progressively better.

Here's a selfie of me looking slightly dopey, but outside without glasses for the first time in forever. You can see a bit of bruising in my left eye if you look hard enough. I'm assured this will heal in a couple of weeks.

One of the side-effects that worried me were “halos” or a “bloom” around bright things, to borrow a gaming term. Particularly things like traffic lights, signs, and (annoyingly) computer screens. This has definitely improved as it's healed, but it's still noticeable on high contrast light points. While you see results instantly, they say it takes about a week for the cornea to heal properly, and this was definitely one of the more noticeable healing issues.

I took a walk through the city the day after and it was quite windy so I definitely noticed some discomfort in my eyes and feel I probably overdid it a little. I bought myself a pair of sunglasses which has been on my list of things to do for ages now and definitely made things better.


LASIK as a programmer

I read a really fantastic overview of the procedure by another programmer who had the procedure done but still wears glasses for working. My surgeon assured me that my vision would be fine for the kind of work I do, but I'm wholly aware that this may not be entirely the case, and certainly won't be forever as presybopia eventually becomes an issue.

Thus far things seem pretty good in terms of working. The main issue now is that where previously focusing near was a zero-effort task, I now have to actively choose to focus on my phone or screens in particular. I can still read tiny ebooks on my phone screen from 10 cm away, though it's not as comfortable as it was before and there's a more sensible point further out.

My main goal is to be able to work at a regular desk with a 27" screen without having to perform acrobatics to do it. Initially there was some discomfort around the "halos" making it more difficult to do much on screens, and this continued for about a week.

I also notice it takes a bit longer to focus "out" from my work. For instance, if someone walks over I'll take a second or two to break out of computer mode and actually engage with them. Often I've instinctively reached for my glasses, so I'm not sure if this is psychosomatic.

The one disappointing thing I've noticed is that I'm having trouble with colour contrast, specifically red on black. This is arguably a terrible design decision to start with, but the super-pretty Monokai colour scheme that (I think) comes default with Sublime Text and that I use for my terminal scheme is uncomfortably difficult to read as a result. I've changed it ot a lighter, more contrasty white-pink, but apparently colour contrast issues are a potential issue, so there you go. I'll update if this changes.

Otherwise everything's great now. Initially I was really worried, but after a week or two it's perfect again.


Overview

Ultimately this was a well-researched but snap decision that I'm totally happy with. There were some initial side-effects that had me a bit worried, and I can't see distance as perfectly as I could with my glasses, but it's pretty damn good, and apparently better than 20:20 anyway.

Would I do it again? Probably. It's a freaky procedure that carries admittedly small risks, and part of me still boggles that I actually went through with it. There may be a touch of post-purchase rationalisation too, but ultimately it's just an amazing experience being able to see properly with my own two eyes.


Two Years On

It's hard to believe it's been almost two years. Life has changed a whole bunch, but for the most part my eyesight is pretty great.

The problems I initially reported are all either resolved or stuff I've gotten used to. I occasionally notice my eyes will get tired and hard to focus on screens, but I imagine that's fairly standard working at a desk all day. My distance vision is still not as perfect as when I had glasses, but again I'm more than happy with it. It's probably something I could improve with glasses, but it's not something I've a need or interest in pursuing.

Another thing I used to notice is that I used to get eyestrain and headaches watching TV for long periods. It only occurred after the surgery that this was due to context switching between my laptop and my TV through my glasses, which no longer happens. So now I don't get nearly as many headaches which is a pretty cool side effect of the surgery.

So overall would I recommend it? Sure. While it's not a complete solution, it's changed my life for the better and I certainly don't miss having to clean my glasses all the time.


Four years after laser eye surgery

It's some four and a half years later and a lot has happened. I've moved to Amsterdam for starters, which is a fair ways from home.

In terms of my eyesight things are still good.

I've noticed that I really need to take care of my eyes while working, otherwise the world is a blurry mess when I step away from my screen after work. This means fairly frequent looking out the window to change focus, and generally taking care not to stare at a screen all day.

In the Amsterdam winter my eyes dried out a lot more than they ever did back in Australia. This was easy enough to fix by making an effort to remember to blink from time to time, but I was on the verge of buying eye drops a few times. They say dry eyes is one of the side effects of the lasik, and I guess it's more of a thing in the cooler climates.

Anyway, that's about it. Just wanted to update things because I know posts like this are valuable when you're considering the procedure. Feel free to reach out on Twitter if you have any questions.

Alchemize stronger & more often

In case you missed it on Twitter, the other day I released Alchemize as a web app, and open sourced the code on GitHub.

Alchemize is a web app which lets you easily pretty-print or minify your source code. It's been a pet project of mine for a couple of years now, and it's really useful as a web developer.

Previously Alchemize was exclusively on the Chrome Web Store, and while it's still available to install as a Chrome app I'm excited to announce it's available online for even easier access.

I've gone to a bunch of trouble to fork and patched the libraries I'm using (a lot of them don't work out of the box) and included them in the NPM manifest so you can easily get to developing. If you're interested, check out the README for instructions.

If you're a web developer and haven't checked it out yet, you should absolutely bookmark the direct link: alchemizeapp.com/app

Polar Defender & js13k

Over the last month I’ve been working on a game for the #js13k game competition.

The concept is fairly simple: make a game in under 13 kilobytes with no external dependencies. The idea is to see what people can come up with on a budget, and it’s awesome to see some of the entries this year.

My game, Polar Defender, is a basic shoot ’em up on a polar coordinate system. It’s heavily inspired by space invaders, except you have to defend various planets from all sides at once. It’s heavily reliant particles and a basic polar trajectory system to provide messy, explodey space fun.

The theme of “elements: earth, air, fire, water” is optional in the contest, but I incorporated it into my level system (an earth-like planet, water planet fire and gas planet). It’s a /little/ contrived, but I think it works well in terms of playability.

I wanted to include a playable level system with a playful narrative since there’s only so much you can do in 13 kb and I felt it would make it a more personal experience. I feel it worked out well, with six levels (including an initial training level) on various planets and varying degrees of difficulty. After early feedback stating it’s too hard to finish in one go, I adjusted the menus to make each level unlockable rather than having to start over, which really improves the gameplay in a casual sense.

Touch input is significantly more difficult than desktop input because I essentially shoehorned the same concept in where it doesn’t really fit. If I had the chance to do it again I would introduce a separate tap-based firing system on mobile.

The tech

Some of the tech I used includes:

  • jsfxr for sound effects, based on Jack Rugile’s blog post.
  • Liberal use of the native Canvas rotate() method.
  • Regular CSS & JS for the menu system.
  • Gulp, Uglify, svgo and a bunch of hand-tweaks to package and minify my codebase.
  • Super rudimentary box-based collision detection.
  • A basic entity/component model through which to extend base sprites.
  • SVG for infinitely customisable graphics. (There’s only four enemy sprites in
    the game, each recoloured and resized as needed.)
  • Procedurally generated starfield & planets.

How to ultra-compress your JS

13 kilobytes is quite a lot in terms of raw code, but also a challenge to meet when including graphics, sound, polyfills and other boilerplate.

Minification of Polar Defender was done by hand and involved a lot of code tweaks.

The ultimate deliverable needed to be compressed into 13 kilobytes of zip file, which is roughly comparable to a gzipped distribution from a web server.

Some of the things I did which aren’t necessarily best practices include:

  • Strip unnecessary properties and pre-compile SVG files into a JSON file to be bundled into the main JS build process. This improves  compression because there’s less junk and the SVG gets compressed in with the JS which presumably improves duplicate string elimination in the zip format.
  • Collapse JSON structures into CSV-like strings that can be reinflated later. JSON objects are super-wasteful in terms of repeated properties, and while compression algorithms are generally pretty good with repeated content, it’s still better to remove the duplicates where possible.
  • Globalise commonly used functions. This isn’t something I’d usually recommend but considering the constraints what the hey. Things like aliasing window to w and Math to m reduces byte-level repetition. Additionally keeping everything in a local scope lets Uglify optimise away long function names.
  • Loose comparison and other sneaky tricks. For instance using 1 for true and 0 for false saves 3 bytes per bool and works in a loose JS equality operation if you’re prepared to ignore JSHint complaining a lot.
  • Reuse everything. I reused a basic set of drawing functions and sprite classes for everything in-game, meaning each new feature was an iteration on an existing one rather than a completely new piece of functionality. See also entity component system on Wikipedia.

Further reading

In addition to my jS13k entry, I’ve got a side-build available in the
Chrome Web Store which you can install and carry around with you. The main benefit is that your scores are stored in the cloud and unlocked content goes wherever you do.

Overall I think it worked quite well and I’m happy with the result. There’s some awesome games submitted so far and I can’t wait to see how everyone goes.

The source code to Polar Defender can be found on GitHub.

Getting moving with HTML5 Canvas

Initialise a canvas

<canvas id="c" width="640" height="480"></canvas>
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

Note:

  • Width and height determine the canvas size.
  • CSS width and height will stretch the canvas.
  • 2d refers to the rendering context (API). Other options include webgl.

Basic drawing with Canvas

There are several ways of drawing on the 2d drawing context.

  • Rects (rectangles)
  • Paths
  • Text
  • Images

Drawing Rectangles

Rectangles can fill, stroke, or clear an area.

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

// Black rectangle ctx.fillRect(0,0,200,200);

// Black outline ctx.strokeRect(200,0,200,200);

// White rectangle (cleared area) ctx.clearRect(50,50,100,100);

See the Pen Canvas Rectangles by Ashley Kyd (@AshKyd) on CodePen.

Drawing Paths

A bit like Logo without the turtle graphic.

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');


// Draw a triangle ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(50,0); ctx.lineTo(100,100); ctx.closePath(); ctx.stroke();

// Draw a circle ctx.beginPath(); ctx.arc(200,50,50,0,Math.PI*2); ctx.fill();

See the Pen Canvas Paths by Ashley Kyd (@AshKyd) on CodePen.

Path Methods

You can use these methods to draw and fill lines onscreen.

Drawing Text

  • The most basic use is ctx.fillText(text, x, y, [maxWidth])
  • Use textAlign=center and textBaseline=middle to center on the specified point.
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

// Default text ctx.strokeRect(0,0,100,100); ctx.fillText('#brisjs',50,50);

// Centered Text ctx.strokeRect(100,0,100,100);

ctx.font = '12px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle' ctx.fillText('#brisjs',150,50);

See the Pen Canvas Text by Ashley Kyd (@AshKyd) on CodePen.

Drawing Images

Use drawImage(img, x, y) to splat any image or canvas element down into your current context.

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

// load an image and draw it in! var img = document.createElement('img'); img.onload = function(){ // Draw the image ctx.drawImage(img,0,0);

// and some text
ctx.font = &#39;bold 40px Impact&#39;;
ctx.textAlign = &#39;center&#39;;
ctx.strokeStyle = &#39;#fff&#39;;
ctx.lineWidth = 2;
ctx.fillText(&#39;MEMES AT #brisjs&#39;,200,40);
ctx.strokeText(&#39;MEMES AT #brisjs&#39;,200,40);

}
img.src = 'http://lorempixel.com/400/400/animals/&#39;;

See the Pen Canvas Images by Ashley Kyd (@AshKyd) on CodePen.

Using Transforms

Transforms adjust the coordinate system your drawing tools use.

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

// Example translate ctx.strokeStyle = 'darkgreen'; ctx.strokeRect(0,0,100,100);

ctx.strokeStyle = 'limegreen'; ctx.translate(100,100); ctx.strokeRect(0,0,100,100);

ctx.strokeStyle = 'black'; ctx.rotate(Math.PI/4); ctx.strokeRect(0,0,100,100);

// Make some isometric tiles with setTransform // ash.ms/blog/2012-07-08/isometric-tile-transforms ctx.strokeStyle = 'purple'; ctx.setTransform(1,-.5,1,.5,0,0); ctx.strokeRect(0,200,100,100); ctx.strokeRect(100,200,100,100); ctx.strokeRect(0,300,100,100); ctx.strokeRect(100,300,100,100);

See the Pen Canvas Transforms by Ashley Kyd (@AshKyd) on CodePen.

  • Transforms are useful for when you have a self-contained item and want it to be able to move.
  • For more information, I've previously written on transforms for isometric games.

Animation

setInterval is so 1995. Use the requestAnimationFrame method to call back before the next screen repaint.

var gameLoop = function(){
    // Do stuff
    requestAnimationFrame(gameLoop);
}
requestAnimationFrame(gameLoop);
  • requestAnimationFrame won't fire if the browser isn't painting, for instance in another tab or minimised.
  • Unit movement should be calculable as a vector, otherwise everything will stop or slow down with the render process.

Let's get moving

This demo shows the basics of animation. The sine wave is calculable based on the current time.

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

function sineWave(){ var yPos = Math.sin(Date.now() / 500 ) 100; ctx.fillRect(0, yPos, 10, 10); }

var gameLoop = function(){ ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.translate(150, 150);

// Let&#39;s draw some sine waves
for(var i=0; i&lt;10; i++){
    ctx.save();

    // pi</em>2 radians == 360°
    ctx.rotate((i/10)<em>Math.<span class="caps">PI</span></em>2);
    sineWave();
    ctx.restore();
}

ctx.restore();
requestAnimationFrame(gameLoop);

}
requestAnimationFrame(gameLoop);

See the Pen Canvas Animation by Ashley Kyd (@AshKyd) on CodePen.

Particles

Particles are one of the most useful things you can have in a 2D game.

See the Pen Canvas Particle Generator by Ashley Kyd (@AshKyd) on CodePen.

  • Particles can be anything you want, but gradients are slow to draw so you'll need to cache them.
  • You can plug in one of many physics engines from NPM, but it's easier to accelerate out from a center point.

Polar Defender (my entry into the 2014 #js13k)

js13k is a month-long game competition to make a game in under 13 kb.

  • Polar coordinates & .rotate() make it east to do a radial game.
  • SVG sprites: scalable, re-colourable assets.
  • "Everything's a particle" approach simplifies collision detection.
  • jsfxr for 8-bit sounds.
  • Using a bunch of Unicode emoji as game assets (gotta save space).
  • Code on GitHub

Play Polar Defender.

Where to go from here

There's a bunch of stuff already out there to make your life easier. Here's some of my favourites:

  • Pick a game engine (or do it by hand)
  • NPM is a treasure trove of amazing things
  • freenode/#bbg – browser based games
  • Learn about Juice in a talk by Martin Jonasson and Petri Purho

Simcity 4 Multiplayer

I've been playing a lot of Simcity lately.

I've had the idea for a while that I've wanted to do a multiplayer game with friends via Dropbox, so I roped a few people like Tate into it and we found it works surprisingly well.

After a few rounds of back-and-forth I took the liberty of rendering out a mega-screenshot and setting it up as a zoomify image. (The stitching was all done by hand, so there's a few rough edges around city borders.)

Simcity 4 is by far my favourite version of Simcity. It has a sweet 2.5D aesthetic (3D models are rendered down to 2d on a fixed trimetric orthographic projection), but more importantly it has a large community of modders and lets you build massive regions spanning multiple cities.

Newer versions in the Simcity franchise sacrifice detail for simplicity and tend to be more "town building" than "city building" sims. Of the newer games I prefer Cities XL (which I feel redeemed itself after a botched launch and a few re-releases), but it's difficult to go past the homely charm of Simcity 4.

Dates & Formatting in Javascript


Dates and Javascript haven't traditionally been very nice. The
Date object
is the only real API for managing dates and code to deal with it can be extremely verbose.

Parsing dates with Javascript

Parsing dates has traditionally been difficult with the Date object only supporting non-standardised inputs dependent on the browser:

RFC 2822
Sat Apr 12 2014 12:22:00 GMT+1000
Unix timestamp
1397269320000

But with ECMAScript 5 we can also parse ISO 8601 dates, which gives us a little more leeway. From the MDN date docs:

simplified extended ISO format (ISO 8601) is always 24 or 27 characters long
(YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, as denoted by the suffix "Z".

To parse a date in plain Javascript, you can now pass a well formed ISO8601 string to the constructor:

var dIso = new Date('2014-04-12T12:22:00.000+10:00');
var dRfc = new Date('Sat Apr 12 2014 12:22:00 GMT+1000');
var dUnix = new Date(1397269320000);

All the above will all return a valid date. Note that the Unix timestamp is in milliseconds. If you're trying to read a Unix timestamp in seconds you may need to multiply it by 1000.

Update: Turns out Safari is a laggard with ISO 8601 dates and like IE8, can't parse them at all. If you need ISO8601 dates on the client, you'll have to resort to either a custom solution or something like moment.js which supports parsing them.

Formatting dates in Javascript

The problem of formatting dates in a particular way in Javascript is difficult. If you wanted to print a basic YYYY-MM-DD timestamp you could do something like the following, but you'd also have to implement logic around padding zeroes and incrementing the zero-based month and the syntax for the most basic notation is horrible. It's no fun.

var d = new Date();
return d.getYear() + '-' + (d.getMonth+1) + '-' + d.getDay();
// 2014-4-12

One of the better libraries for managing dates in Javascript is Moment.js, which brings slick chainable date handling to the browser (or node). The main downfall is that it’s quite heavy, but when you need to be able to manipulate a lot of dates it’s totally worth it.

Our previous example can be condensed into the following:

return moment().format('YYYY-MM-DD');

Moment has some other sweet features, particularly around date parsing and manipulation so you should definitely check it out.

Specific date formats in JS and Moment

While we're at it, here's a cheat sheet of specific date formats you may need to use in JS.

Date Raw JS Moment
RFC 2822 myDate.toUTCString() moment().format('ddd, DD MMM YYYY HH:mm:ss ZZ')
ISO 8601 myDate.toISOString()* moment().toISOString()
Unix Timestamp Number(myDate) moment().valueOf()

Note that the native Date.toISOString method was introduced in ECMAScript 5, so only works in IE 9 and above.

Maps Post-Google

I spoke at the Web Directions What Do You Know night in Brisbane tonight. Here's a slightly more in-depth version of what I talked about, with links to all the good stuff. You can also view my slides though they're quite large.

Recently the Google Maps Mania blog wrote a post entitled “The slow death of the Google Maps API”, not so much lamenting the demise of Google Maps as much as embracing the change that’s occurred in this space and it got me thinking.

Google Maps used to be the only real solution to showing maps online, and I’m sure you’ve plopped down the Google Maps embed code on a contact page in your day. But lately there’s been a lot more choices cropping up in both software and services so I’m going to quickly go through some of the cool stuff you can do with maps.

Mapbox: probably better than Google?

Firstly I’ll mention that in my opinion the main competitor to the Google Maps API right now is Mapbox. Mapbox has a bunch of services and APIs for both apps and the web, and you should check them out if you haven’t already (their blog is well worth a read too).

They have a sweet web interface that lets you completely customise your map styles and content, and offer a bunch of goodies for creating and managing maps including TileMill which is the ultimate map mashup customisation whatsit.

If you’re looking to plop a map onto a contact page these guys can absolutely get you there, but if you’re looking to do a full-on data visualisation they’ve got you covered too.

Leaflet

Leaflet Maps

Mapbox are throwing a lot of support behind open source tools like Mapnik, Node and especially Leaflet.js which is the BSD licensed mapping library that most of their service runs on.

Leaflet is especially nice to use as both a user and a developer because it’s it’s super-fast and works well even down to IE7. It's completely styleable with CSS has excellent touch support for mobile devices which makes it really awesome if you need a responsive maps solution.

In terms of data visualisation, it uses SVG by default (with a VML fallback) or you can draw onto HTML5 canvas if you don’t need IE8. There's also a large number of modules you can use, both official and otherwise.

Heatwave Tracker

I’ll briefly mention the ABC News heatwave tracker which I did late last year, showing an animated map of temperatures for the past week.

This one was originally going to use Google Maps but had some performance issues on mobile that prompted the move to Leaflet.

The ABC heatwave tracker was ported to Leaflet in a matter of an hour or so.

This visualisation ended up using the basic Leaflet API to draw circles for each weather station and animating them using requestAnimationFrame. Under the hood Leaflet created a SVG circle for each of these points which turned out to be hardware accelerated to varying degrees across browsers, so it was super fast with around six-hundred data points updating at sixty frames per second.

There was no particularly tricky code involved in this, it’s all just using Leaflet’s standard APIs without any optimisations on the map side of things. The Leaflet port from Google Maps took about an hour which gives you some indication as to the effort involved.

100 Years of Air Travel

The Guardian has a much more impressive interactive with their 100 Years of Aviation feature.

This feature used a combo of Leaflet with a bunch of custom code to create a collage of maps, images, and audio showing the history of air travel. The most interesting feature is the html5 canvas-based visualisation showing all the planes in the sky over the last twenty-four hours which you can zoom, pan, and explore like a traditional map.

It's kinda mesmerising.

This one was commissioned by The Guardian and built by Kiln who I have somewhat of a map geek crush on right now. They used TileMill for the background layer (I had a suspicion!).

What about D3?

But Leaflet isn’t the only client-side library that’s doing interesting things in mapping. While Leaflet is positioned as a more traditional Google Maps replacement, D3 takes a more data-driven approach to visualising geodata.

For those not aware, D3 stands for “data driven documents” and you might remember Colin Gourlay talking about using D3 for responsive charts in the last Last What Do You Know in September.

Well D3 also has geodata functionality that can do wonderful things with more of a focus on your raw data rather than a traditional map.

This demo is from the D3 geo.projection plugin shows a few of the different types of map projection you can use in your projects, and you can see the way the map is animating between different projections that the library has a lot of power over a traditional flat map.

Earth

While this isn’t something you’d usually use in itself, it does lend to some interesting ways of visualising data, such as in the Earth global weather visualisation by @cambecc.

Earth is one of my favourite Javascript visualisations ever.

This is a really compelling mashup of wind, air pressure and temperature projected on a 2D globe then animated to show about as close as you can get to real time world-wide weather conditions.

This demo uses D3 and Backbone.js to display data which has been pre-processed from a number of different sources. It’s using the orthographic projection of D3 which presents a sweet 2d globe effect which you can spin and zoom to explore the nuances of the planet.

Because this is using the HTML5 canvas as a 2d drawing platform, all the individual data points you see moving on the screen have to be calculated each time you adjust your viewpoint. This is all done in D3 rather than on a GPU for instance, which might not be something you'd do in a super-high performance situation, but it's a really good demo of what D3 is capable of.

Google is still good…

Google Maps is still great, but they've really been focusing more on the consumer with their offerings of late.

The Google Maps WebGL globe is amazing.

The new version of Google Maps is a fantastic use of WebGL and is really a showcase use for the technology, but you can't develop against it for use in your own apps. In terms of the Maps APIs they've stagnated over the years and as a result we're seeing more innovation from other players rather than Google themselves.

So next time you're looking at doing anything to do with maps, check out some of the alternatives. You might find yourself getting more done, doing cooler things and generally looking better among your peers.

What does everyone else know?

If you weren't at Web Directions What Do You Know, here are some the other talks from the night.

Sarah Bock
Narcissism and the web
Andy Fitzsimon
Generative design is awesome (My personal favourite, I want to play with netengine.io)
Luke Brooker
Craft as in Beer
Jilly Magee
Data is the real King (and yep, content is data)

South Brisbane Fibre

Just a quick rant because I’ve been trying since October to get myself set up with fibre Internet in South Brisbane.

A little background for those of us who don’t know: South Brisbane fibre is wholly owned by Telstra, and isn’t part of the NBN. The plans are different, a lot of ISPs don’t seem to bother competing here and everything has to go through Telstra’s wholesale division.

The unit I moved into has never had a landline connected so I got hit with a ~$300 connection fee straight up. Initially Telstra thought there was a connection at this address and disconnected my landlady next door, taking out her phone and Internet for the better part of a week which was a massive pain. After that it took about a month for them to get around to installing the network stuff in my unit and another month for me to convince them it wasn’t working and come out to actually plug the fibre in at the comms room.

It literally took four hours for the poor tech to unravel the network here and get it connected. In the process I think he unplugged the line into another unit where the tenants were trying to get their own Internet connected, so they’ll probably be hit with the $300 connection fee as well.

The tech was a funny guy. Reasonable enough, although he asked me to fix his computer while he was working which was a bit awkward. When he finally got the line connected he confirmed with me that it was 30 mbit, at which point I mentioned I was trying to get 100 mbit and that something must be wrong. Before telling me that 30 mbit should be more than enough for my needs he mentioned that Telstra Wholesale only goes up to 30/1 mbit and that I’d have to sign up for a Telstra plan if I wanted to go higher.

I was pretty mad at this point, but hey, I had Internet for the moment.

Since then I’ve spent another month chasing iiNet trying to get the bottom of the 100 mbit situation. iiNet themselves have never heard of the 30 mbit limit, they’ve verified on their end that I should be getting 100 mbit, and have been super reluctant to chase it up for me. I’ve complained by phone, email, Twitter, all the while being told that someone would chase it up for me and give me a call back, or email me, or follow it up internally somehow.

I just called up now and they have no record of any of the email or phone correspondence I’ve had, the guy has reiterated that “it should be fine, have you tried power cycling your modem?” and asked me to plug my PC directly into the wall. (I’ve already done this when I initially reported the problem, I even had to borrow a laptop with Ethernet from a friend to do so.)

Meanwhile my practical speeds with two separate modems are fluctuating between the full 30 mbit and 0.5 mbit/second depending on the stars. I actually had a 700 millisecond ping to Speedtest.net this morning.

To Be Continued…

That time a truck crushed my laptop and I replaced it with the XPS 13

Waiting at the lights, my bag popped off the back of my bike somehow. I noticed straight away because the weight was different, but by the time I’d stopped and turned around, the ute behind me had driven over it with not one, but both sets of wheels.

A laptop all bent out of shape, still turns on but the screen is shattered. A tablet next to it, equally crushed.

The guy looked at me briefly, then drove off. I didn’t even think to note his license plate, I was too busy freaking out on the traffic island. My laptop is seriously my most important possession and it was immediately obvious it’s been completely written off.

I checked out my insurance, but it’s only for medical and third party which means I’ve got nothin’. I can shift some money around, but it’s certainly changed my short-term plans.

So I set out on a search for a new computer. I wasn’t going to buy another Samsung Series 9 because the quality of the screen was absolutely rubbish and having used it for a month or so I couldn’t justify the price again. So I went searching, and found the Dell XPS 13.


The Dell XPS 13 is a laptop.

Not the Developer Edition

I was originally looking at the Ubuntu Developer Edition which isn’t available in Australia. The Developer Edition comes with Ubuntu pre-installed, and a bunch of compatibility patches and developer tools already loaded on.

It’s a pretty attractive deal, because Dell have been contributing their modifications back to the Linux kernel to make sure this machine is the Linux latop amongst the Windows-crippled alternatives out there.

The XPS 13 is the same machine, just with Windows pre-installed instead. All the same bits and pieces under the hood (and a few extra stickers), but you can wipe Windows and install your choice of Linux distro over the top with no problems at all.


The Specs

There are a few models of this machine available, and I can’t find mine on the Dell site any more, so your mileage may vary.

Size
13.3″
CPU
Intel i5/i7 available
RAM
8GB Dual channel DDR3 1600Mhz
Storage
128 GB SSD (Mine has 256 GB, but this no longer seems to be an option.)
Graphics
Intel® HD Graphics 4000
Display
Full 1080p (IPS?) display
Networking
Intel Centrino Advanced-N 6235 and Bluetooth 4.0
Battery
47 WHr 6-Cell Battery
Chassis
13″, machined aluminium & carbon fibre composite shell, silicone palm rest

Initial Thoughts

My initial thoughts on this laptop were really positive. This laptop feels expensive.

Aluminium & carbon fibre shell

The device has a full 13.3″ screen, but the size of the laptop is tiny owing to the really small bezel around it. The chassis is an attractive complement of machined aluminium on the lid, carbon fibre on the base, and a silicone finish on the palmrests which is surprisingly nice to use.

There’s a metallic cover on the bottom of the laptop which opens to reveal the Windows and Intel stickers as well as FCC information and other important bits.

There are two USB3 ports, one on the left and one on the right. There’s also a Mini DisplayPort and a headphone jack. There are no other ports on the laptop. If you want to use something like cabled Ethernet you’re going to have to pick up a USB adaptor online ($10 ought to do it on eBay), or if you need more devices you’ll have to look into a USB3 hub.

I’ve noticed the lid can be a little tricky to open as the weight isn’t quite balanced with the opening mechanism but on the flip side, the lid is fixed in place wherever you put it. There’s no wobble or anything because of the heavily weighted hinge.


Installing Linux on the XPS 13

There’s a few ways you can install Linux, by USB flash drive or via an external DVD drive, it’s pretty straightforward.

The Dell XPS 13 running Ubuntu

While the device comes with Microsoft’s “Secure Boot” enabled, you have the option of going into the menus and turning it off. In addition, a number of Linux distros come with Microsoft signed keys that will run with Secure Boot enabled anyway.

Another nice touch is the ability to fall back to BIOS emulation mode, which lets you boot older OSes of if you run into shoddy UEFI support in your distro of choice.

You can get into the UEFI/BIOS interface by pressing F2 on boot. (Keep pressing it until it tells you it’s got it.)

Other than Secure Boot, this is a really straightforward machine to install on. You’ll have no problems.


The Keyboard

The keyboard is really quite nice. It’s backlit, and the chiclet style keys have a fair bit of give to them.

It’s quite nice to type with, much nicer than the Samsung Series 9 for instance, although they’re a bit softer than the generally quite firm MacBook Pro.

I’ve also been told the keyboard is an unusual layout (although I haven’t noticed), but either way you’ll likely get used to it in no time.


The Screen

The screen is the total show stealer. The original XPS 13 had a measly 768p screen, whereas this one has the full 1080p and it’s gorgeous.

I’ve gone through a few screens lately, and this is easily the best one I’ve ever used. It’s easily better than my 2010 era MacBook Pro, and wipes the floor with the rubbish used in most Windows laptops on the market these days, including the Series 9.

The screen is perfectly clear, offers no motion artefacts or screen-door effect at all (unlike it’s shonky bigger brother).

I suspect it’s an IPS screen although I haven’t been able to verify this information anywhere other than one or two news and blog sites. It has perfect colour reproduction, with no vertical colour distortion whatsoever and perfect viewing angles from all directions.

In terms of brightness it’s a 350 nit panel, which is pretty damn good. You can find other brighter laptops on the market, but this one’s perfectly good for indoor and outdoor use. It’s a glossy screen as opposed to a matte, which means it can be impossibly glarey in the wrong environments but I’ve never found myself unable to use the laptop due to lighting conditions.

Whether you’re a designer or developer, you should absolutely consider this laptop for the screen alone.


Trackpad

The trackpad is really nice. It has a smooth finish and tracks well with one or two fingers. It’s gesture capable, although I haven’t used any of these features.

Dell and Canonical have apparently taken the existing Cypress trackpad driver and extended it to support the Developer edition perfectly. These changes have been merged upstream into the proper Linux kernel and should be available on most new distributions.

I’m using the drivers that Fedora 18 picked up, and I’m not sure whether they’re the right ones or not. I’ve noticed very occasionally that the trackpad can get a little jumpy and I’ll need to suspend/resume to reset it. I’m interested in whether people have this issue in newer kernels than version 3.9.4-200.


Noise

This machine actually has a little more noise than I’m used to. While it’s no rocketship like my previous MacBook, it can get somewhat loud under load.

I’ve also noticed that the fan makes funny noises even when not under load. It’s barely noticeable, but if you shove your ear up to the bottom of the laptop you can hear it ticking and scraping. It’s a little bit of a concern, I’m not sure if I need to open it up and clean it or if that would make it worse.


External Monitors/VGA Out

This laptop uses Mini DisplayPort, like older MacBooks, which is pretty well supported.

The laptop itself doesn’t come with any cables, but you can grab a Mini DisplayPort cable to output to DisplayPort, DVI, HDMI or VGA.

I’ve driven my Dell U2711 27″ screen at 2560×1440 over DisplayPort with no problems. I understand there may be difficulties converting from DisplayPort to dual-link DVI etc for very large resolutions, so it pays to use DisplayPort→DisplayPort whenever you can.

I’ve also had problems connecting the Mini DisplayPort to a VGA projector using an Apple dongle. Turns out the Apple dongles are a bit special and won’t work with this particular laptop, so if you’re going to be presenting anywhere you’ll need to bring your own non-Apple adaptor.


Other features

The battery is a 47 WHr 6-Cell Battery but I can’t tell you much more than that. It’s not as good as the Samsung Series 9 for instance, but I rarely find it fails me when I’m out and about through the day. You should check out some other reviews for information on the battery life.

Graphics are standard Intel HD Graphics 4000, which are pretty standard across the board. The benefit of Intel graphics is that everything in Linux is supported so much nicer than with nVidia or ATI. If you’re looking for gaming, it’s not the worst you could do, but you should check around to see how the HD 4000 graphics fare on various games.

Sound is quite good. It’s much better than the Series 9 or 2010 MacBook Pro for instance. I’m not sure where it comes from, but it seems beefier than your average laptop sound. I haven’t put it through any vigorous tests (because it’s laptop sound after all) but I quite like it.

Output from the headphone jack is generally good too, free of pops and hisses, and I haven’t heard any processor squeal come through my earbuds which can be a problem on cheaper systems.


Conclusions

The Dell XPS 13 (Non-Developer Edition) is an awesome laptop and if you’re a Linux user looking for a quality device you should absolutely get this one.

While there’s a lot of different materials gone into the build, the quality is stellar. It’s a good weight, feels tough, and I consider it an extremely attractive design.

A person uses a the Dell XPS 13 at a display stand

All the useless loose ends have been removed (CD Drive, Ethernet, serial) leaving only the very basics. If you need more you can extend it with USB adaptors. It’s the ultimate minimal experience.

The speed is great, the compatibility is stellar and the display is the killer feature that beats out all the other devices on the market (with the exception, of course, of the retina Macs which aren’t much use in Linux anyway).

Everyone who sees the laptop loves it, and I recommend it for everybody. If you’re not convinced, leave a question in the comments and I’ll see what I can do to answer it. Otherwise, you’re going to love this laptop and should check it out now.

GeoJSON & Leaflet Maps

I've spent the last couple of days adding features to my site about cycling in Brisbane and my favourite would have to be allowing GeoJSON annotation of maps.

What's GeoJSON?

GeoJSON is a Javascript-based file format designed to hold geographical information, similar to KML or GPX. It's supported by default in the Leaflet mapping library which I use on Briscycle, and is supported out of the box by the JOSM map editor, which means I have a full suite of authoring tools at my disposal.

How does this help?

Previously each page about a particular cycleway or feature would have an embedded map at the bottom showing the Briscycle map layer, including various features shown on the full version of the map. This was okay, but not particularly clear, especially when explaining something like the Moreton Bay Cycleway which is some hundred kilometres long, winding around the coastline from Redlands to Moreton Bay.

Using GeoJSON I can add the fill path of the Moreton Bay Cycleway in a clear manner.

GeoJSON annotation is great because it lets me add an extra layer to the map, including lines, icons, pinned features and more.

In the case of the MBC, this includes an educated guesstimate of the entire route which people can follow from their desktop or mobile phone.

In other places I've used it to point out map features relevant to that particular route, but not necessary to display on the main map. It's even possible to use GeoJSON as the primary map source without a tile layer in the background, for instance if you wanted to map out your office or property.

Making a GeoJSON file

GeoJSON is a JSON-based file format, so you could technically write it by hand. This, however, sounds like no fun at all.

I used JOSM, an OpenStreetMap editor which offers a bunch of satellite and map overlays and lets you draw features straight onto the map. Being an OpenStreetMap editor, it's heavily tag based, which makes it translate very easily to GeoJSON, so when I was done drawing and adding my tags, I could save it straight out to a GeoJSON file.

JOSM allows you to create any geo lines, points and areas you can imagine.

It's a good idea to save your GeoJSON file in the OpenStreetMap XML format as well, since JOSM doesn't appear to be able to re-open GeoJSON files. If you need to convert a GeoJSON file back to OSM format for editing, you could use something like the trusty GPSBabel.

Mapping a GeoJSON file with Leaflet

GeoJSON is pretty well supported by the Leaflet JS mapping library, and you can get up and running straight away using the default GeoJSON layer type.

Leaflet provides a comprehensive examples page for the GeoJSON layer which includes the basics, as well as:

  • Adjusting default styles.
  • Styling individual items (both paths and points).
  • Making GeoJSON elements interactive.

I've passed a custom style function which checks the attributes on each path to decide how it should be styled. The onEachFeature lets me create popups when a user clicks certain elements, and I've added a custom pointToLayer function to override the default marker and display standard OpenStreetMap icons for points.

If you're looking at using other formats with Leaflet such as GPX or KML, check out the plugin work done by Pavel Shramov.

Best Library Ever

If you're looking for a mapping library, you really can't go past Leaflet. It might not be as mature as others on the market, but it's by far the nicest to develop with, and it's gorgeous on the client-side.

To get a feel for what I've done you can check out some of the pages I've published thus far, including the Brisbane Valley Rail Trail, the V1 Cycleway from Brisbane to the Gold Coast, and the Moreton Bay Cycleway.