Sie sind auf Seite 1von 196

The

Ann u a l Top tip


on HTMs
jQuery L,
JavaSc, CSS,
r
& moreipt
Welcome to
The

n n u a l
A
The World Wide Web is nothing short of magical. It connects people regardless
of location and opens up a whole new world of knowledge, entertainment
and community. For the creatively minded, this platform of endless possibilities
is incredibly exciting, but it can also be daunting and challenging. With so many
options, styles, skills, and languages, it can be easy to lose sight of the bigger
picture. In this edition of Web Design Annual, weve collated only the best and
the most helpful features and tutorials to separate the wheat from chaff, and
present you with an exhaustive collection of the latest in web design. Weve
covered everything from mobile browsing to virtual reality, and provided tutorials
for HTML, CSS, jQuery and much, much more. Whether youre an experienced
coder by profession or a enthusiastic hobbyist, a specialised designer with an eye
for the perfect interface or still figuring out your skillset, youre bound to find a
tutorial that tests your expertise in this book. So fire up your PC and let the pages
of this book show you the infinite possibilities of web design.
The

n u a l
An
Imagine Publishing Ltd
Richmond House
33 Richmond Hill
Bournemouth
Dorset BH2 6EZ
 +44 (0) 1202 586200
Website: www.imagine-publishing.co.uk
Twitter: @Books_Imagine
Facebook: www.facebook.com/ImagineBookazines

Publishing Director
Aaron Asadi

Head of Design
Ross Andrews

Production Editor
Sanne de Boer

Senior Art Editor


Greg Whitaker

Assistant Designer
Alexander Phoenix

Photographer
James Sheppard

Printed by
William Gibbons, 26 Planetary Road, Willenhall, West Midlands, WV13 3XT

Distributed in the UK, Eire & the Rest of the World by


Marketforce, 5 Churchill Place, Canary Wharf, London, E14 5HU
Tel 0203 148 3300 www.marketforce.co.uk

Distributed in Australia by
Network Services (a division of Bauer Media Group), Level 21 Civic Tower, 66-68 Goulburn Street,
Sydney, New South Wales 2000, Australia, Tel +61 2 8667 5288

Disclaimer
The publisher cannot accept responsibility for any unsolicited material lost or damaged in the
post. All text and layout is the copyright of Imagine Publishing Ltd. Nothing in this bookazine may
be reproduced in whole or part without the written permission of the publisher. All copyrights are
recognised and used specifically for the purpose of criticism and review. Although the bookazine has
endeavoured to ensure all information is correct at time of print, prices and availability may change.
This bookazine is fully independent and not affiliated in any way with the companies mentioned herein.

Web Design Annual 2015 Imagine Publishing Ltd

ISBN 9781785461798

Part of the

bookazine series
W
The

&R Q W H Q Annual

8: HTML & CSS animation


DESIGN
16: Web of Things
122: Your best CSS ever
CODING
130: Create a colour swatch
26: HTML & CSS patterns tool with Vibrant.js
34: Customise maps with 134: Alter page
the Google Places API element colour
40: Create virtual 138: Build custom layers
reality panoramas with CSS
44: Build iOS-style web 142: Expert guide to web 3D
applications with
Framework7 150: Interactive 3D game
with WebGL
48: Deploy your web
apps to Heroku 154: Image-based
pop-up menus
54: Develop a web app
quickly with Lucee 156: On-click popup tooltips
60: Atom 158: On-click transitions
66: Create desktop
applictions with Electron 160: Latest CSS4 selectors

70: Use NW.JS to develop 164: Circular


desktop applications on-hover animation
76: Robust Javascript code 166: Flick background image
82: Make a playlist
with Last.FM 168: Slide down on
scroll menu
88: Complete guide to GIT
170: The importance
94: 20 Best GIThub Projects of typography
100: Build a friendly bot
to enhance your 178: Animate type
Slack group & text

106: Create API schemas 182: UX design


with Swagger
188: Enhance UX with
112: Future HTML Hover CSS
The:HE'HVLJAnnual

Presenting

T S R E V E A L THE PATH TO BUIL


EXPER UTIFUL DYNAMIC DESIGN DING
BEA S
// HTML & CSS ANIMATION

Whats up with
web animation?
A sk any two designers what they
think of animation, and youll get
six opinions. The web still hasnt quite
emphasise the stories you want the site
to tell.
If the animation isnt helping out, dont
recovered from the Flash years, when use it. You can make exceptions for
loading and splash pages stressed showcase and demo sites where youre
prebroadband modems and made users exploring a new technology. But for
wait for extravagant doodles. general public access, animation should
For designers, Flash was a brilliant way always be able to justify its existence.
to rack up the billable hours. It wasnt so As the technology has improved, the
popular with visitors, who either learned limiting factor for motion design isnt the
to click on the Skip animation button as technology. You can use animation
soon as it appeared, or were left frameworks and plain CSS3 to do almost
wondering why theyd just spent two anything you want in 2D. 3D isnt quite as
minutes watching a cartoon rocket land developed, but it doesnt have as many
in a giant vector graphic cheesecake. clear use cases, and most sites work fine
Of course Flash is still around, but it with 2D animation, perhaps with a few
doesnt seem to be winning new fans. understated 3D accents.
Today, most clients and creative directors
are going to look strangely at anyone
The challenges have more to do with
clever design, creativity and most of all
Shane Mielke
who suggests a splash screen, whether it efective communication. Animation isnt Creative director at shanemielke.com
uses Flash or a more recent technology. so much about moving divs as about


That could be because modern moving visitors. If it isnt doing that, you
animation has calmed down and tried to may need to rethink it. CSS and GreenSock animations are
make itself more of a team player. Instead To make life easy, well pull out some of amazing ways to spice up your front-end
of being all about the technology or the the recent UI and UX design trends so
designer, animations have become more you can look at them in more detail.
builds. Pixi.js and three.js give us 2D and 3D
about the design. Theres no need to start with a blank WebGL/Canvas animation playgrounds. In
So what is animation for? Its easy to editor and an equally blank expression. the right hands all of these tools can work
make a site where everything moves all Modern animation design doesnt mean magic. Were just missing a standardised
the time, but visitors will hate it. Its more starting from scratch on every project. A
useful to think of animation as a power few hints and suggestions go a long way,
timeline animation IDE like we had in Flash


tool you can use to enhance your sites as does some knowledge of what the rest that will output clean, lightweight code.
production values, help users find their of the industry is doing. If youre ready to
way to the content theyre looking for, and be moved, read on
The state of browser support

CSS3 keyframes 10 4 16 4 15 7.1 4.1

CSS3 animation 10 4 16 4 15 7.1 4.1

jQuery 1.X animation 6 Current Current 5.1 12.1 6.1 4

jQuery 2.X animation 9 Current Current 5.1 12.1 6.1 4

Other JavaScript
frameworks 9 Current Current 5.1 12.1 6.1 4

The SmartWater site (drinksmartwater.com) WebGL [1]


has some charming animated interactive
11 31 31[2] 8 29[2] 8.3 40[2]
clouds that reinforce the brands message
[1] Requires compatible graphics hardware [2] Partial

9
:HE'HVLJ
The:HE'HVLJAnnual

Animation in Action
Dreamteam
dreamteam.pl
The use of web animation needs to considered and have value. Alternatively, it
can be something to adore and be admired. DreamTeam by Polish creatives
BrightMedia sits very much in adore and admire. The homepage animation reveals
itself with a simple straight line before blossoming into a fully fledged animation.
The fun doesnt stop at the homescreen, scroll down and watch more smart design
unveil itself.

All for show


The opening animation has no real purpose other
KEEPING than to engage and excite the user. The
UP moment the animation starts, the user is
The creatives behind hooked. An attention-grabbing design is
guaranteed to give the creators attention
DreamTeam are Polish agency
right across the web design community.
BrightMedia. Keep up with their
latest work via brightmedia.pl.
Alternatively, check their
Twitter @brightmediapl
for latest updates.

UI animation
Simple navigation animation is used to enhance the
overall site. To reinforce the common purpose of the site
each menu item has a rollover efect. A solid white
background eases in with a subtle animation and
immediately draws the users attention.

The technologies & tools Yahoo especially in the form of AlloyUI (alloyui.com)
which merged it into Bootstrap.
Now jQuery has taken over most of the load, with its
Keep it simple with CSS3 Theres one catch. CSS3 runs eficiently inside the .animate function, which includes easings, durations, and
Knowing how to work with CSS3 animations is a core browser with superfast precompiled code. JavaScript the ability to animate any numerical CSS property.
skill now. CSS3 animations are split into two related tag animation is compiled on the fly, and its not nearly as But thats not enough for some projects. For more
groups. The transform tags move things around the eficient. So if you do anything complicated youll kill the control, you can work with more advanced frameworks
screen, with simple support for 3D. The animation and battery life on mobile, and heat up the processor on such as paper.js (paperjs.org), Raphael.js (raphaeljs.com)
keyframe tags control the movement. desktops and laptops until the fans kick in. and Processing (there are two web versions
But there are downsides, and these will include some Raw JS is a powerful option with a lot of creative processingjs.org and p5js.org). For those who want a
of the usual CSS gotchas. Its easy to make animations potential. But you will need to handle it with a lot of care. Flash-like interface, theres also the paid-for GreenSock
that almost work but its possible that they may just start framework (greensock.com).
or stop in the wrong place, or dont quite loop as you Working with frameworks The big advantage over basic CSS3/HTML is support
want them to. And CSS3 simply isnt very smart. You can JavaScript wouldnt be JavaScript without more libraries for vector graphics and simplified animation loop that
link animations to events in a basic way, and you can than a human brain can remember. Luckily only a saves you from dealing directly with timers.
chain and link animations to create complex efects as handful are popular at a time. A few years ago MooTools Which should you choose? Processing is the most
well. But its dificult to make animations respond to FX Morph, Transition and Tween classes were widely sophisticated, and supports pixel-level manipulations
surrounding content. used. (See mootools.net for details.) Yahoos YUI library although theyre buggy in processing.js videos,
(yuilibrary.com) also found favour, inside and outside webcams and sound. It works with HTML5 Canvas tags,
JS & jQuery: the missing link

Raw JS is a powerful option with a lot of


JavaScript and jQuery can fill in the features that are
missing from CSS3. Do you need to make sure an
element wont fall of the bottom of the screen, or cover
something important when the user reveals it?
creative potential. But you will need to handle
JavaScript is the solution.

10
it with a lot of care

// HTML & CSS ANIMATION

Web animation
API: a new
solution?
If youve looked at native apps, youll know the
web doesnt have anything quite like the slick
HTML5 technology and streamline native animation frameworks
Taking a peek at the source built into iOS and Android. The W3Cs web
code reveals a surprisingly slim
animation API is an attempt to fix this. Its not a
page. It is the HTML5 Canvas
element where all the hard drop-in replacement for mobile animation, so
work is done. The animation dont expect to make elements glide or fade more
sits quietly in the background easily than in the past. For better or worse, the
claiming all the glory while the W3C committee have gone in a diferent direction.
standard HTML creates the
The current proposal bundles the existing CSS3
crucial elements needed to
navigate and guide users animation features, extends them to allow simpler
around the site. DOM element animation and adds some welcome
extras, including support for a timeline and for
play state management. Keyframes also get an
upgrade, so you can do more with them. Its also
going to be possible to start, stop, restart, and
pause animations using JavaScript code, which
And theres more will fix some of the limitations of CSS3 animation.
The homescreen is If youre thinking this sounds a little like Flash
undoubtedly the centrepiece
it does. Or at least, the timeline and keyframe
of the DreamTeam site, but
complimentary and more features do. When web animation becomes widely
constructive animation is supported its going to become easier to chain
incorporated into the site. animations, to create animated efects by
Simply scroll down the page to
flip-booking SVG files, and to make animations
see how subtle user interface
animations are introduced into respond to external events.
the site design. So its better to think of it as an animation
management system, and not so much as a new
set of canned efects you can drop into your pages
with almost no code.
Motion The current API proposal has issues. One big
so its good for big animated emotion with it it will definitely take your data problem is lack of synchronisation. You can make
backgrounds and digital art. Dont forget that many CSS tags vis skills up a couple of levels. events play together on the same timeline, but its
However its not so ideal for including older pre-CSS3 tags hard to guarantee that animations on separate
making UI elements and moving can be animated. So animation WebGL and 3D timelines will remain synchronised across a page.
them around. Raphael and paper can mean creating opacity animation Another problem is complexity. The API
are simpler, and concentrate more on fades, animated borders and Waiting in the wings is 3D animation proposal tries to do so much its not a model of
vector graphic design with a hint of text decoration. and rendering. This has a lot of elegance and clarity. Its possible to create
animation. GreenSock is much used by potential, but its not quite there yet. The complex animations with it, but its not going to
corporates and adds useful functions that WebGL standard is a simplified version of the win awards for being easy to use. This is good
simplify CSS animation. Theyre all worth looking at, OpenGL 3D graphics programming API used in news for designers with good code skills, who will
because knowing whats out there can spark new ideas high-poly commercial games. continue to be in demand. But perhaps its not so
for existing designs. This sounds like a good thing. But not all platforms good for the state of web animation in general
support all features, and some older hardware barely although its likely that as soon as the spec is
Visualising data supports WebGL at all. So you cant rely on it. And its finalised, its going to be wrapped into a friendlier
If youre working with data visualisation, the go-to hard to make it look awesome. Gamers are used to and simpler framework so more people can use it
framework is d3.js. (d3js.org.) d3 is a monster that chews high-poly rendering with advanced lighting efects, and without reaching for the paracetamol.
on data and spits it out in almost any shapes you can WebGL cant match that. Whatever the limitations, the API is the most
imagine and a few you probably cant. Its immensely Finally, its hard to use. The three.js framework (threejs. exciting thing to happen to animation since CSS3.
powerful, but also has a steep learning curve. If you can org) makes it more accessible, and there are plenty of It should be ready for commercial use within a
hack it though, its ideal for making and animating UI demos to learn from (look out for the work of mrdoob year or two. Currently its being considered by
elements, especially if youre using them to display you can follow him on Twitter @mrdoob). But its still a Microsoft. Chromes developer builds include it,
quantitative data. couple of levels up from plain CSS. and Firefox has a not-quite-there implementation.
To help you get started, the d3 site has a huge Is it worth it? For plain vanilla UI design, no. For more Older and more obscure browsers will play
selection of demos and examples. Dont expect instant experimental projects, its certainly worth exploring to catch-up, as usual. If you want to know more,
results, but if you can spare a week or two to get familiar see whats possible. check out w3c.github.io/web-animations.

11
:HE'HVLJ
The:HE'HVLJAnnual

Make animation work for the user


In a world after Flash, the point of animation is to equivalent of the animated GIFs that haunt the ancient visual equivalent of an <important> tag. It highlights
enhance the user experience without distracting or underworld of amateur web design. something you want visitors to remember.
annoying your users. Its not quite true that animation The next UX group are the attention-getters. When At the top of the animation tree are full-blown
should be unnoticeable sometimes you want you want a user to focus on one point in the web sales infographics. The genius of motion design means you
something that stands out. But it should never clash with pitch, add some content-related animation to make that can make infographics interactive (see page 48 for our
the rest of the site design, it should never draw attention element stand out. These elements are the descendants tutorial). This often works better than leaving users
to itself without a good reason, and it should always of the old splash pages, but theyve been toned down for passively looking at the screen as an animation plays
provide a clear user benefit. modern sites so they dont overwhelm visitors. Theyre through. Its a huge win for all kinds of education and
Modern motion design has split into three main areas. very popular on Bootstrap sites, where one item out of training sites, where you can build a simulation and help
UI sweeteners add a hint of eye candy to plain vanilla UI two or three has added movement and maybe tells a users learn about a topic by interacting with it.
elements to raise production values without beating short story. Typically theyre spread over a third or a But animation isnt an obligatory part. Adding a simple
visitors over the eyeballs with designer awesome. quarter of the page, and theyre more cute than splash or bounce tells the user theyre in a new part of
cinematic. The animation works a bit like a tiny video that the site, and youre telling them a new chapter in your
Staying focused dramatises the point of the element it decorates, like the sites story. With careful tuning you can make the motion
The aim is to make your site look slicker, smoother and
glossier, and generally more sophisticated and
authoritative. A little CSS3 or JavaScript can do a
lot of good, but if the user is more likely to
remember the motion than the content Speed
you may want to rethink your design up jQuery
strategy especially if you start JQuery isnt fast, and .animate
veering towards the sketchy end of is even slower. To make your
town with insane animate- animations faster and more
everything excess, and overly eficient, try Velocity.js (julian.
bouncy, distracting image carousels com/research/velocity) for a
and sliders. These are the modern drop-in .animate
replacement.

Edwin
Europe
edwin-europe.
com
Check the Denim fit guide Vimeo
to see the 360-degree Cameo
view: animation with vimeo.com/
the wow factor. cameo
Subtle, simple and
efective animations that
work on diferent levels
on diferent
devices.

12
// HTML & CSS ANIMATION

a thing of beauty that stands on its own. Make sure that decorations and pop-ups. Getting links right is always a colour. Apples You got that wrong, so this text box looks
you keep it short though challenge. A subtle mouseover underline animation can like its shaking its head is the classic example here.
help draw attention to a link without making the rest of Skeuomorphisms help make the site feel more
Make UI engaging the page look busy and link-heavy. Another example are physical. The aim here is to use visual metaphors to
Why spice up a UI with animation? Too much twitching form error notifications. Have you ever pressed Submit suggest physical objects. Often, just a hint of physicality
and blinking can give users a migraine. But just the right on a site and then wondered why nothing happened? is enough for more weight and presence.
amount of animation can make the diference between a Site designers realised it was helpful to highlight mistakes Attention seekers are the final UI group. They provide
boring site and one that users will keep coming back to. in red, so users can see problems immediately. important stand-out features that cant be ignored, so
In outline, there are three kinds of UI animations. But sometimes this is too subtle. You can use theyre hard to get right. Examples include FILL IN OUR
Highlighters decorate existing content to suggest an animation to draw attention to problems by making FEEDBACK FORM pop-ups, but you can also find them
afordance. The most obvious examples are link incorrect elements move a little, as well as changing scrolling up from the bottom of the page on news sites
to ofer breaking news.

The right amount of animation can make


the difference between a boring site and one
Attention seekers tend to annoy users, so consider
using animation to make them less distracting. Make
pop-ups appear at the side instead of the middle of the

that users will keep coming back to



viewport, and put breaking news in a window. The
animation should always help the user, not distract them.

Catch
the dragon
catchthe
dragon.nl
Car manufacturer Peugeot
combine video, VR and
animation to create a
breath-taking
experience.

13
:HE'HVLJ
The:HE'HVLJAnnual

Tutorial degrees between each dot and create a radius object


that we will use to tween the position of each individual
Create a dot. We are using 7px as the value for distance you can
play around with this value to create a circle with less or
pulsating circle more dots in it.

Hello Monday technical lead Torben 3. The init method


Dalgaard Jensen reveals how they Here we are creating each individual dot. We need to
created the effects on Revelator.com convert the degrees to radians and then calculate the
The Revelator website is built on the idea that you only initial position using trigonometry. We find it easier to
need to use one platform if you want to run a music work with degrees than radians, but this step can be
business. We wanted to showcase this idea by leading skipped and do all calculations with radians.
the user through an animated story that breaks the
features into simple steps. Below well explain how you 4. Implode and pulse
can create the type of animation we used for the These methods tween the radius value and update the
Promote feature. position of the dots (see next step). In this example they
Well use trigonometry to create the pulsating efect will keep running each other when the tween completes
and write it entirely in JavaScript. GreenSock TweenMax is to create the pulsating efect.
used for the tweening, and we will be writing a JavaScript
object instance for the circle so that we can preserve 5. Update
modularity and readability. Now what well do is we will update the position of the
dots based on the new radius value we are tweening. Torben Dalgaard Jensen
1. Initial setup Then we will be delaying them incrementally to create Technical lead at hellomonday,com
First what we will do is create a container and an array to the staggered efect.
hold the circles. Then we are centring the container
within the window. Also we are writing some stub code
that we will revisit later.

2. Create DotCircle.js
We will go through the methods for the stub code for the
6. Ready to rock!
Going back to the main script we will now create three
instances of the DotCircle with incrementing radius. Then
we will start the animation, again using delay to stagger
them. For the full code in this tutorial, make sure that you
We wanted to create a visual
representation and give a sense
of the excitement and relief
musicians feel when they release
their music and see the mood of


DotCircle in the next steps. We calculate the distance in check out FileSilo (filesilo.co.uk/webdesigner). their fans rise.

14
// HTML & CSS ANIMATION

Q&A
Animations: keep it simple Resources
Interviewing Julian Shapiro
Animations have varying levels of expressiveness and bit.ly/1Jzl5tX
personality. The most colorful kind like 3D flips,
bounces or elastic easing can be a great way to make Find out what velocity.js author Julian Shapiro thinks
an interface more fun but since theyre so distinct its is going to happen next on the animated web. Read
easy for them to be visually fatiguing. Its generally better his comments about the diference between good
to stick with simpler animations for things that people and bad animation design, learn about the imminent
interact with frequently and save the more playful ones speed and eficiency bump, discover how too much
for areas that are used more seldomly. creativity can be a bad thing, and why education
Another rule of thumb I use is to show slow and hide matters more than ever in motion design.
fast. For example, I might run a half-second intro
animation for a modal dialog but hide it without any Rachel Nabors UX Guide
animation at all. The rationale here is that youre more bit.ly/1R6UdWj
willing to watch something you requested animate in
than you are waiting for something you dismissed to This excellent slide deck introduces the latest trends
animate out. in animated UX design from the perspective of a
trainer and designer. You may not necessarily agree
Q. Which web animation technologies currently with all the points especially the one about the
excite you and why? return of splashy flash screens. But the rest is
CSS transitions and animations are the technologies that definitely well worth reading for a creative and
I care most about. Combined they are flexible enough to inspiring overview.
achieve the efects I want and its been great seeing
Hakim el Hattab them gain broad support so quickly. Val Heads Videos
Designer and developer vimeo.com/valhead/videos
hakim.se Q. Web animation has vast potential. How do you
see it evolving over the next couple of years? Not so much of the future, but you may as well get a
Q. The use of web animation in any project needs I expect tooling to get a lot better and I know that good guide to the state of the art in the present
to be carefully considered. What advice would browser vendors are making good progress towards this. before you go ahead and any higher this collection
you give to designers and developers? Working with animation is a visual process often of tutorial videos covers all the CSS3 animation bases,
When working on a web app keep in mind that excessive requiring many iterations of number tweaking and and includes an impressive collection of design
and lengthy interface animations can reflect negatively previewing. If friction can be removed in that workflow examples. Theres only about half an hour here in total
on the app as a whole. If animations are too slow the app well see higher quality animations. though, but its certainly time well spent, especially if
itself is perceived as sluggish. If there are too many The Web Animations API is looking promising too. youre just starting out.
things animating too frequently it wont feel reliable and Theres certainly a need for animations that can be
robust. Keep animations brief and remember that not controlled more explicitly via a script than whats Narayan Prustys Web
everything needs to animate. currently possible with CSS transitions and animations. Animation Tutorial
qnimate.com/web-animation-
api-tutorial
What next for animation? If API specs make you dizzy you can find some simple
code examples of the Web Animation API here.
In the past, web design was split into epic splash same contemporary flat, minimal, cartoon-style design Theres a handy comparison with traditional CSS3
animations and relatively small and trivial UI tweaks, language common on the web, but add an animated animation, so that you can see how to move from the
with a few sliders in the middle. What happens when twist to highlight a feature or make it more memorable. old API to the new one. Its not going to win any
the web animation API becomes more widely used and Eventually some icons will be animated as a matter of design awards, but its a good place to start if youre
designers can work with more complex animations? course. Balance is key. Too much movement is confusing feeling lost and confused about where animation will
Some designers will stampede back towards epic for users. Animated GIFs were the bane of the early web, go in the future.
splash pages. Even though loading times and browser and animated icons could easily become the modern


speeds make splash pages more feasible than they were equivalent. But they probably wont, because designers
in their heyday, its likely theyll remain a sideline. are more experienced now, and theres more of a trend The trends in
The trends in current design are clear: theyre all about
integrating animation with content or rather, about
towards minimal design, where designers keep removing
elements until theyre left with the bare essentials.
current design are
enhancing content with tasteful and relevant animation.
Parallax scrollers, minivideos, and animated icons do this
If those essentials happen to include some movement
that can justify its existence by telling a story about some
clear: integrating
already, with varying degrees of success. content or highlighting the afordances of an icon or animation with


For examples of possible future trends, run a search other UI element, that could potentially make the web
for the animation tag on Dribble. Most examples use the much more creative for everyone. content

15
:HE'HVLJ
The:HE'HVLJAnnual

WEB
OF
THINGS The IoT revolution has only just begun.
The Web of Things is here to brush aside
proprietary protocols and help bring web
standards to the party
// Web of things

AdaFruit
on IoT Daniel IoT to WoT
Limor Fried might be a Rosenstein Olimex The paper published at
media darling her blog @Olimex vs.inf.ethz.ch/publ/papers/
(blog.adafruit.com/
@IoTDan This Bulgarian dguinard-fromth-2010.pdf
A Microsoft expert veteran manufacturer can be considered one of
category/iot) nevertheless and a must-follow for of developer boards is
tends to contain all kinds of anyone who uses an essential the first bits of research
interesting morsels .net technology resource. outlining the way from IoT
somehow related to the in IoT. to WoT.
Internet of Things.

2015
5 billion The IPv6 protocol
It is estimated by 2017,
IoT will have 20 billion
connected things means that there will
be 340,282,366,920,9
connected devices
compared with in use. 38,463,463,374,60,43
1,768,211,456
smartphones which
will have 7 billion
connections. 2020
25 billion
addresses compared
to v4 which had
4.3 billion.

connected things
in use..

IoT slideshow Hack a Day


Hosei University in Japan
Atmel Microchip You never know what to
has an impressive lecture
Corporation Technology expect visiting hackaday.
@Atmel @MicrochipTech com. The team does an
slideshow (Wcis.k.hosei.
Atmel is a fierce Microchip can be excellent job at collecting
ac.jp/~jianhua/course/ubi/ Microchip competitor considered the go-to
Lecture11.pdf) with many and a global leader in source for reliable all kinds of information
application examples of microcontrollers. microcontrollers. which might interest
IoT in action. tinkerers and developers.

The IoT is the next frontier of distributed computing and ambient intelligence and
as such meant to change the way we live, work and play. However, IoT is still
perceived by most people as just a framework of things connected and
controlled by a smart device. A more comprehensive view sees IoT as the
bridge between the digital and physical world, the space where the natural
boundary between the two becomes blurred and new things happen. The
Web of Things is the additional application layer which implements a
broader view, allowing links with the web and web data, content and services.
Dizmo fully embraces the Web of Things, its concept and programming
technologies. It provides the infinite whitespace where the objective of the
Web of Things, to extend the reach of the IoT and to simplify its full


implementation, can be achieved
Luigi Mantellassi, CMO at Dizmo

17
:HE'HVLJ
The:HE'HVLJAnnual

W hen Kevin Ashton was working at Procter &


Gambles, he recognised that RFID technology
could simplify the ever-confusing factory floors. It Turning IoT into WoT
takes but one look at the vast factory halls of an
aeronautic company be it Tupolev, Bisnovat or Ilyushin HOW THE WEB OF THINGS NETWORK MAKES USE OF WEB STANDARDS
to see, as Howard Moon would put it, a microcosm of Ever since the OSI model was specified, networked Moving our aforementioned cofee machine to the
creative chaos. systems had a tendency to be broken down into WoT would require the implementation of a
Kevin Ashton used the term Internet of Things to tie individual layers. standardised communication protocol: be it low-level
his idea into the dot-com bubble. His suggestion was The Web of Things can best be described as the or a more general and developer-friendly interface
simple: to provide the individual containers with some application layer for the Internet of Things. What the such as JSON via REST.
degree of intelligence to enable process optimisation. IoT does is it looks at the technological side of things One interesting extension to the topic involves
For example a bakery could know that a particular that may not have looked techy before. A cofee real-time-systems: HTTP is badly suited for this and
type of product, ie a chocolate cake, is running low; an machine which communicates via a proprietary thats because of its relatively complex handshake
email to waiters would be ardent in order to inform them protocol is a perfectly valid IoT application for example. architecture. Developers can solve this problem by
that pushing sales of chocolate cake is not sensible due In the WoT the situation is a bit more complex. abusing streams of media protocols
to the lack of stock. Normally, Web of Things solutions are based on such as RTP/RTSP. XPP or
Miniaturisation has enabled chip vendors to standardised web technologies. This means that the WebSockets may also
produce-ever smaller microcontrollers which can subsist individual devices tend to be addressable via a URL. see some use here.
on amounts of power which would have been obscene
ten years ago. Back then, a MCU draining ten milliamps
was considered frugal. Today, this would be excessive.
For individuals, the Internet of Things can bring both
benefits and problems. For example, insurance
Microsoft
companies now deploy health-measuring devices which on IoT
are to be worn around your wrist at all times. The data Open blogs.microsoft.
collected by these systems is transmitted to a central
com/iot in order to treat
yourself to a selection of all
server, where your GP can analyse it in order to
things IoT and Redmond.
determine whether you are behaving in an healthy and You might not believe it, but
sane way. Thus, a binge-drinking party might be cut Microsoft is a
short by a call from your friendly GP reminding you that significant IoT
you already have hypertension whether this is a good player.
or bad reminder will need to be decided by each
individual of course.
This kind of scenario is now more common though
Arduino
When working with Arduino planars, creating a system for
and we will look at a selection of topics connected to our Internet of Things can be as easy as hacking together a web
everyday lives with this upcoming field of technology. interface and a basic hardware driver

IoT hardware
HOW SINGLE BOARDS HAVE TRANSFORMED THE INTERNET OF THINGS

When looking for IoT solutions, always keep in thousands of diferent controllers. Purchasing a chip is
mind that your customers brains are firmly tuned but a small part of the solution: all kinds of additional Cheap as chips
to the good old radio station going by the name hardware is required in order to get the MCU up and When purchasing electronal components, local
WIFM. In case any of you are not aware of the meaning running. This might not be a problem for experienced retailers tend to be ideally suited for prototypes.
of this acronym: it stands for Whats In it For Me?. electrical engineers if you dont know the diference Once large-scale manufacturing starts, importing
Successful IoT projects tend to be the ones which between an easistor, a transistor and a thyristor then your components from China provides significant
provide monetary or comfort value to their customers: taking this approach is not sensible. savings. One good website to start out is AliExpress:
humans are, by nature, not masochists and want a A variety of third-party vendors provide so-called be aware that shipping can take up to a month and
bang for their buck. evaluation, or development boards. Initially intended that American Express credit cards are not accepted.
for electrical engineers evaluating a new chip type,
Arduino and friends eval boards provided simple access to various
Picking a microcontroller is a daunting task. peripherals. An Italian researcher called Massimo Arduino series has since established itself as the main
Manufacturers provide an insane pile of diferent Banzi was among the first to figure out that eval boards dominant player in amateur embedded development
models: large vendors such as Microchip sell could also be used as single-board computers. His of today.

18
b of things

Apple watch
One of the latest, and most
popular smart devices to
enter the consumer market

RasPi
This single-board computer can be used to connect to all
kinds of items. What about a doorbell that sends a text,
makes a call and captures video of whos at your door?

Why it matters
A GREATER CONNECTIVITY IS JUST ONE BENEFIT
Internet of Things can be considered the pinnacle of the convergence trend,

Whats WoT?
started by smart TVs, smartwatches and similar devices.
Human life would be made easier if the things surrounding us were provided
with intelligence of their own. Imagine a washing machine which completes work
on sensitive shirts only when its owner is on their way home. Theres also the old
THE WORK THAT DIFFERS THE TWO NETWORKS adage of the fridge which automatically orders more Red Bull as stock dwindles.
Having started out with the use of RFID, the Internet of Things can best be For developers, unlimited opportunities await in this field. Take a look around
considered the lower levels of the Web of Things. IoT-related applications are you and were sure you will see an endless deluge of dumb devices begging to be
confined to state information contained in real-world objects. They must be made made a little smarter. Programming their embedded firmware, is of course, one
available to software actors and other devices, which then act accordingly. way to profit from this trend. This, however, requires significant amounts of highly
For example, a shipping container could be equipped with an RFID tag technical knowledge. Fortunately, the frontend of most devices needs to look
containing its ID information and a microcontroller measuring the weight of the great: an area where web designers creative experience will be of unlimited value
contained iron ore. An intelligent steel plant could then parse this data in order to to the manufactures and the developers alike.
determine whether a second ore smelter needs to be fired up. Cutting a long story short: IoT and WoT are buzzwords which will make many
Even though the distinction between IoT and WoT is blurry at best, at the people really, really rich. Web developers can profit from it in two ways: first of all,
current state of the procedures it is safe to consider lower-level work the pinnacle endless opportunity awaits in the creation of the user interfaces for devices.
of IoT development. In practice, developers should not be too concerned with the Secondarily, accessing IoT and WoT peripherals adds a new layer of context
two terms: just choose the one which sounds best. sensitivity to your systems.

The biggest strength of the Arduino Platform is its Yn can link into a local Wi-Fi with minimal efort. Third When working on small-scale solutions, the added
standardised expansion slot. Known by the name of parties provide similar boards with embedded RFID or cost of an evaluation board tends to be ofset by the
Shield, it has two rows of sockets. Expansions are Bluetooth low-energy radios. cost of getting boards and sensors manufactured. In
plugged into these, the compiler architecture ensures Arduino is but one possible system. The Raspberry this case Microsofts Gadgeteer can be an attractive
that driver deployment isnt an issue in most instances. Pi has recently seen quite a bit of use in the IoT space. alternative it provides a set of prespecified
Due to the ubiquity of the Italian process computer Boards from the Bulgarian consulting company Olimex components ranging from displays to cameras and a
family, a large ecosystem of Shields have cropped up. have also made significant inroads. wide array of other sensors. Their most significant
Your Arduino can be connected to wired ethernet, Once your solution has reached production benefit is that they can be connected using a
Wi-Fi or Bluetooth LE it is but a question of selecting readiness, bundling it with a process computer can be standardised interface: building up your IoT system is
the correct Shield and plugging it into the planar. expensive due to place and material cost constraints. as easy as connecting the elements to one another.
In addition to that, a large group of more or less Many single-board computers have an open hardware
eficient combination planars has seen the light of day. design, letting you embed their circuits into a planar of The IP address problem
The superpricey Arduino Yn combines the AVR-based your own. This is especially true of the Arduinos except Radical proponents of the Internet of Things propose,
Arduino with a Linaro-based minicomputer which has for the Yn: they are based on stock AVR processors at some point, every device in the world should be
a Wi-Fi transmitter. A circuit connected to an Arduino that run on simple breadboards. intelligent. Sadly this does not work well with the
existing IP protocol, as it was developed to provide

Many single-board computers have an about 4.3 billion addresses. This was more than
enough for the tiny network the explosive growth of
open hardware design, letting you embed their the internet has since led to a phenomenon known as
IPv4 address exhaustion. The price of individual IP
circuits into a planar of your own
addresses has been on a permanent climb since.

19
:HE'HVLJ
The:HE'HVLJAnnual

In the real world


THE IOT OUTSIDE OF ITS DIGITAL ARCHITECTURE

Smart LED bulbs Run tracking


belkin.com/us/Products/home- apple.com/ipod/nike/run.html
automation/c/wemo-home-automation Music can transform a boring jog into
Turning lights on requires you to walk to a a meditative experience. Apple
nearby switch in the dark. Belkins WeMo promoted its iPhone 3GS via
system wants to break this never-ending cooperation with Nike which has since
cycle by providing a smart adapter which been expanded across the entire
is plugged into a mains outlet. A product portfolio. The idea is relatively
companion application connects to the simple: a small sensor is embedded
adapter, permitting you to turn the into a space below the sole of your
attached peripheral on and of as pair of sneakers. While running, data
needed. In addition to that, smart LED is transmitted to the iPhone it uses this
bulbs are sold their colour hue can be data for profiling. More advanced systems
adjusted dynamically. Finally, third parties could perform real-time exercise intensity
are permitted to license the standard for use tracking: overtraining is the bane of amateur and
in their own products. professional joggers.

Fulfilling garbage
potential
bigbelly.com/solutions/stations
Overfilling trash cans are an eyesore. Sadly,
Mobile
emptying them every day puts an unnecessary drain Internet
on community resources. Bigbelly solves this problem by of Things blog
providing intelligent garbage cans. Each Bigbelly can Dr. Florian Michahelless
contains a small solar cell. It provides energy for a small blog can be accessed via
wireless transmitter which returns fullness information to a florian-michahelles.
cloud service. Municipal administrators use this information to
blogspot.sk. It contains
links to all kinds of material
optimise garbage collection: the waste collection service no
which might be interesting
longer needs to check which cans are empty. Furthermore, to IoT devs.
valuable information on citizen habits can be collected by
analysing the amount of garbage produced.

Due to widespread adoption [Bluetooth


In the media, Network Address Translation (NAT) is
considered one way to mitigate the problem. In
practice, however, it does not really work routing
multiple devices of the same type through a router can
LE] is a winner it could even thrive without
become a nightmare to set up and furthermore makes
the use of a unique port number dificult.
The solution is a new generation of the IP protocol
which goes by the name of IPv6. It has been around for
ages, but sadly, adoption has been rather slow so far.
the IoT itself
Harness the power

f.

We name-checked Bluetooth LE earlier. The


Bluetooth LE works on a relatively simple software
model based on characteristics. A characteristic is an
attribute of a device: it could be the colour of an LED or
The biggest barrier to a widespread adoption of IPv6 is technology called Bluetooth Smart when trading in the amount of energy left in the battery. Further
that IPv4 hosts cannot contact their more the consumer space shares the name and the information on each characteristic can be contained in
technologically advanced brethren directly. frequency hopping with its famous ancestor. Other the descriptors, both of which can be wrapped up in
In the case of the Internet of Things, this should not than that, it can be described as complete redesign of services. The GATT profile acts as transport layer
be too much of a problem. If all sensors and their the original shortwave wireless service. around these concepts: you use it to read and write
controllers are based on IPv6, there are no legacy Bluetooth LE fixes many previous problems. The characteristics and descriptors. Implementing
systems which need to be supported in the first place. discovery section, which once took more than ten Bluetooth LE by hand is a painful and futile task: a
As of writing, most providers are able to handle IPv6 seconds can now be accomplished in less than a variety of companies provide ready-made modules
trafic. In practice, developers rarely need to worry second. The availability of the GATT profile ensures which can be attached to a process computer of choice
about this keep it in the back of your head though in that developers and device manufactures dont need via SPI or L2C. LE is far superior to proprietary
case something goes really, really wrong or some to bother themselves with creating, specifying and protocols like the ones used in the once-popular LPRS
pesky VC asks you about it. certifying Bluetooth profiles. easyRadio family. Due to the widespread adoption of

20
// Web of things

WoT community
W3.ORG/COMMUNITY/WOT
If the oficial Web of Things Interest the WoT Community Group might be
Group is too expensive, the WOT an interesting way to start connecting
community might be an alternative. It yourself to the W3C. Linking up is as
was first organised in 2013, and was easy as visiting their website (w3.org/
responsible for the highly successful community). Fill out the form, and you
workshop in Berlin which spawned its are all set to go if there still is
aforementioned larger brother. anything taking place, that is.
Sadly, its activities have since started You can also look for local events. In
to slow down no updates have been most big cities, one or more Internet of
posted since June 2014. Nevertheless, Things meetups take place joining
joining the remaining 160 members of one is a cheap way to find out more.

WoT Interest Group


W3.ORG/WOT/IG
After the success of the Web of Things input to these standard drafts. It can
Workshop held in Berlin in 2014, the also serve as a first-class opportunity
W3C started a Web of Things Interest for networking as the current chairs are
Group. The group will be responsible from Siemens and Intel and it wouldnt
for defining standards: the topics hurt to have these contacts.
discussed will range from simple things Sadly joining the Web of Things
such as scripting language subtypes Interest Group is not cheap for an
to more complex issues such as amateur developer. To join the W3C
data encoding, metadata formats you will need to pay the minimum
and the protocols used for annual fee of 1,950 (1,395) for two
communication. Being a years. After that, the fees will quadruple
member of this group and will stay in the range of about
permits the providing of 8,000 (5,725) a year.

Bluetooth LE and the highly cooperative way Special voltage, which must then be digitised. Due to the on collected information usually requires quite a bit of
Interest Group handles licensing, this technology is a nonlinear characteristic of most transducers, a power: the GPIO ports of the average MCU are not
winner it could even thrive without the IoT itself. complex linearisation is required in order to yield strong enough to provide the kind of current needed
useful values. This problem can be bypassed by using to move motors, switch relays or do other funny things.
Sensors... smart transducers. They communicate with your Well, the transistor comes to the rescue here: this
By and large, single-board computers are a relatively single-board computer via a defined protocol: some component can amplify small currents, thereby
stupid bunch. They can read digital signals, a much simply provide parallel data, while others can be increasing the current drive capability. Connecting
slower A/D converter samples analogue voltages with addressed via SPI or I2C. Using these components via a transistor is not always the
moderate accuracy. When performing measurements industry-standard bus protocols simplifies ideal solution though because when you
of real-world dimensions, the first step usually involves sensor integration: in the case of an are switching mains or even higher
analysing the type of the quantity to be measured. If Arduino, accessing the peripherals is voltages, galvanic separation is
you are dealing with a voltage, the situation is easy as easy as invoking the correct Diana Kupfer often desired and this can be
you need to check if the A/D converter can sample it library functions. The datasheets @dianakupfer achieved via the use of a relay.
directly or if amplification or dampening is needed. of smart transducers tend to Veteran media manager Relays are an electromechanic
If the dimension at hand is not of an electronic type, contain one or more sample who recently was assigned component which combines a
a transducer is needed. Theses can be grouped up into circuits, which explain how to to manage a large IoT focus coil and a magnetically driven
two groups: dumb and smart ones. The classic condition the incoming signal for group. Retweets loads of switch. Chasing a current through
example of a dumb transducer is an LDR or an NTC: maximum accuracy.
valuable messages. the coil creates a magnetic field,
they are resistors, which change their value in thereby moving the switch to the
relationship to the measured dimension. Using them ...and actors closed position. This will load currrent
requires the amplification or dampening of the Reading values is but part of the solution. Acting flows over the switch, which is not connected

21
:HE'HVLJ
The:HE'HVLJAnnual

Enriching
lives
EXPERT INSIGHT

technology enriches and simplifies our lives, but we need of IoT applications. How quickly and how efective do
to take too many manual actions to benefit from this. you think they will be?
Brad Fry When everything is connected things will just work, no Weve been through similar standards wars in the past:
Director of Strategy & Insights at Folk buttons to tap or things to log. with browsers, video codecs and even network protocols
bradfry.com Moving to the macro scale, the volume of the data (anyone remember Novell? I actually liked IPX). They have
collected by billions of connected devices can help all eventually converged into a standard (although
By the end of 2015 it is predicted that there will be 4.9 profoundly. It will help improve weather models, redesign Bluetooth still has a way to go).
billion connected things in use. By 2020 it estimated to trafic systems and accurately diagnose illness earlier. Modern web standards now rely on compatible
reach 25 billion. Where do you think the IoTs greatest endpoints dumb pipes and smart hubs so the lack of
potential lies? The Web of Things is an attempt to use existing and standardisation may be less of an issue. Apple has made
At the micro level the greatest potential for us as end well-known web standards rather than specific a big play towards acting as a intermediary in connected
users is in convenience. There are so many ways our manufacturer standards to help simplify the creation devices (HealthKit and HomeKit). As long as we have
compatible endpoints, we can probably relax about the

As long as we have compatible endpoints, transport protocols uses by the devices themselves.

we can probably relax about the transport With more and more connected devices joining the IoT
party, what will designers and developers need to
protocols uses by the devices themselves

electrically, to the relays coil. Sadly, relays can grace



Motors come in incredible variety of types: entire
consider when creating UIs for applications?

detail would exhaust more space. The asynchronous


multiple issues. First of all, the coil can create magnetic books have been written, cataloguing each of the one is especially critical as it has still not been
fields, which might not be entirely acceptable in some subtypes. When dealing with the IoT, you usually have modelled fully: when working on an application with an
circumstances. Secondarily, the actual switching to use one of three diferent types. Stepper motors can asynchronous engine, you should not be ashamed to
process can cause sparks which can ignite be considered fine motor skills wizards: they are seek help from professionals.
combustible atmospheres. Finally, the coil needs quite extraordinarily accurate and move by a fixed amount
a bit of current use a transistor to amplify, and dont of degrees when provided with an impulse. When The power bank
forget the kickback protection diode. combined with external gear shift, amazing levels of Power supply remains the Achilles heel of the Internet
Relays are limited to switching on and of. accuracy can be achieved. of Things: when a sensor runs out of energy, it cannot
In many cases, a more granular level of DC motors are on the other side of the transmit any further data. Users have shown
control is required. This can be equation. Their rotation speed themselves to be extraordinarily hesitant to changing
achived via D/A converters: hey depends on the load and the the battery of their gadgetry frequently. If you want to
take a digital value and convert it Martin Woolley voltage: the only way to ensure a keep your clients happy, try to aim for battery lifetimes
into a variable voltage or a @bluetooth_mdw reliable RPM involves measuring that range from six month to almost infinity.
variable current. Extraordinarily active it continuously and adjusting This obviously disqualifies some battery types
developer advocate drive voltage accordingly. NiCD and NiMH types sufer from a relatively fast rate
Run an engine working for the Bluetooth Exerting very large forces of self-discharge. This means that the internal
SIG. A must-follow due to
A common real-world task is motor requires the use of AC motors. resistance of the battery slowly destroys the energy
his diverse range of topics.
driving: be it a big, beefy cable They come in the forms of the stored inside: if the cell sits on a shelf for a few months,
winch lifting a crate of arms, or a tiny synchronous and the asynchronous it might end up empty. Modern MCUs provide
motor moving a print head across a rail. motors sadly, discussing them in further low-power standby modes: When no data is to be

22
// Web of things

Design has been moving from complex to simple for the


last decade and that will continue. Were going from the
traditional engineering-led approach of making
something that does everything to the user-centric things
that do a few jobs brilliantly.
The challenge for developers is to make smarter AI to
figure out what I want before I know it myself, like Google
Now. All the big strides being made in technology today
are in this area just look at Timeful (recently purchased by
Google), a calendar application with artificial intelligence,
or Transit (just imagine what they can do with all this
Internet of Things data).
For my life with connected devices, voice is the
interface of choice. As if being able to turn my heating on
from bed wasnt lazy enough, Im looking forward to the
day I can declare Hey Siri, turn the heating on just
need to wait on HomeKit!

The future
THE COMMON PROTOCOL TRENDS
Ever-rising marketing costs ensure that devices will
get smarter over time: selling customers a service,
rather than a gadget, increases loyalty and provides a
continuous revenue stream.
LG sold a combination of smart TV and mobile
phones in the hope that if clients have a TV set which
works only with LG phones, they are likely to opt for
the handset too. As LG is a giant in the whiteware
business, we can assume this trend will continue. The
IoT will standardise itself: be it by the manufacturers
establishing a common protocol, or by a third party
selling a cross-platform framework.

collected, hibernation occurs. Sadly, this is but part of


the solution. In practice a field of technologies, which
goes by the name of energy harvesting, promises
some solutions for this very problem.
Energy harvesting can take more classic or more
modern forms. The most traditional form, by far, is a
solar cell: it can collect a small amount of energy from
artificial light, and can collect much more power once
provided with sunlight. This however, is but a small
part of the available options: Peltier elements can be
used to generate energy from diferences in ambient
temperature, while more exotic systems use bloodflow
or high-frequency radiation emissions to collect small
amounts of energy. These will then let the attach
system eke out its lifespan.
Designing energy harvest in circuits requires a high
level of knowledge in electronics. Fortunately various
manufactures provide ready-made intergraded
circuits, which require you to link them with an energy
source and a temporary storage medium: The rest of
the work is complied inside of the intergraded circuit.

23
60

44
112

24
26

&R G L Q
26: HTML & CSS patterns

34: Customise maps with the


Google Places API

40: Create virtual


reality panoramas

44: Build iOS-style web


applications with
Framework7

48: Deploy your web


apps to Heroku

54: Develop a web app


quickly with Lucee

60: Atom
66: Create desktop applications
with Electron
70: Use NW.JS to develop
desktop applications
76: Robust Javascript code
82: Make a playlist with Last.FM
88: Complete guide to GIT

94: 20 Best GIThub Projects

100: Build a friendly bot to


enhance your Slack group

106: Create API schemas


with Swagger
112: Future HTML
:HE'HVLJ
The:HE'HVLJAnnual

C O D E
T O M
I L D S W I T H C U S

C S S
FAS
M
T
LE R

S
BU
&
T
H TER N E

T
H
ET
R OV

A
M P
N DI
S AS

P
N
T ERJECT
PAT RO
I G N RP
E S YOU
O F D OF
E R IT Y
OW UAL
P Q
T HE
S
N ES
R
HA
// HTML & CSS PATTERNS

DESIGN PATTERNS DO DESIGN PATTERNS DONT


s Help to standardise your code s Consist of a suite of code snippets
When writing code to a defined pattern it is easier to maintain consistency, even across Code snippets provide reusable functionality that is already tested and proven within
a large-scale project. This consistency is vital as it enables you to be confident about other projects, stopping us from writing the same or similar solutions time and again.
the quality and stability of your solution. Well-structured code is much easier to test, Design patterns provide us with a structure to work within, a set of rules if you like, that
debug and fix, for example a pattern that separates data, logic and presentation ena- help to make consistent decisions when writing code. Code snippets themselves can
bles each area to be tested independently. This means that any issues within a code fit within a range of patterns and when considering larger reuseable sections of code,
solution can be identified and eradicated with very little debugging efort. As you gain you should bear in mind how these fit with any patterns you may be working with.
experience in working with standardised approaches and patterns, you will also find Dont expect a design pattern to provide you with answers, it will instead give you the
that estimating projects becomes more accurate. means to find the answers more eficiently.

s Provide consistent UI behaviours s Negate the need for user testing


When considering the user experience of a digital interface you will be thinking of When thinking about UI patterns, we are generally making sure that any journeys
patterns without even realising it. Every user holds a certain level of expectation for or interactions are considered and based on proven approaches we know users
the behaviours or steps through a user journey. These expectations are understand and expect. Therefore, it is easy to assume that our platform is
generally based on repetition and in turn help us to establish standards fine for users without any form of user testing. This is a risky assumption
over time. There is not one UI pattern that suits all cases, but by ensuring Diverse to make, users across diferent demographics, industries and even in
that a platform does not switch between patterns, your users will not patterns difering environments can and will expect difering behaviours. Even
get confused. This is really important to design and build digital Due to the range of design if you are building a solution for users you have built for previously,
products that not only work but work well for users. patterns, there isnt one master it is important to remember that these user experience standards
pattern that can be defined or have evolved over time and will continue to do so.
s Enable reuse and maintainability found. This a good thing, because
It is very easy to solely concentrate on the exact requirements and if this wasnt the case, coding s Provide one approach for all projects
agreed functionality you have defined with a client. In doing so you could get quite boring The use of design patterns span from providing an overarching
can be certain that you will design and build something that your client very quickly. structure to an application to more granular patterns for small decoupled
is very happy with, making the project a success. However, what happens pieces of functionality. Most projects encompass a range of design pat-
when your client changes their mind or you are requested to extend or adapt terns, separated by UI and functional, and one pattern may contain other
some functionality as part of a subsequent project? This can incur a lot of refactoring smaller patterns. For example AngularJS is based on an MVC application pattern which
or code rewrites, but by coding with patterns you can cater for future extensibility and separates your Model, View and Controller, however your controller can contain more
build something you are happy with. granular JavaScript patterns such as Constructor or Modular.

WHAT CAN PATTERNS DO FOR YOU?


You may think that design patterns dont apply to me or and noticed some core underlying diferences when
my work, they are only relevant to people who work on comparing it to how we write code today.
large-scale projects or sizable development teams. If we consider design patterns when we write our
However it is very rare, even if you actually are working code, the problems of technical debt in our code will not
alone, that you only work with your own code, and thats cost us nearly as much time when we come back to it
because design patterns are in use with pretty much one or two years later down the line. These problems
every piece of open source code that we will find can be largely eradicated by understanding the design
ourselves using. If these technologies and frameworks patterns and approaches that were used, making it much
had not been produced with core underlying design easier for us to get back into developing within an old
patterns then they would be extremely dificult to work code solution.
with, understand and maintain. In short a plugin or If you do tend to work with other developers, design
framework with no design pattern will not have much patterns can be a useful means to communicate how an
longevity within the community. application has been built or even how it is planned to be
Even if you are building in isolation, with no use of built. This can really save some time in getting multiple
other open source code, it is likely you will need to come people up to speed on working within the same project,
back to your code at some point in the future. We have yet still maintain consistency and ensure stability within
all experienced code that was written some time ago the final product.

Design patterns can be a useful means to


communicate how an application has been
built or even how it is planned to be built

Madebymany.github.io/css-patterns is just
one pattern library available on GitHub

27
:HE'HVLJ
The:HE'HVLJAnnual

Design patterns
have been around for
a long time. Realising
how we have already
been using them and
then taking
advantage of the
consistency they can
provide is essential in
building modern web
applications.
Luke Guppy
Frontend director

THE DIFFERENT
PATTERN TYPES
THE BENEFITS OF UI PATTERNS
The main benefit to using design patterns when building or are in odd groups, and not all at once. The things you
UI patterns user interfaces is that they ensure you take advantage of will need to consider are: positioning of error messages,
These are common design solutions to function- tried and tested solutions to common design problems. alongside the relevant field is the most common user
al interfaces. They are predominantly defined More often than not there will be a range of established expectation; timing of messages so dont validate fields
by understanding our users and their interface approaches to choose from and in making this decision before the user has finished editing them and decide
expectations and interpretations. We provide the make sure you assume nothing about your users. Only whether it is best to validate one at a time, whether in
most eficient way for a user to complete a task with a good understanding of your users goals and ex- groups or altogether; and dont wait for the user to submit
or provide multiple ways to get the same result. pectations can you be sure of building the best solution. the form before revalidating any changes make sure the
UI patterns define more than just interactive elements. messages are clear and concise.
Persuasive patterns Arguably the most important aspect is clear visual com-
These leverage content to persuade the user to munication to users this is achieved through common, s Searching and filtering
take a specific journey or make the decision we recognisable iconography. A good simple example is the When you have a lot of information for a user to view,
want. This could be achieved by reinforcing a humble external link icon, using this sets the expectation consider whether they need to get to something specific
products quality using social proof or creating that you will be leaving the site, therefore avoiding the as quickly as possible, or if they need to explore and
empathy for a cause. Theyre particularly power- issue of confusing the user when they only find this out curate the data. If the former then the user will expect to
ful in eCommerce as they bring emotion into a after using the link. Confusion makes users feel uncom- be given all the tools to run an extensive search straight
users decision-making process. fortable, and when uncomfortable they will tend to exit away. Otherwise it can be daunting for a user if you ask
the user journey you have set out for them. them too many questions at the start of an exploratory
JavaScript patterns journey. In this case you will find that simpler search tools
Within front-end development, JavaScript Common UI problems followed by additional filter options alongside will prove
provides complex functionality, and this means There are so many UI problems we solve all the time. more successful.
that the benefits to be found with using design Reusing these approaches is probably the simplest form
patterns are far more obvious. JavaScript pat- of design pattern, as we all do this as part of the design- Responsive patterns
tens help to break down your scripts into smaller and-build process as standard. Adjusting layouts across screen sizes and providing clear
more manageable pieces. interactions for both mouse and touch inputs make
s Form validation responsive patterns essential. The two main aspects of
Application patterns We have all experienced error messages on forms that responsive builds that benefit from well-defined patterns
Application builds that run predominantly within either seem to be displayed too late, in the wrong location are layouts and navigation.
the browser are now prevalent across the web.

Confusion makes users feel uncomfortable,


They enable almost instant feedback and to
achieve this, a number of MV* patterns have
been adopted by app frameworks. These provide
much-needed separation of concerns.
and when uncomfortable they will tend to exit

28
the user journey you have set out for them

// HTML & CSS PATTERNS

WHAT ARE PERSUASIVE DESIGN PATTERNS? READ ON


Persuasive design has been used successfully Pride Empathy
within advertising and marketing for years. Loss What you have to do to appeal to a users sense of Using content which gradually builds up
aversion is probably the most common form and pride is simply reinforce a decision that has been empathy can be a useful pattern when the key
this is based on the premise that people prefer to made, and you can do this reinforcing through your objective is to gain donations from users. To
avoid losing something than gaining something, social media content. You can also make use of succeed in using empathy, it is vital to establish
for example just look at sales or deals that have a imagery to position a product or service within an this emotion prior to asking for any commitment
limited time period. aspirational setting. from the user.

s Layout patterns more complex interactions, it takes time for users to altogether and leave future development as mainly guess
Two good examples of layout patterns, and probably become accustomed to them. work. If you are precious about maintaining clean HTML
the most common, are fluid to stack and column drop. within your projects but want to use modular CSS you
There are a huge amount of patterns in use and in most The modular approach can separate your modular CSS files from your HTML
projects a range of patterns will be needed to support the Any responsive pattern you adopt will be created with structure-based declarations and bring them together
range of information required by the platform. HTML and CSS, but have you ever thought about how with a CSS precompiler. It would be advisable to refrain
The fluid to stack pattern relies on a fluid grid which you approach writing it? The fully modular CSS pattern from overruling modular classes start with your modu-
scales down with the screen and requires the content of removes the reliance on a specific HTML structure to lar CSS and when it needs adjusting move it to your main
each column to scale down with it. A breakpoint is then achieve your responsive interface. Instead of targeting CSS files. This gives you confidence that any modular
defined to stack all columns when appropriate. HTML elements, or relationships between them, it relies declarations will have the build efect you expect.
The column drop requires less reduction in scale of on an extensive range of CSS classes which can be
column contents but uses more breakpoints: one to stack applied to any element. Each class must have a specific
each column (from the right) below the other columns
when the width is limited.
purpose and usually only consists of a few properties.
These classes can be grouped to achieve the desired
EVOLUTION
s Navigation patterns
layouts across screen sizes. This approach requires a lot
of planning and consideration upfront. It can be dificult
OF USER
Providing clear functionality on smaller screens is a prob-
lem solveable by navigation patterns. Any
to define all the required CSS declarations, and it is tempt- EXPECTATION
ing to breach the pattern for a quick solution.
solution will be partly dependent on the But, your CSS can become very confusing. There are standard approaches that we all find
amount and size of the navigation links. Stick to This approach is relied upon by respon- ourselves building time and again, these are
The most common solution is a tog- your guns sive frameworks, such as Bootstrap tried and tested UI solutions that users are famil-
gle menu, when the navigation links Once you have decided on the theyve done the hard work for you iar with. It is vital to ensure that with any interac-
no longer fit across the screen, design patterns that you have set and have established a definitive, tions or journeys, the user can understand the
they are replaced with a menu the boundaries and rules for, well-defined range of modular functionality and process with very little efort.
which, when clicked, slides down the try to avoid any temptation to classes for building responsive sites. This ensures that users are comfortable and feel
links from the top of the screen. From deviate from these design in control, nobody likes to feel they dont know
a visual aspect it is also common to use patterns for any short Maintaining your HTML how to do something.
the burger icon to represent a menu link. term gains. A modular CSS pattern does come with These approaches, although tried and tested,
Another solution which was adopted and its own drawbacks. To support a full website do not last forever. Advances in technology can
popularised by the Facebook app, is a slide-left menu. build the CSS will be extensive, and in assigning separate change how we think about interactions. Take
This behaves in a similar fashion but slides the page to classes for a desired feature they will litter your markup. the transition from the humble desktop mouse
the right and menu in from the left. This approach often If you take a fully modular approach, avoid adjusting to touchscreens as an example, users used to
incorporates swipe gestures to hide and show the menu. the efect of classes based on their position within your expect hover states and click events, now they
When it comes to multilevel navigation solutions there HTML. If you do start to overrule properties in this way, expect the ability to swipe, pinch and rotate
are still a wide range of approaches in use, as with many you can quickly lose the benefits of the modular system and all this with an indication force and velocity
expected too.
It is not only technology that changes users
s Fluid to stack s Column drop expectations of an interface, on mobile devices
Uses a fluid grid with the content Uses more breakpoints to stack trends are set by the implementation of both
scaling down on smaller screens columns below other columns iOS and Android interfaces. Many solutions and
visual cues accepted across the internet today
as standard were first seen with these mobile
operating systems.
Facebook is another key player in the evolu-
tion of user interaction, any software application
that covers such a broad range of users has the
inherent influence to change the way we build.

29
:HE'HVLJ
The:HE'HVLJAnnual

TAKE CONTROL WITH FRONT-END PATTERNS


Technical solutions this.firstname = firstname; Structural patterns cript application frameworks including
with JavaScript this.lastname = lastname; The JavaScript patterns so far have been Angular, Knockout, Ember and Backbone.
It is very easy to get lost in your code this.age = age; creational, structural patterns deal with They separate the concerns of diferent
and end up with an unrecognisable mess this.fullname = firstname + " " + the composition of objects and how sections of an application, making these
of functions, objects and variables that lastname; these compositions relate to each other. distinct sections independently testable,
you know work, but youre not quite sure } Structural patterns ensure that objects interchangeable and reuseable. There are
how. Design patterns can stop this from var bob = new can be related and when one is changed three diferent MV* patterns, MVC, MVVM
happening as they are proven solutions Person("Bob","Robson","27"); this change is realised across the platform. and MVP, all three separate presentation
to common technical problems that give console.log(bob.fullname); // Bob This enables us to manage object-based (our HTML), data (the information held
you some clear rules to adhere to when Robson code in small chunks and be confident within our application) and logic (our
youre developing. that extending or adapting one composi- functional code). This gives us great
If you work with JavaScript libraries and The prototype pattern tion will not unexpectedly impact the rest flexibility on how we can build and also
frameworks you will already know many JavaScript is a prototype-based language, of our application. lets us create much larger scale software
of these patterns, possibly without even this means that every object is based solutions in JavaScript with ease.
realising it. on an original prototype. As seen in the Behavioural From a UI perspective these
last example the Person function is the patterns patterns, and in turn any
The constructor pattern original object and bob is based on this. If These patterns are frameworks that use them,
This is a very simple pattern but is the original object, or any created from it, concerned with the com- Start off have given us two-way
essential when building a large piece is extended using the prototype method, munication between simple binding of data within
of software, as it gives control over an the same extension will be applied to any objects across our If you are new to working with our interfaces. This
objects structure and the creation of new objects based on this original prototype. platform. When we design patterns then the list of gives users instant
instances of those objects. This ensures If you have used a polyfill to provide new want one object approaches can be daunting. Start responses to their
that you can be confident of what to methods to object types such as arrays, to afect another of simple and use patterns for actions and has
expect from a given object when using it then these polyfills are leveraging this pat- in a defined manner, real coding problems before therefore really influ-
across your application. The constructor tern to extend all array objects. Without these patterns come into moving on to the enced web applications
is a function that receives a defined list the prototype pattern we wouldnt be able their own. A good example next one. of today.
of arguments and extends itself with to use new JavaScript techniques until the would be the Observer pat-
properties and/or methods based on browsers implemented their own solution. tern, this consists of an object to hold and JavaScript syntax
those arguments. In JavaScript calling a Person.prototype.getInitials = maintain a list of other objects as an array. All JavaScript patterns to this point have
function with the new prefix creates an function(){return this.firstname. This array can then be given functionality been concerned with what our code is
isolated instance of that object, based on split("")[0] + this.lastname. to compare, change and notify specific actually doing and how it is doing it. Pat-
the defined structure. split("")[0]}; listed subjects or even all of them. This terns within your code syntax are equally
function Person(firstname, bob.getInitials(); pattern can be useful when building listed beneficial for large-scale projects, these
lastname, age){ // BR data items that can afect one other, for would constitute a set of rules outlining
example a league table or leaderboard. anything from capitalisation of names-

Without the prototype pattern paces to where and when variables,


Application patterns public or private, are declared. By defining
we wouldnt be able to use new These are very popular in web develop-
ment today, also known as MV* patterns
clear guidance on your syntax structure,
other developers will find it much quicker
JavaScript techniques
FIVE TWITTER ACCOUNTS TO FOLLOW
as they provide us with a host of JavaS- to familiarise themselves with any code.

Addy Osmani Brad Frost JavaScript Live John Resig Henrik Joreteg
@addyosmani @brad_frost @JavaScriptDaily @jeresig @HenrikJoreteg
An engineer at Google, An extremely experienced This is a great Twitter account One of the creators of jQuery The president of &yet, con-
creator of Yeoman and and well-respected web de- for keeping up to date with and an expert in all things fere JavaScript developer
leading voice in all things sign/developer and consult- the latest community news, JavaScript (including being and creator of Ampersand-
JavaScript, open web tool- ant with some great insights events in the industry as well the author of Pro JavaScript JS. Henrik has some great
ing and web application. into UI designs and patterns. as approaches, techniques Techniques), John is an es- ideas about how applica-
Addy is currently working Brad has worked on some ex- and framework. Make sure sential expert to follow. He has tions can be built to truly
on Polymer and is also the cellent web tools and various you sign up to their email been working with and shar- benefit people in general.
author of the excellent book resources such as Pattern newsletter so you never have ing his thoughts on design He also provides updates for
JavaScript Design Patterns. Lab (patternlab.io). to miss a thing! patterns for years. his latest shipping releases.

30
// HTML & CSS PATTERNS

6 PATTERN FRAMEWORKS YOU NEED TO KNOW

Bootstrap / getbootstrap.com Semantic UI / semantic-ui.com


A wealth of tried and tested UI components based on a modular CSS pattern. This responsive UI framework uses semantic, easy-to-interpret language.

Kendo UI / telerik.com/kendo-ui Angular JS / angularjs.org


Benefit from a wide gamut of UI and app patterns with this extensive toolset. Arguably the MVC application framework of choice in web development today.

Ampersand JS / ampersandjs.com Knockout JS / knockoutjs.com


A fully modular JavaScript development approach, uses exactly what you need. An MVVM data-binding framework, separate your data from your presentation.

31
:HE'HVLJ
The:HE'HVLJAnnual

DEFINE YOUR OWN REMEMBER TO


KEEP THINGS
CREATIVE
DESIGN PATTERNS
Where to start that may have come close to solving it. This helps others
It is possible to take the use of design patterns
too far, you can become too reliant on them and
find yourself producing the same solutions over
and over again. Technology and people change,
Start with the problem, a design pattern should be to make a faster decision, if you have already gone therefore both what impossible and what is
created for no good reason. You must have a problem through a review of other possible solutions why not expected changes. This means that a proven
that doesnt already have an established solution. To share that information? solution may become old-fashioned and if you
ascertain if there are already solutions out there, you Now clearly define the rules or scope of the pattern, have become heavily reliant on it you could
need to review other patterns that may suffice. This be sure to include what your pattern isnt for as well as quickly fall behind.
could even mean trying some code out before making a what it is. These rules can be a simple bulleted list of dos Good eficient production is essential within a
decision. A new pattern without a distinctly different and donts. Then provide a good, but simple example of web development project, but writing code is a
purpose will just crowd the landscape and make it more your pattern's usage, with more complex patterns you creative discipline. Remember there will always
difficult for others to make informed decisions for any of may need more than one example. If your pattern be more than one way to solve any UI or techni-
their problems. encompasses a range of smaller ones, it may be worth cal problem. We all need to keep our minds open
Once you have concluded that there are not any documenting it in that way. to diferent approaches, techniques and new
sufficient patterns that solve your problem, break the design patterns it is our collective responsibil-
problem down into as small a piece as possible. Then Collaborate ity as developers to shape the digital landscape
you can consider if and how these small separate Once you have created a pattern and are happy with its we are all part of.
concerns may need to relate or communicate structure, purpose and usage release it into One of the best ways to do this is through
with each other. A good way of visualising the wild. This can be achieved by selecting collaboration, this can be discussing approaches
this is by simply sketching out this Taking a small group of colleagues or peers and and techniques with colleagues, or taking the
structure. Each part of your pattern critique asking them to review and question time to read blogs, review new ideas and follow
should be able to be independently This process may be dificult, as your solution and decisions. key players on Twitter.
tested and as you have broken it isnt easy to see your own No pattern or framework that Even if you see a very small failing in a pattern,
your problem down you may find creations come under such has fully established itself in or have just the beginnings of a new idea, by
some smaller, existing design scrutiny, but by doing so you will todays landscape came about by enlisting the help of others we will be able to get
patterns solve some of your smaller be confident in the reliance one person alone. You cannot afford to the best solutions quickly and move on to the
problems. Again ensure that you reuse and suitability of the final to be too precious about it, but do next big problem.
approaches if possible. end product. remember that if any decisions come If we repeat too many aspects of our builds
down to opinion, the final say is yours it will tend to stifle our own creativity and we
Communicate because you own it. You will find that over would risk the web becoming a very
Dont leave your design pattern in your head, it is no use time and with good quality feedback, your pattern will monotonous place.
to anyone left in there. When you go through the gradually develop into something transferable to other
process of trying to find a suitable design pattern or projects and developers, which is the core purpose for it
patterns, you will begin to appreciate how important anyway. Collective wisdom is so much more powerful
good communication of a pattern is. Firstly outline the than that of the individual, collaborate with your peers
problem you are solving, then list any existing patterns and challenge others to really interrogate your pattern.

Clearly define the rules or scope of the


pattern, be sure to include what your pattern
isnt for as well as what it is

RESOURCES

UX Pin tuts+ JavaScript Jabber
uxpin.com code.tutsplus.com devchat.tv/js-jabber
A great resource of UX insight and a host of free An expansive repository of training material includ- A weekly podcast covering all things JavaScript. A
eBooks including Web UI Design Patterns. ing an introduction to JavaScript design patterns. good source of what is new in JS development.

32
// HTML & CSS PATTERNS

EXPERT ADVICE: 9 TIPS AND


TOOLS FROM THE PROS
Tabs to accordions Accessibility
1 Content thats displayed in a group of
tabs in your desktop layout can be
easily switched to use an accordion when
4 This is an aspect of web development
which is easy to overlook. With any UI
pattern be sure to consider the
the viewport becomes narrower. This way semantics of your markup and the context
the content stays nicely structured and it remains given. Testing your platform with screen readers is useful
useable as well. because you can validate how accessible the platform is.

Column dropping Usability


2 You may have a grid with a certain
number of elements on each row. Use
media queries to reduce the number of
5 Usability is at the heart of any user
interface pattern, but remember that
this will evolve over time as users and
elements on each row as the users technologies change. Also bear in mind
viewport becomes narrower, and allow the content inside how useable an interface is when you are developing
each block to remain consistent. applications that may have lots of data to represent.

Shifting labels Security


3 Labels are often sat next to their
respective inputs when the viewport is
wide enough. When you lose space, sit
6 When working with behavioural design
patterns you will predominantly be
concerned with the communication
them directly above their inputs. The between parts of your application. Any
relationship between field and label is maintained and communication of data must always be properly secured
precious screen space is saved. ensuring the safety of users data within your platform.

7 Photoshop CC 8 Jasmine 9 InVision


adobe.ly/1OMTGU5 jasmine.github.io invisionapp.com
With the introduction of This is a behaviour-driven This is an online, interactive
artboards to Photoshop CC 2015, it testing framework for your web prototyping tool, which
is now simpler to represent JavaScript builds. It does not enables you to quickly visualise
multiple layouts, states and require a DOM or other JavaScript possible UI patterns and
behaviours within one single PSD frameworks. When combining collaborate with others in finalising
file. This function is most effective JavaScript patterns and building solutions. You can even collaborate
when you need to communicate a large-scale applications, a good in real-time, get direct comments
Ash Robbins responsive pattern with colleagues testing tool is vital to maintain and and feedback, and sync your files
Lead frontend developer at Redweb and clients. ensure the stability of your code. with version histories available.

JavaScript Design Patterns CSS Secrets User Testing


oreil.ly/1zeoTpz oreil.ly/1IJz4M9 usertesting.com
A comprehensive read covering a huge range of A book by Lea Verou, really useful for getting to grips An online system for getting your new design pat-
JavaScript design patterns, their uses and flaws. with modern CSS techniques. terns user tested and getting real world feedback.

33
The:HE'HVLJAnnual

Customise maps
with the Google
Places API
Use Street View and Google Maps to create a more immersive map
experience that takes up less bandwidth

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Customise maps with the Google Places API

2. Write markup and link scripts

G
oogle Maps celebrated its tenth birthday Well use the Places API in a few ways that aim to give
in 2015. Ten years of sustained efort has you a solid understanding of how to use it and ideas to After creating the in within our index.html file well add a
resulted in the de facto map application enhance your sites. First, were going to build a simple few divisions which will hold the Google Map, the Street
both on the web and on mobile devices. text box that will allow users to see nearby places without View and an information area. To include the Places API
Part of its success is due to the ability for people to a map. Then well build a split map and Street View from Google Maps a query parameter of libraries is
embed maps within their own sites. This quickly made its interface which will update as the user pans and provide added. Were using version 3.21, a changelog can be
interface familiar and is now ubiquitous on contact pages information on the markers they click on. found at bit.ly/1IYCvPD.
the web over. The Google Maps JavaScript library ofers
more functionality than simply a map and a marker. 1. Create index.html
The Places API can be used for four requests: nearby, Start by writing some HTML linking normalize.css and
text, radar and place details. Well be covering all but our own stylesheet. The custom CSS floats both Change the maps look
radar, which is used to return a large list of places within a .map-areas and sets them to 50 per cent of the available If your website has a specific visual style then
radius but without much detail. Nearby is similar as it width. To prevent images within Google Map windows you can use custom overlays and icons to
visually integrate your unique style by going to
takes a radius and specific types of places but provides from being too wide we set a max-width on them by
bit.ly/1IN8B2m.
more detail. A text search is useful for organic searching. targeting .gm-style-iw img.

Left
Depending on the libraries you specify, Google Maps
dynamically includes what you need. Were using the
experimental version

Top left
Once the Places API has returned nearby web places we
display them in this dropdown
Top right
When the user selects a place we get its details using the
Places details service which we then show here

35
:HE'HVLJ
The:HE'HVLJAnnual

3. Attribute to Google google.maps.event.addDomListener(window, geolocation then itll request access to it and provide
When using the Places API without a map you need to 'load', initialise); their coordinates.
attribute it to Google. A ZIP file is provided from })(google); var center = new google.maps.LatLng(51.5072,
developers.google.com/places/webservice/policies 0.1275); // London
with a range of images for diferent resolutions and 5. Start the Places service if ('geolocation' in navigator) {
contrasts. You should also reference Googles Privacy SetMap wont be called straightaway, well call it once we navigator.geolocation.
Policy and Terms of Use in a footer. know if we have the users location or not. Were not getCurrentPosition(function (position) {
<img src="images/powered-by-google-on-white. displaying a map but a virtual element is still needed to center = new google.maps.LatLng(position.
png" alt="Powered by Google."> pass to the Places service. This element only exists in coords.latitude, position.coords.longitude);
memory so access is much faster than one in the DOM. setMap(center);
4. Setup and initialisation function setMap (center) { });
Create a file called places-dropdown.js, this is where well var div = document.createElement('div'); } else {
write the module which will list nearby places in a select var map = new google.maps.Map(div); setMap(center);
box. JQuery isnt included in this project but Google Places = new google.maps.places. }
Maps provides a convenient abstraction for adding event PlacesService(map);
listeners. Its simple to use but more verbose than getTextPlaces(center, 'web'); 7. Perform a text search
jQuerys version. } One of the searches that Places lets you perform is a
(function (google) { simple text search. Were passing web so itll look for all
'use strict'; 6. Create the form tag places that have tagged themselves as web. The radius
var Places; Still within the initialise function, we need to work out is in metres so in this case, one kilometre. The textSearch
function initialise () { where the centre of the map should be. By default weve service requires a callback which receives the data.
/* next step */ set it to the latitude and longitude coordinates for function getTextPlaces (location, query) {
} London. If the users browser has a browser with var request = {

Top left
The site asks for the users location (if its available) and
centres the map on them

Top right
Once the map tiles have loaded, the idle event triggers the
service to make a request and drop the markers
Right
Clicking a marker opens an information window with some
details about that place; you can put any HTML inside

36
// Customise maps with the Google Places API

The great-circle
formula in JS
The zoomToRadius
function is pretty
interesting but also very
math based. It uses a
formula called the
great-circle distance.
Its not quite 100 per
cent accurate though
but it gives us
adequately useable
results. To get the
radius we need to know
the centre and top right
bounds (latitude and
longitude) of the map.
We then have a distance
between the centre and
the top right.
To convert this into a
circle we use radians by
dividing each latitude
and longitude by
57.2958 (or 180/Math.
PI). Finally we convert
this distance from miles
to metres by multiplying
it by the number of
metres in a mile, which
is 1609.344. A thorough
explanation of this
formula can be found at
mathworld.wolfram.
com/GreatCircle.html.

location: location, 9. Add options to dropdown target.value], function (details, status) {


radius: 1000, Now the results are alphabetised, loop through them and var info = document.getElementById('info');
query: query create a new option element for each one and set the info.innerHTML = '';
}; index as the value. As we go along we append them to info.innerHTML += '<p>' + details.adr_
Places.textSearch(request, callback); the select element. After all the option elements have address;
} been appended as children to the select element it is info.innerHTML += '<p>' + details.formatted_
time to add it to the page. phone_number;
8. Alphabetise the results for (var i = 0; i < sortedResults.length; info.innerHTML += details.website ? '<a
The callback is passed the results and status respectively. i++) { href="' + details.website + '">' + details.
Now check that the status is okay. If it is, then create a var option = document. website + '</a>' : '';
select element and a new array of alphabetised results createElement('option'); });
(they come unordered) using localeCompare. This option.value = i; });
ensures that a precedes b, and so on. option.innerHTML = sortedResults[i].name;
function callback (results, status) { select.appendChild(option); 11. Create map-street.js
if (status === google.maps.places. } Weve demonstrated that the Places API can be used to
PlacesServiceStatus.OK) { document.body.appendChild(select); create a list of options without having to display a full
var select = document. map which is useful when you have limited bandwidth or
createElement('select'); 10. Build up details to show dont want to give much prominence to a map. Well
var sortedResults = results.sort(function Within the closure so that sortedResults is in scope move on to a split map/street view app so create a new
(a, b) { well make use of Googles event management again. file, map-street.js.
return a.name.localeCompare(b.name); This time we will listen for changes to the dropdown and (function (google) {
}); perform a getDetails search. That then returns a var map,
/* next step */ formatted address, telephone number, website, images panorama,
} and many other useful properties. infowindow,
} google.maps.event.addDomListener(select, StreetView,
'change', function (event) { Places,
Places.getDetails(sortedResults[event. TYPES = ['book_store', 'art_gallery',

37
:HE'HVLJ
The:HE'HVLJAnnual

'cafe']; }); happen, usually additional information. To facilitate this


google.maps.event.addDomListener(window, } use addListener with the two markers weve created for
'load', initialise); the main map and Street View panorama. All events are
/* next step */ 15. Configure Street View listed at bit.ly/1OR2HMw.
})(google); Carrying on within setMap, well create a Street View google.maps.event.addListener(mapMarker,
panorama in a similar fashion to the map. First of, start 'click', showInfoWindow);
12. Initialise StreetViewService by passing it a reference to an element and some google.maps.event.addListener(panMarker,
Similar to before, the initialise function is executed when configuration options. Then to link them, call 'click', showInfoWindow);
the page is loaded. At this point the StreetViewService setStreetView with the panorama.
can be instantiated. This service provides all of the var panoramaOptions = { 20. Show information window
methods and properties to interact with street views. position: center The window for each marker will show: if the place is
function initialise() { }; open or closed, an image of the place, and if the place is
StreetView = new google.maps. panorama = new google.maps. well reviewed or very well reviewed. By setting the
StreetViewService(); StreetViewPanorama(document. infoWindows content to null first, the content of the last
var center = new google.maps.LatLng(51.5072, getElementById('pano'), panoramaOptions); one clears while details load for this location.
0.1275); // London map.setStreetView(panorama); var showInfoWindow = function() {
/* next step */ var open = place.opening_hours && place.
} 16. Find nearby places opening_hours.open_now;
The zoomToRadius function can be found at var msg = open ? 'is open' : 'is closed';
13. Get the users location stackoverflow.com/a/3527136. It converts what the user infowindow.setContent(null);
Obtaining the users position we must use can see into a radius to get enough results to fill the map. infowindow.open(map, this);
getCurrentPosition. This is asynchronous so requires a Google allows you to search for various types of places /* next step */
callback function for us to handle the outcome. You can which are documented at bit.ly/1HXkInx. };
optionally require high accuracy by passing an object function getNearbyPlaces(location) {
and a time-out if you like. var request = { 21. Get details on a place
if ('geolocation' in navigator) { location: location, The most comprehensive request that Places gives you
navigator.geolocation. radius: zoomToRadius(), access to is getDetails. This takes a single place (as you
getCurrentPosition(function (position) { types: TYPES received it from a previous search) and gives a wealth of
center = new google.maps.LatLng(position. }; information on that establishment. Build up a string with
coords.latitude, position.coords.longitude); Places.nearbySearch(request, callback); HTML to append to the info window to show this data.
setMap(center); } Places.getDetails(place, function (details,
}); status) {
} else { 17. Handle results from search var html = '<p>' + place.name + ' ' + msg +
setMap(center); When the search request is resolved it fires callback. '.' + '</p>';
} First, check that the results are useable by checking that });
its the OK status. Were going to create a marker for
14. Set up the map and Places each result. Although not the most eficient way to 22. Display a places image
To show the map we give it a reference to #map and iterate, forEach is used for its readability and conciseness. If any photos are available well display the first one. The
centre it on the coordinates calculated above. A diferent function callback(results, status) { process is a little bit unusual because you have to call a
type of event listener is used here, a map listener and not if (status === google.maps.places. method called getUrl rather than being provided as a
a DOM listener. The idle event fires when the map stops PlacesServiceStatus.OK) { property. You pass this method a maximum width and
loading new tiles, eg after first load or when panning. results.forEach(createMarker); height for the image so theyre optimised for the
function setMap (center) { } dimensions youll display.
map = new google.maps.Map(document. } if (details.photos) {
getElementById('map'), { var url = details.photos[0].getUrl({
center: center 18. Create the marker maxWidth: 400,
}); Google Maps makes it simple to add new markers, we maxHeight: 200
Places = new google.maps.places. just have to tell it which map to associate it and so on. To });
PlacesService(map); add the marker within the Street View, use the code html += '<img src="' + url + '">';
infowindow = new google.maps.InfoWindow(); below and replace map with panorama. }
google.maps.event.addListener(map, 'idle', function createMarker(place) {
function () { var mapMarker = new google.maps.Marker({ 23. Show a review breakdown
getNearbyPlaces(map.getCenter()); map: map, If there are any reviews available then well show a simple
position: place.geometry.location, breakdown to indicate how well reviewed this place is.
title: place.name First, find out what the total of each rating is added
Manage variables }); together (using reduce adds the previous number to the
There are many global variables in map-street.js } current one). Then divide that total by the number of
which can become hard to maintain. In larger reviews to find the mean.
applications its a good idea to use getters and
setters to avoid accidentally overwriting them.
19. Listen to marker clicks if (details.reviews) {
When a user clicks a marker they expect something to var total = details.reviews.reduce(function

38
// Customise maps with the Google Places API

(previous, current) { html += '<p>This '+ type +' is well geometry.location, 50, function (data,
return previous + current.rating; reviewed.</p>'; status) {
}, 0); } else if (mean >= 4.5) { if (status === google.maps.StreetViewStatus.
var mean = total / details.reviews.length; html += '<p>This '+ type +' is very well OK) {
/* next step */ reviewed.</p>'; panorama.setPano(data.location.pano);
} } } else {
infowindow.setContent(html); console.log('No street view panorama
24. Review scores found');
The mean can now indicate review status. A tweak is 25. Set the Street View panorama }
needed as types are separated by underscores, not To set the Street View panorama to the place selected, });
spaces (eg art_gallery) so replace these. Once the datas use getPanoramaByLocation. This takes a location, a
calculated set the window content to the HTML string. radius in metres and a callback. The radius is how far to
var type = details.types[0].replace('_', ' look for matching panoramas and isnt always accurate. If
'); we have one update panorama with setPano and an ID.
if (mean >= 3 && mean < 4.5) { StreetView.getPanoramaByLocation(place.

Top right
Street View panoramas look impressive
but dont take much more efort to set
up than a traditional Google map

Top left
Clicking on a marker within the Street
View triggers the same behaviour as
clicking on the map interface
Bottom
Markers are displayed within the Street
View because theyve been linked to the
map on the left

39
The:HE'HVLJAnnual

Create virtual reality


panoramas
Bring an immersive VR experience to the browser and Google
Cardboard with the help of three.js

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Create virtual reality panoramas

T
he web is for everyone, but sometimes Your browser does not support the video we need to know how fast to animate and how much
technology arrives that creates a barrier element time has passed since the app started or was last called.
to this. Virtual reality is one of those </video> var clock = new THREE.Clock();
barriers. Unless you have a very expensive init();
device like an Oculus Rift or Samsung Gear you cant 2. Reference script files
access VR content. However, if you have a smartphone Much of the heavy lifting has been done for us in the 5. Start initialising scene
then you can buy an inexpensive virtual reality viewer, like form of three.js plugins. The oficial ones that we have The renderer is the heart of outputting pixels to the page.
Google Cardboard, for the price of a film (between ten made use of are StereoEfect, DeviceOrientationControls, The element is the DOM element of the Canvas. The
and twenty pounds). OrbitControls. Lastly paper.js will glue all of it together. scene is the space that everything is put into. Just like a
These low-tech devices are little more than a cleverly <script src="https://cdnjs.cloudflare.com/ movie, digital scenes contain objects, lights and cameras.
constructed piece of cardboard with two lenses. They ajax/libs/three.js/r71/three.min.js"></ function init() {
take the left and right images on a screen and trick your script> renderer = new THREE.WebGLRenderer();
eyes into believing its a single image. Its simple design <script src="js/third-party/threejs/ element = renderer.domElement;
means its easy to replicate and cheap to manufacture. StereoEffect.js"></script> container = document.
Youll learn how to use three.js to create a 360-degree <script src="js/third-party/threejs/ getElementById('canvas');
video panorama that the user can look around with a DeviceOrientationControls.js"></script> container.appendChild(element);
device and Google Cardboard all within the browser! <script src="js/third-party/threejs/ scene = new THREE.Scene();
Much of the terminology well use comes from the OrbitControls.js"></script> }
videogames world. As were using three.js, theres much <script src="js/paper.js"></script>
more interactivity that you can add to this. It allows you to 6. Create sphere geometry
add any 3D object into the world, and using ray casting 3. Create paper.js For the panorama, create a sphere and look in the inside
(to detect what the user is looking at) you could trigger Most three.js files have three lifecycle functions: init, of it. To make the sphere we generate its geometry its
interactions within it. Were going to keep it simple by render and animate. Within paper.js, well kick of by mathematical 3D representation. Then apply a matrix,
introducing the basic concepts and provide a world for declaring some variables which will be accessed by more inverting it so the outside plane is on the inside.
the user to look around and be immersed within. than one of these. var sphere = new THREE.SphereGeometry(500,
(function() { 60, 40);
1. Create index.html 'use strict';
Start by creating a blank page with a video element and a var camera, scene, renderer;
container. The video elements behaviour is controlled by var effect, controls;
attributes, in this case weve told it to play automatically
and loop indefinitely. The more sources you provide, the
var element, container;
var videoTexture, videoMesh;
Develop with Unity
Google Cardboard provides a Unity SDK and
greater the number of browsers that will be able to play it. })(); demo which you can use for free. Unity can
<div id="canvas"></div> export to WebGL (experimentally) and has
<video id="video" autoplay loop> 4. Clock and initialise community support. Unity has an easy-to-use
<source src="videos/panorama.mp4" The clock is a simple but extremely handy utility. This is interface for scenes and so on.
type="video/mp4"></source> useful for us because when animating or moving around,

Left
Adding the video mesh to the sphere makes it a bit more
obvious as to the effect that were striving for. Flip -1 to 1 in
makeScale to see this

Top left
The video is going to be projected on the inside of this
sphere. The cameras currently placed outside but will be
moved inside to pan around
Top right
The three.js site contains helpful documentation including
code examples and a breakdown of the terminology used
for arguments passed to methods

41
:HE'HVLJ
The:HE'HVLJAnnual

sphere.applyMatrix(new THREE.Matrix4(). videoTexture.minFilter = THREE.LinearFilter; camera.position.x + 0.1,


makeScale(-1, 1, 1)); var videoMaterial = new THREE. camera.position.y,
MeshBasicMaterial({ camera.position.z
7. Play video on devices map: videoTexture );
On iOS and Android, videos cant be automatically }); controls.noZoom = true;
played, it needs a user to interact with the page videoMesh = new THREE.Mesh(sphere, controls.noPan = true;
beforehand. This could be linked to a button, or in this videoMaterial);
case, any click on the page will trigger the video to play. 12. Change controls
On iOS the video will be paused as you pan around it. 9. Camera effects If the environment that our code is running in fires the
var video = document. The stereo efect works by passing the renderer to it and device orientation event then instead of using orbit
getElementById('video'); rendering everything out twice, but slightly ofset. This controls itll switch to using device orientation controls.
function bindPlay () { gives the illusion of depth and VR its appeal. To see the This means users can simply rotate their device to look
video.play(); scene we need to place a camera within it. In this case, around instead of tapping and dragging.
document.body.removeEventListener('click', the perspective camera is used for a first-person view. function setOrientationControls(e) {
bindPlay); effect = new THREE.StereoEffect(renderer); if (!e.alpha) {
} camera = new THREE.PerspectiveCamera(95, 1, return;
document.body.addEventListener('click', 0.001, 700); }
bindPlay, false); controls = new THREE.DeviceOrientationContro
10. Set cameras position ls(camera, true);
8. Create a video texture The perspective camera takes arguments in the controls.connect();
The video texture maps the video to the sphere. Create following order: field of view, aspect ratio, depth to start controls.update();
the texture by passing it the video element, then set the rendering objects (near), and depth to stop rendering
min filter to linear as the size is unlikely to be a power of 2 objects (far). Once created, positioning the camera is as 13. Remove event listener
(eg 16 by 16). The material describes the appearance of simple as setting its 3D coordinates: x, y and z. Once the controls are set to use device orientation, we
the object. The basic mesh will show as a flat polygon. camera.position.set(100, 100, 100); wont want to reinstantiate those controls every time the
var videoTexture = new THREE. scene.add(camera); event is fired. To fix this, remove setOrientationControls
VideoTexture(video); at the bottom of the previous function.
11. Add controls for mouse window.removeEventListener('deviceorientati
Next up well add orbit controls. This allows you to click on', setOrientationControls, true);
and drag to look around, which is useful for debugging }
Black screen when not on a device. We then set the starting position
of the controls to the same position as the camera. 14. Device orientation
Some built-in command-line servers (like PHP
and Python on OS X) dont serve video files controls = new THREE.OrbitControls(camera, The device orientation event is fired when the
correctly. MAMP or similar programs are able to element); accelerometer detects a change in the devices
handle them though. controls.rotateUp(Math.PI / 4); orientation. Were interested in the z axis, otherwise
controls.target.set( known as alpha (beta and gamma are x and y

Top left
The DeviceOrientationControls adds its own event
listener to deviceorientation. As the device moves, it
updates its alpha, beta, and gamma values

Top right
Finally our Cardboard app comes together with the stereo
effect plugin duplicating and offsetting the rendered
video; its very effective viewing
Right
Firefox provides excellent tools for debugging whats
happening in Canvas elements. It captures a frame and
you can scrub through to see changes

42
// Create virtual reality panoramas

Content for your


panorama
One of the most
challenging parts is
finding good content for
360-degree panoramas. A
number of apps exist for
smartphones (like Google
Street View or Microsoft
Photosynth) which takes
multiple pictures and
stitches them together.
While these are often free
and easy to use, automatic
stitching is hard to ensure
and there are often
misaligned objects. To get
true 360-degree content
you need dedicated
hardware, like a rig of
GoPros or the RICOH
THETA. The strange
appearance of these
images is known as an
equirectangular
projection. It distorts the
northern and southern
parts of the image and has
two distinct fisheye
distortions. Google Images
has a few of these, but are
rarely royalty-free.

respectively). Alpha goes from 0 to 360. In the init of seconds since the clocks getDelta method was last should be straightforward but there are many vendor
function well add the listener for device orientation. called. Itll be called by the animate function, which will be prefixed versions that we need to accommodate. The
window.addEventListener('deviceorientation', written shortly, and invoke getDelta. first of the if statements is the standard, nonprefixed one
setOrientationControls, true); function update (dt) { and we cascade down Microsoft, Mozilla and WebKit.
resize(); function fullscreen () {
15. Add sphere to scene controls.update(dt); if (container.requestFullscreen) {
The final part of init adds the video mesh, the } container.requestFullscreen();
culmination of the sphere and video texture, to the } else if (container.msRequestFullscreen) {
scene. Attach a resize handler to ensure that browser 18. Render function container.msRequestFullscreen();
resizing doesnt look strange, and kick of animate. The render function outputs everything to the screen. } else if (container.mozRequestFullScreen) {
scene.add(videoMesh); Efect here is the stereo imaging and sets up the left and container.mozRequestFullScreen();
window.addEventListener('resize', resize, right images which behave as separate cameras. } else if (container.
false); Internally it then uses the renderer (which we provided webkitRequestFullscreen) {
animate(); much earlier) to output to the Canvas. container.webkitRequestFullscreen();
function render () { }
16. Resize function effect.render(scene, camera); }
Resize is responsible for making sure the aspect ratio is }
maintained when resizing the window (or if going from 21. Finishing touches
portrait to landscape). Then the renderer and stereo 19. Animate function Through the goodwill of the developer community, the
efect are updated with the new width and height. Animate keeps our panorama responsive to movement. technology exists to place 360-degree panoramas in the
function resize () { At each frame it calls update and render. Crucially, it also browser. There are currently limitations on playing back
var width = container.offsetWidth; calls itself as a requestAnimationFrame callback. This video within iOS which needs to be addressed but as an
var height = container.offsetHeight; ensures that the camera is perpetually updated. interim, an image-only panorama can be used.
camera.aspect = width / height; function animate () { #canvas {
camera.updateProjectionMatrix(); requestAnimationFrame(animate); position: absolute;
renderer.setSize(width, height); update(clock.getDelta()); top: 0; bottom: 0;
effect.setSize(width, height); render(); left: 0; right: 0;
} } }
#video {
17. Update function 20. Fullscreen ahead position: absolute;
The update function calls resize and updates the controls Earlier we referenced a full-screen function which is left: -9999em;
with a new delta from the clock. The delta is the number triggered when the user clicks the Canvas element. This }

43
The:HE'HVLJAnnual

Build iOS-style web


applications with
Framework7
Use Framework7 to put together a quick app for iOS with all
the looks of native iOS but with the ease of HTML5

DOWNLOAD TUTORIAL FILES


44 www.filesilo.co.uk/bks-809
// Build iOS-style web applications with Framework7

E
ver since the first iPhone hit the market window and cd into your new project folder. Next run the var myApp = new Framework7({
eight years ago, mobile has become the following command: init : false
dominant platform for displaying > $ bower install framework7 });
webpages and web apps. Since then web var $$ = Dom7;
developers have been working tirelessly to emulate the 3. Copy project files myApp.init();
look and feel of native iOS apps in HTML5 and JavaScript. A new folder will appear called bower_components, go to With the myApp variable weve created a new instance of
Then iOS 7 happened and it had a brand-new look and bower_components/framework7/dist and copy all of the Framework7 to use. The $$ variable is the Framework7
feel; all of those libraries and designs that first appeared contents of the dist folder (all of the files inside dist, not Dom7 library that handles DOM manipulation its like
due to the creation of the first iPhone suddenly looked the actual dist folder itself) to the root of your project jQuery, but lighter. Finally, MyApp.init() begins our app.
ancient in the face of new flat designs that Apple started folder, then delete the bower_components folder as we
pumping out. If users notice theyre using a web app, they wont need that again. 7. Display in a view
inherently think its lesser than its native cousins, so Mostly everything that is displayed in a Framework7 app
everything web devs had used to make their lives easier 4. Clean up is within a view. By adding classes to certain HTML
over the years needed a serious overhaul and fast. The files weve copied into our project folder is a skeleton elements we allow Framework7 to treat certain elements
Enter Framework7, a seriously comprehensive set of app for Framework7 and were going to use it as the in certain ways. With classes, Framework7 enables us to
libraries and assets that lets you put together a modern basis for our own project. Delete the about.html, form. create navigation bars, pages and toolbars. Were going
iOS-like app in no time at all. No more fishing around for html and services.html files. Then open index.html and to use the first two.
icon images or manually animating transitions between scroll down to line 10 and make the following changes:
diferent views, we get all of that out of the box. In this // From this 8. The classes have it
tutorial, were going to make a simple app that shows of <link rel="stylesheet" href="css/framework7. In Step 6, we have a number of divs with classes. On the
some of Londons most famous tourist attractions. min.css"> right elements in the right order, Framework7 uses these
// To this classes to manipulate user interactions and animate
1. Set up the project <link rel="stylesheet" href="css/framework7. elements. Class=navbar tells Framework7 to use that div
Getting Framework7 started is a little tricky, were going ios.min.css"> as a wrapper for the navigation bar, class=navbar-inner
to have to do some house cleaning before we can start becomes the holder for the text content and
writing code. Before we grab Framework7 create a new 5. Strip index.html class=center sliding aligns our text to the centre and
folder for your project. Create an empty file called index. A lot of the stuf that we will be making use of is in index. adds a sliding animation when the view is changed.
html in your new folder and create a folder structure like html, but theres also a lot of stuf that were not going to
the following: be making use of. To save confusion were going blank
- Project Folder (root)
- assets
slate. Delete everything from index.html between the
<body></body> tags.
F7 is Retina-ready
Straight out of the box, F7 comes with a great
Retina-ready icon set as well as styles that let you
2. Get Framework7 6. Strip Core.js get on with your markup and application logic.
There are a couple of ways to get Framework7, you can Head into the js/ folder and open my-app.js for editing. No more tweaking CSS margins, paddings and so
grab it from GitHub if you like, but were going to use Delete everything already in the file and add the on trying to make everything look just right.
bower to grab everything we need. Open up a terminal following in its place and save.

Left
Using Gulp and Bower, you can build a custom F7 library
that only has the modules you need, but thats painful for
what were doing, so just copy the kitchen sink

Top left
Bower makes getting Framework7 an absolute synch.
Simply open terminal, put in the command and Bower
grabs everything we need from the GitHub repo
Top right
The item-media class on a <div> element lets us add little
icons to the items in our list

45
:HE'HVLJ
The:HE'HVLJAnnual

9. Preview our work <div class="page-content"> Now if you refresh and look at the console, youll see an
Framework7 relies heavily on AJAX for most actions that <div class="list-block"> object with all of the data to build our list. Remember that
afect the content of the DOM. This means we need to <ul id="places"> $$ is like the Framework7 equivalent of jQuery, and a lot
run a local server to view our project files. On most </ul> of its functions follow similar naming conventions.
systems that come with a Python installation, you can set </div>
up a quick static file server with: </div> 14. Add HTML
$ python -m SimpleHTTPServer 8080 </div> Now that we have the landmarks.json file we can put
</div> together HTML elements based on the data we have.
10. Content with content Inside the callback for getJSON, add the following:
So far, our app does little. Its a view with a navigation bar 12. Register our view myApp.landmarks = data.landmarks;
that says Landmarks of London and not much else we Before we can manipulate our view, we need to register it var place = undefined, list = "";
need content. Grab the resources from FileSilo and move with a Framework7 instance (myApp variable). In my-app. for(var x = 0; x < myApp.landmarks.length;
the landmarks.json file to the project root. This contains js add the following just before myApp.init(): x += 1){
all of the information we need to build a list of options var mainView = myApp.addView('.view-main', { place = data.landmarks[x];
that our users can click. Next move the contents of the // Because we use fixed-through navbar we list += '<li class="landmark-link">\
assets folder to the assets folder you made earlier. can enable dynamic navbar <a href="#" class="item-link" data-
dynamicNavbar: true landmark="' + place.name + '">\
11. Create our first page }); <div class="item-content">\
To put content in a view, we need a page to insert it into. myApp.onPageInit('index', function (page) { <div class="item-media"><img src="' + place.
Think of a view like a book cover that binds everything console.log("main-view initialised"); icon + '" width="29"></div>\
and a page as a page. Add the following after the closing }); <div class="item-inner">\
tag of <div class=navbar>. With data-page, we give our Now when myApp.init() is called our view-main is <div class="item-title">' + place.name + '</
page a name we can access. registered and initialised, and then a callback is called div>\
<div class="navbar"> ... </div> with the onPageInit listener. We can now write code to </div>\
<div class="pages navbar-through toolbar- populate a list of places from landmarks.json. </div>\
through"> </a>\
<div data-page="index" class="page"> 13. Populate our page with data </li>';
To make a list of places a person can go to, were going }
to GET landmarks.json and use its info to populate our $$('#places').html(list);
page. Back in my-app.js amend myApp.onPageInit() call });

Framework7 Android
An iOS app on an Android system would look out of
so it looks like this:
myApp.onPageInit('index', function (page) {
For each landmark an <li> element is created and added
to the #places <ul>.
place, wouldnt it? Dont worry, Framework7 has a $$.getJSON("landmarks.json", function(data){
Material Design version for Android too. Same console.log(data); 15. Assign click events
code, but with diferent styles. }); Now we need to be able to tap elements. Using the
}); landmark-link class, assign a click event to every list item.

Top left
With $$.getJSON, retrieve and parse a JSON file with all
the information we need to build our page. Of course,
this can be any JSON output

Top right
Using D7 (F7s DOM manipulation library) we can generate
and insert the HTML weve created from our JSON file
Right
Our app is pretty bare-bones, but we now have a
foundation to build great things on

46
// Build iOS-style web applications with Framework7

All-encompassing
libraries
Web projects, or apps
written with web
technologies, are
notorious for becoming
unmaintainable after a fair
amount of development.
Part of is due to the code
that has to be written to
tie various JS libraries that
do things better or quicker
than you might have done.
With F7 and other similar
frameworks, you dont
have to write the glue that
holds everything together
you just write the way the
framework dictates you
should to achieve the
result you want. By
making developers follow
the convention of a
framework that does close
to everything, rather than
using mutiple libraries to
do the same thing, other
developers who use the
same framework can
quickly pick up where you
left of and maintain your
code and vice versa.

... were going to use Framework7s template library we if(myApp.landmarks[y].name ===


$$('#places').html(list); just need to activate it. Find the $$ variable in my-app.js clickedLandmarkName){
$$('.landmark-link').on("click", and change the code to this: var info = {
function(evt){ var $$ = Dom7, placeName: myApp.landmarks[y].name,
// Clever clicky code goes here... $T = Template7; placeInfo: myApp.landmarks[y].info,
}); var landmarkTemplate = $$('#landmark- placeImage : myApp.landmarks[y].image
template').html(), };
16. Clever code compiledTemplate = $T. var compiledHTML = compiledTemplate(info);
When we click an item in our list, we need to find out compile(landmarkTemplate); break;
which one we clicked. On the <a> tag we added in our }
$$.getJSON we created a data-landmark data attribute. 18. Create a template
We can get that value and then work through every Template7 works a lot like handlebars, by using 20. Render the template
landmark stored to get the appropriate information {{[VARIABLE_NAME]}} we can replace chunks of code Now, compiledHTML contains the HTML for our new
needed to create another page. with values that we pass. In the FileSilo files you page, but weve not added it to the DOM yet. We could
... downloaded earlier, there is a landmark_template.html add it with $$([ELEMENT]).html(compiledTemplate), but
$$('.landmark-link').on("click", file. Copy its contents and add it to the end of index.html that wont register the page with our Framework7
function(evt){ just before the <script> tags we already have there. instance. Instead, to get all the back-button and
var clickedLandmarkName = $$(evt.target). <!--Insert landmarks_template.html here--> animation goodness we can use F7s built-in router. This
parents('a')[0].getAttribute('data- <script type="text/javascript" src="js/ will render our content and animate it approriately.
landmark') ; framework7.min.js"></script> ...
for(var y = 0; y < myApp.landmarks.length; <script type="text/javascript" src="js/ var compiledHTML = compiledTemplate(info);
y += 1){ my-app.js"></script> mainView.router.loadContent(compiledHTML);
if(myApp.landmarks[y].name === </body> break;
clickedLandmarkName){ }
break; 19. Use our template ...
} Now that we have a template, we will go on to using it. In
} my-app.js we were looping through all of the landmarks 21. Round-up
}); we knew about to find the information for the list item we Now weve put together a fully interactive, native-like
clicked. Once we find it, we can use the data to generate prototype app in no time at all. Weve used views,
17. F7 templating engine HTML by compiling our template. We can do this by explored the part that classes play in F7 and rendered
When we tap our list item, we want to make a new page passing an object with the variables that we used in the valid HTML with F7s template engine T7. Remember, F7
with all of our information. Multiline strings are a pain, so template ( the {{ }} ). can do so much more, so get exploring!

47
The:HE'HVLJAnnual

Deploy your web


apps to Heroku
Set up SSH keys spinning up an instance and deploy to the cloud
with command-line Git

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Deploy your web apps to Heroku

W
e all enjoy making things every inbox now for an email confirming that you want to sign you can read on and follow what they say. SSH keys are
now and then. This can take any up and create a strong password. If youre worried about user credentials that dont involve a password. Instead
form a linter, image converter or Heroku costing you something, fear not because theres though, it uses public-key cryptography to generate a
even a web service that sends you a a free tier for you to experiment, explore and learn from. secure way of authenticating a user to a service, and
picture of a cat whenever someone hits a button. This free tier is the one that well be using in this tutorial. were going to do just that with Heroku. This will spare
Often made for ourselves, sometimes, these tools pick you having to type in your password every single time
up traction and other people start to use the thing youve 2. The dashboard that you want to do something.
made; youve solved a problem that other people have, Once youve logged in to your dashboard, its here that
congratulations! But this success has brought you a we can create, manage, deploy and destory our apps 6. Create an SSH Key
problem in itself, how are you going to keep your servers with the help of the Heroku platform. If you click your In terminal, enter the following with the email address
up with all of these new people using your shiny thing? email address in the top left of the dashboard, youll see you used to sign up to Heroku:
Shared web hosting is designed to be used by a a dropdown with the option Manage Account. Dont click ssh-keygen -t rsa -b 4096 -C [[YOUR@
couple of hundred, maybe even a few thousand people it, but take note of where it is located for now as well be EMAILADDRESS.COM]]
at the same time. Its not going to be able to stand up to using it in a little while A new private/public key will be generated for you. Youll
something going viral at least not for long and thats be asked if you want to store the keys anywhere specific,
assuming your web project is relatively small. If youve 3. The Heroku Toolbelt just hit enter and accept the defaults until youre asked
made something thats, lets say, 2MB in size, it doesnt In development, the Terminal is a powerful tool. Heroku to enter a passphrase, choose something secure but
seem like too much for your provider to handle, does it? has created a Toolbelt to help us get the most out of memorable its not easy to change this one!
What if 10,000 people access your site in one day? Thats Heroku through the command line. Most of this tutorial
20GB in bandwidth youve got to provide! Shared hosting will be done in the CLI (command-line interface), so head 7. Enable the SSH Keys
is not going to cut the mustard. You could provision a to toolbelt.heroku.com, select the right Toolbelt for your To get your system to actually use your new SSH keys,
server and make it bigger as the site gets bigger, but that operating system and simply follow the instructions to we will need to add them to the SSH agent. After that we
means youve got to select a provider, access the server, install it. can add them to Heroku. Enter the following command,
configure it for your app and, more often than not, scale it youll be asked for the passphrase you used when
manually. This is not good enough. 4. Log in with the Toolbelt
This is where Heroku comes in. Heroku is a cloud Once the Toolbelt has installed, you should now open
platform that delivers your app for you, it scales your terminal (or the equivalent for your operating
whenever you like and it has Node, Ruby, PHP and system) and simply enter:
Python built into it and ready to go! This tutorial is going heroku login Herokus tiers
to walk you through setting up a Heroku account, getting Heroku has four pricing tiers: Free, Hobby,
Standard and Performance each one is more
SSH keys all in order, configuring a Node.js app for
powerful and expensive to run than the last.
deployment and then firing it of to Heroku to be run. 5. Heroku and SSH Keys Were using Free, but if youre deploying
In the next few steps, we will now go over creating SSH something small that you want to run 24/7 (the
1. Create an account keys on a Unix-based system (Linux or OS X). If youre free tier has to spend six hours ofline daily) then
Head on over to heroku.com and then simply click the familiar with this process though, you can just skip over Hobby is only $7 (4.60) monthly per instance.
Sign Up button to create a new account. Check your them and generate the SSH keys as you like, otherwise,

Left
Signing up is easy. Heroku is for single users and
businesses alike, but dont be put of by them asking for a
business name, you dont need one

Top left
From the dashboard, all things Heroku can be found and
controlled. Take some time to look around and try out the
various options
Top right
The Heroku Toolbelt lets us control every aspect of Heroku
and our apps from the CLI. Its the most efficient way to
interact with Heroku

49
:HE'HVLJ
The:HE'HVLJAnnual

creating the new keys. The SSH key will then be ready to Youll be asked if you want to upload your key to Heroku. 11. Prepare for deployment
be used by your computer and it will also have been Hit Y for yes. If you have a project ready that youd like to test
copied to your clipboard. deploying to Heroku, cd to the root folder of that project
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/ 10. Create a new project now. Otherwise, there is a demo project that you can
id_rsa && pbcopy < ~/.ssh/id_rsa.pub On your Heroku dashboard there is a + sign in the grab from our FileSilo downloads. Once youve made
top-right corner. Click it now to create a new Heroku app. your way to your chosen project in Heroku, enter the
Youll then be given a form asking you to enter a name following commands:
8. Add the SSH key and whether you want your server to be in the US or git init
Remember that Manage Accounts button we told you to Europe. If you dont enter a name, one will be generated heroku git:remote -a name_of_your_heroku_app
take note of earlier? Its time to press it. Head back to the for you, so its up to you whether you want to give your When those commands have completed, we will have
Heroku dashboard (heroku.com will redirect you there if app a name. created a new Git repo with our Heroku app as a remote.
youre still logged in) and then click the Manage Account
button. Now just scroll down until you see SSH Keys, click
edit and then paste the SSH key into the input (the last
command that we entered also copied it into our
clipboard for us).

9. Alternative method
If all that GUI goodness is not your way of doing things,
you can upload the SSH key to Heroku with the
command-line interface. Simply head back to your
terminal and enter:
heroku keys:add

Work with Procfiles


When youre working on a project with multiple
team members, its not always a dead cert that
every one is going to push to Heroku with the
same provisioning settings. By using a Procfile
and including it in your shared Git repo, you can
be certain that every time a team member
pushes a deployment to Heroku, it will run on
what its meant to.

Top left
Once you have your SSH key, adding it is simple. Just
click on Manage Account and scroll down until you see
the option. Click the tab and then paste your key in

Top right
Heroku wont cost you money straight off of the bat, but if
someone gets a hold of your account it could cost you
dearly. Strong passwords are a must
Right
Our app is just a simple static page being delivered by our
Node.js app with a simple CSS animation, but gosh, doesnt
it look friendly?

50
// Deploy your web apps to Heroku

Dyno types
Heroku has a bunch of
tiers, but these tiers
comprise dyno types,
which are the kinds of
machines (specs if you
will) that you can run.
When scaling your
services, you can choose
which of these dynos you
want to use, as each use
case may require diferent
kinds of services. For
example, lets say your
web service just got some
overnight fame on one of
the social networks we all
love to loathe, your
standard instance is now
starting to buckle under
the pressure you need to
scale now! But even with
the hundreds of hits youre
getting, your standard
instance is still holding its
own. Scaling up to a
performance instance
would almost certainly
solve your problem, but
its also probably overkill
as this amount of trafic
might not last that long.

With this, we can use SSH and Git to deploy our apps to git commit -m
Heroku with a Git commit. git push heroku master
Youll see Heroku building, testing and then finally
12. Our demo app deploying our app to its platform. If all has gone well,
Our app is a simple Node.js/Express server, delivering youll see something like
files in our public folder to whomever browses to /. One Launching... done, v1
thing to note is the port binding on line 7 of demoServer. remote: https://your_heroku_app.herokuapp.
js: process.env.PORT || 8080. Process.env.PORT lets com/ deployed to Heroku
Heroku choose the port it wants to make our app
available on as it can change per deploy or instance. 14. Debugging errors
Except you probably wont see that everything has gone
13. Deploy to Heroku right, because weve deliberately added an error. So how
We can also deploy with a Git commit. Now that we have do we debug errors on our Heroku instances? If a
Heroku set up as a remote Git repository, by pushing Heroku build fails, it will refuse to deploy the broken code
new code to it, Herokus build process will be triggered in favour of previously working code. But that only works
and will deploy our app for us. Lets give it a go now: if its a compile-time error. If the error is a run-time error, it error may lie, you can enter heroku logs --tail and youll
git add . wont break until after its deployed. To find out where the see the latest entries for your Heroku server.

51
:HE'HVLJ
The:HE'HVLJAnnual

15. Fix the error 16. Deploy the fix


If you look at our logs, the error that was deliberately Now that weve fixed our app, we can try and redeploy it
made is simple, Our Node.js app is trying to listen on a to Heroku. Theres no special procedure for this, simply
port reserved by the system. Now just open demoServer. commit the modified files for a Git push and then push to
js and change line 7 so that it reads: the Heroku origin.
// Old git add .
// port = 15 || process.env.PORT || 8080; git commit
-m
// New "Fixed server port issue"
port = process.env.PORT || 8080; git push heroku master

Heroku origins notoriously hard to move from development to production. Heroku was designed to be
Heroku is not the spring chicken you might think it is its been ticking along, in one a one-stop-shop for getting your latest and greatest Ruby-based works out into the
form or another, since 2007! One of the first cloud platforms, originally, Heroku was world. As time moved on, so too did developers language preferences. Over the years
designed as a platform for quickly deploying Ruby projects that people wanted to share. Heroku made performance tweaks and added in the ability to deploy projects using
Back in 2007 (and some might argue that little has changed since) Ruby projects were almost any technology you can think of.

52
// Deploy your web apps to Heroku

instances, or perhaps you needed to execute a diferent


command to run your node app on a Heroku server (like
installing and running Bower or Gulp, for example). These
are the functions that the Procfile is for. Think of a Procfile
as a package.json for Heroku instances. It lives in the root
of your Heroku project folder, is called Procfile, and
whenever you deploy your app to Heroku, the
commands inside of it are the commands that will then
be used to build and run your shiny new service.
DemoServer.js begins the command that runs our server
(as defined in our package.json), you can have the
following execute in its place.
web : npm install bower && bower install &&
node demoServer.js

17. Scale your web service


By default, Heroku will start your apps running on the
web=2
.in your command-line interface. That will spin up two
Heroku hardware
With Heroku, we dont have to provision machines or
web tier of its service. This is the least powerful of the web-scale instances of your Heroku app and will split the set up environments. So much hard work must have
tiers available, but its also free. Lets say you have an users betwee n them thus, each server will handle half gone into building an infrastructure. It may surprise you
overnight hit on your hands, how do you scale your app of the load. to learn that Heroku doesnt have its own hardware it
runs on AWS (Amazon Web Services), which, in a way,
to handle all of these new people wanting to use the makes Heroku a kind of API for a the Amazon web
great thing youve made? Its actually pretty simple, you 18. Procfiles and you platform. This is known as SaaS (software as a service)
can just enter: Lets say that you wanted to deploy an app to Heroku business model.
heroku ps:scale and you didnt want to worry about the provisioning of

Code library
var express = require('express'),
app = express(),
These are some http = require('http'),
typical modules that
fs = require('fs'),
you would probably
use in a Node app. Any querystring = require('querystring'),
module included in request = require('request'),
your package.json will port = 15 || process.env.PORT || 8080;
also be installed by for(var _ = 0; _ < process.argv.length; _ += 1){
Heroku when you
if(process.argv[_] === "--port" || process.argv[_] === "-port" ||
deploy your project.
process.argv[_] === "-p"){
if(process.argv[ _ + 1 ] !== undefined){
Our demo app is a port = process.argv[_ + 1];
simple, static break;
webpage. This line }
says that whenever
}
someone hits the /
path of our web }
domain, every file and app.listen(port);
resources that we will app.use(express.bodyParser())
be accessing will app.use(express.static(__dirname + '/public'));
come from the public
app.use('/images', express.static(__dirname + '/images'));
folder in our project.
app.use(express.cookieParser());
app.all('*', function(req, res, next) {
This is a simple res.set('Access-Control-Allow-Origin', '*');
Express route. If you res.set('Access-Control-Allow-Methods', 'GET, POST');
want to process some res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-
information or give a
Type');
specific resource a
special URL, you can next();
do that here. If you go });
to your Heroku app console.log("Server started.\nAvailable on localhost:" + port);
address and add / app.get('/hello', function(req, res){
hello to the end, youll
res.send("Hi!");
see Hi!.
});

53
The:HE'HVLJAnnual

Develop a web app


quickly with Lucee
Say hello to the Lucee language, the latest CFML engine, and
quickly build a powerful dynamic application

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Develop a web app quickly with Lucee

T
o some, CFML (ColdFusion Markup ./startup.sh return true;
Language) may not mean anything. To or for Windows: }
others it may be perceived as an ./startup.bat
out-of-date language no longer used. In 5. Directory index
fact CFML is 20-years-old this year and it was born the 2. Default page and admin Create a new file called index.lucee in the directory. This
same year as PHP and JavaScript. If you havent yet After starting up the Lucee engine you will be able to will be the default index page for our application. To start
experienced building a CMFL application yet, then now is access the server in your browser via http:// well simply request a data dump of everything available
your chance to do so. localhost:8888. The default welcome page that appears within the application scope (created from the
Lucee, a completely open source CFML engine, was here will have some useful links to guide you through the application configuration file). You can use the tag format
released in January 2015. As a fork from an existing CFML language, and it will also have two important links that or script syntax to do this.
engine Lucee did not have to start from scratch and had will take you right through to the server and web <:script>
a fantastic core engine to build upon. administrators too. dump(application);
In this tutorial we will download and install an Express </:script>
edition (self-contained) version of Lucee 5, which includes 3. Application component
all of the latest additions to the code syntax and Create a new file in the root of the new directory called 6. Task model definition
language. We will develop a simple example application Application.lucee. This component will hold the Create a new directory of model, and inside of this
using the new Lucee dialect and file extensions, and we application-specific variables and configuration for this create a new file, task.lucee. This new component
will then show an example of how to interact with the subapp. Create the name using a hashed version of both contains properties for our model defined, setting the
application scope for persistence. We will use Lucees the current path and substring value to help ensure that type, name and default value attributes for each. The
member functions to check for variables within certain it is unique. getters and setters will be created for us thanks to the
scopes and lengths of arrays. component { accessors=true attribute.
We will also look into creating RESTful API resources this.name = hash(GetDirectoryFromPath('./')) component accessors="true" {
using Lucee and mapping components to match REST & '_procrastination_app'; property type="numeric" name="id";
paths. We will see how to manage sending arguments in } property type="string" name="title"
the URL as well as dealing with both GET and POST default="";
requests to the API. 4. Run onApplicationStart property type="string" name="content"
The application framework will support multiple
1. Download Lucee event-driven functions which we are then able to interact
The Lucee language is available for us to download from with. OnApplicationStart will run the very first time that
a number of platforms in stable and beta versions. Just
head on over to lucee.org/downloads.html to do just
the application instantiates. Here we will then define two
variables that are assigned to the application scope, and
Lucee 5 beta
In this tutorial we have been using the latest
that. We will be selecting Express version 5 to use in this these are made available for us to access throughout the
version of Lucee 5, still in beta at time of writing
tutorial, which is a version that will work across all entire application. but almost production ready. The new Lucee
operating systems. Now you can just unpack the archive boolean function onApplicationStart() { dialect code format and file extensions are only
file and use your terminal or command prompt to start application.tasks = []; available in version 5.
up the server. application.completeTasks = "";

Left
CFML server management and configuration is a
relatively simple process thanks to Lucee and its server
and web admin contexts

Top left
Open your terminal or command prompt window and start
the Lucee Express edition engine using the platform-
appropriate start-up script
Top right
Our model properties and the accessors=true attribute
generates all of the GET and SET methods we need to
populate our model, shown here as a dumped object

55
:HE'HVLJ
The:HE'HVLJAnnual

default=""; 7. HTML layout <body>


property type="boolean" Open index.lucee and define the base HTML layout for </body>
name="complete" the application. Were using Bootstrap for structure here. <script src="https://ajax.googleapis.com/
default="false"; Note the output tags wrapping the entire template. ajax/libs/jquery/1.11.3/jquery.min.js"></
} These will deal with any string wrapped by # characters script>
as a variable for translation. <script src="js/bootstrap.min.js"></script>
</html>
<:output> </:output>
CFML from the CLI <!DOCTYPE html>
CommandBox is a stand-alone native command <html lang="en"> 8. Form definition
line interface tool written in CFML with package <head> Create a new form now that will post back to the
management and much more. It also generates <meta charset="utf-8"> index.lucee page. This will have a text input field with the
embedded Lucee servers for your local
<title>Procrastination List</title> name attribute set to title and a textarea field with the
development work. You can find out more by
going to bit.ly/1CqTokB. <link rel="stylesheet" href="css/bootstrap. name set to content. The submit button will have the
min.css"> name new_task which we will use to identify a
</head> submission. Then finally, the variable #strFlash# will be

Top
Lucee has been open and available to the community
since its release and welcomes pull requests and
community interaction

Middle
Full documentation for the language tags and functions
are available from the Lucee site, complete with all
attribute variations and options
Right
Lucee is available to download for Windows and
Linux-based operating systems, in full installer versions or
Express editions

56
// Develop a web app quickly with Lucee

The application framework


Throughout this tutorial we have made extensive use of the application scope to persist variables throughout the application. Its not
advised to use that scope as a data store (except for this example application as it saved on setting up a database connection) but it is
incredibly useful for persistence and sharing objects, variables and certain bits of data. We created an application.lucee file, which
could also have been an application.cfc (ColdFusion Component). This is a special file for CFML projects and enables a lot of
event-driven method processing. Make sure that you check out this great introduction to the application framework in Lucee for more
information bit.ly/1gF2Mau.

used to display any errors that appear. 9. Script block model, and we will then populate the properties with the
<div class="container"> Create a new script block at the top of the index.lucee values and insert that component into the task array
<h1 class="page-header">The Procrastination file. Create a default strFlash variable with an empty using the built-in arrayAppend function. If either of the
List</h1> value. An if statement will check for the existence of the title and content are missing then well create the
#strFlash# new_task button in the form scope (available after a form warning message for output.
<form method="POST" action="index.lucee" submission). If it exists we can then process the if ( len(form.title) && len(form.content)
class="form-horizontal"> submitted values accordingly. ) {
<div class="form-group"> <:script> task = new model.task(
<div class="col-sm-offset-1 col-sm-11"> strFlash = ""; title=form.title,
<button type="submit" name="new_task" if ( structKeyExists(form, 'new_task') ) { content=form.content,
class="btn btn-default">Save } id=arrayLen(application.tasks)+1
Task</button> </:script> );
</div> arrayAppend(application.tasks, task);
</div> 10. New model instantiation } else {
</form> If both the title and content values are present in the strFlash = '<div class="alert alert-
</div> form submission then we will instantiate a new task warning">Please provide a title and task

57
:HE'HVLJ
The:HE'HVLJAnnual

detail.</div>'; hover"> 12. Loop over collection


} <thead> Place a new form between the table body tags to post
<tr> back to index.lucee. Within this form loop over the tasks
11. Display the list <th colspan="2">&nbsp; array from the application scope. The checkbox id and
Below the header, we will now add some code to detect </th> value hold the task id and the conditional statement will
if we have any records saved in the array. ArrayLen is a </tr> populate the checkbox if already marked as complete.
built-in CFML function to check for the length of the </thead> <:loop collection=application.tasks
provided array. If true, the following HTML panel and <tbody> item="task">
table will be displayed to the user. </tbody> <tr class="<:if (application.tasks[task].
<:if arrayLen(application.tasks)> </table> getComplete())>success</:if>">
<div class="panel panel-default"> </div> <td>
<table class="table table-bordered table- </:if> <input type="checkbox" name="task"

Introducing the Lucee dialect


Lucee 5 contains an updated enhanced language framework and syntax that is known as the Lucee dialect (or occasionally referenced
as LuceeLang). The dialect is based on the original concepts of CFML. As a relatively new engine it continues to support CFML and the
ecosystem around it, which includes compatibility support for existing versions of CFML engines including Adobes ColdFusion engine.
As well as helping to maintain backwards-compatible syntax for existing applications it also wants to help drive the CFML environment
and update the syntax and available methods and functions. This is where the Lucee dialect comes into play. Find out more about this
dialect by going here: bit.ly/1KaNiF2.

58
// Develop a web app quickly with Lucee

id="check[#application.tasks[task] = strTasks; sent_value. This response uses CFMLs built-in


.getId()#]" } dateTimeFormat() method to handle formatting the
<:if (application.tasks[task]. current time returned from the now() function.
getComplete())>checked</:if> 15. Clear completed tasks remote any function returnResponse(string
value="#application.tasks[task] If the user submits the button now to clear the sent_value restargsource="Path")
.getId()#" /> completed tasks, the conditional statement will check for httpmethod="GET"
</td> the existence of the clearcomplete value that was sent in restpath="{a}"
<td> the URL. This will then loop over all tasks and, once it has {
<p>#application.tasks[task].getTitle()#<br found the matching task using the ID, it will go on to return {
/> delete it from the array before sending the user back to 'request_made':
<span class="small">#application. the index page. dateTimeFormat(now(),
tasks[task].getContent()#</span> 'dd/mm/yyyy HH:NN'),
</p> if ( structKeyExists(url, 'clearcomplete') ) 'value': arguments.a
</td> { };
</tr> for( task_id in listToArray }
</:loop>
(application.completeTasks) ) { 19. Handle POST requests
13. Update the tasks for( task in application.tasks ) { Create another remote method to handle our POST
Include the following buttons before the closing form tag if ( task.getId() EQ task_id ) { requests. The restargsource attribute will be set to Form,
in the table. Once an update has been processed and arrayDelete(application.tasks, task); expecting the parameter posted_value in that
any tasks are complete, check the length of the } submission. return the submitted value, the current
application scope completeTasks list variable. If it holds } datetime value and the entire arguments scope, which
data, display the button to clear those items from the list. } could be used for API response debugging.
application.completeTasks = ""; remote any function postResponse(string
<tr> location('/app', false); posted_value restargsource="Form")
<td colspan="2"> } httpmethod=
<input type="submit" name="update_tasks" "POST" {
class="btn btn-default" value="Update Tasks" 16. Creating REST resources return {
/> Lucee ofers an incredibly easy way to create and 'request_made': dateTimeFormat(now(), 'dd/
<:if listLen(application.completeTasks)> generate RESTful resources, written using the familiar mm/yyyy HH:NN'),
<a href="/app?clearcomplete=true" component structure. Create a new directory called rest 'you_submitted':
class="btn btn-danger">Clear within your project, inside of which we will place all of our arguments.posted_value,
Complete Tasks components. Create a file called random.lucee with the 'form_data':
(#listLen(application.completeTasks)# / following code. The rest path attribute dictates the URL arguments
#application.tasks.len()#)</a> that this component will respond to when we call the API. }
</:if> }
</td> component restpath=/random rest=true {
</tr> } 20. Admin configuration
The REST resources need to be defined and mapped in
14. Handle updates 17. Initial GET Request the Lucee administrator. Log in to the web content
Back at the top of index.lucee we will add another Now we will define the routes and responses for each admin and select Archives & Resources>Rest. Create a
conditional statement within the script block. This API resource within the open component block. First lets new mapping virtual name (use api for brevity) and point
conditional statement will check for a form update create a new remotely accessible function that responds the physical to the directory location of the components.
submission and it loops over the tasks array, setting each to a GET request. This simple example returns a random
to incomplete. After that, it will then loop over the number nested inside of a JSON response. The function 21. Test POST submission
submitted tasks (using the checkbox ids) and set those name has no direct impact on the resource, but ideally it Create a test lucee file in the project root to test the API.
tasks to complete. should relate to the purpose of the function. Create a new script block and make an HTTP POST
request to the local API address. At least one of the http
if ( form.keyExists('update_tasks') ) { remote any function getRandomNumber() param lines, set as a form field, should be the value
strTasks = ""; httpmethod="GET" { expected by the method. Finally dump out the cfhttp
for( task in application.tasks ) { return {'random_number': result for visual debugging.
task.setComplete(false); randRange <:script>
if ( structKeyExists(form, 'task') ) { (1,1000000) }; http url="http://localhost:8888/rest/api/
if (listContains(form.task, task.getId())) { } random/" method="POST"
task.setComplete(true); {
} 18. Manage URL parameters http param name="posted_value" value="Lucee
strTasks = form.task; Create a new GET resource function in the component is powerful" type="formField";
} to accept a single argument or parameter. The }
} restargsource attribute dictates that the argument will be dump(cfhttp);
application.completeTasks part of the path and we define the argument value as </:script>

59
:HE'HVLJ
The:HE'HVLJAnnual

A customisable text editor for the 21st Century.


Find out how to make it what you want
// Atom: the hackable text editor

Getting started with the Atom editor


THE DEFAULT INSTALL OF THE EDITOR PRESENTS A HOST OF HELPFUL RESOURCES

Atom is fully Packages are used to


documented, providing expand the feature set
an in-depth manual for of the editor. They can
normal users of the be searched for,
editor, to a detailed look configured, installed
at the editors internals and upgraded, all from
for those who wish to within the Atom
change the very core of editor itself through a
the editor itself. simple interface.

The core keyboard


shortcut to learn for By default, the editor
Atom is Cmd/ sports a dark theme. If
Ctrl+Shift+P. It will this isnt to your liking
toggle a small window though, you can select
called the Command lighter alternatives for
Palette, which contains the UI and syntax.
every Atom command Theres also the option
available and displays of searching for more
their shortcut if they themes from the
have one. Atom community.

GitHubs Atom editor, built for the web


BUILT ON THE WEB TECHNOLOGIES FOR MAKING WEB-BASED APPS
The Atom editor originally started life back in 2008, much more powerful than the JavaScript that can be
as a side project from one of GitHubs founders, Chris found in web browsers, as it takes advantage of the
Wanstrath. Atom was born from his desire to create Node.js project to provide a powerful API for accessing
an editor that was flexible, easy to customise and built the filesystem, networking and much more. This also
on top of web technologies. It wasnt until a few years includes the possibility of using over 170,000 (at the
later though, in 2011, when Atom was picked back time of writing) modules that are provided
up by GitHub and subsequently taken on through Nodes npm.
as an oficial project, and thats when Markdown All of this efort has created a
work on it really started to progress. support cross-platform editor, which at this
Work went on behind the scenes Atoms Markdown support, point includes all of the normal
and whilst that happened, web enables you to create and features that youd expect to find
technology in general improved to preview Markdown-based docs. such as syntax highlighting,
the point where it was viable to Cmd/Ctrl+Shift+M splits the editor autocomplete, searching files,
release the project publicly as a view with a side-by-side of your multiple view panels, multiple David Boyer
beta version in early 2014. A year Markdown and cursors, project support and much, Senior software developer for NHS
and a few months later, in June 2015, the HTML. much more. The appearance of the Wales Informatics Service
version 1.0 was released. editor is very flexible as well, with the The ability to have an editor built
The editor is built upon a range of familiar overall look and the syntax highlighting using familiar technologies makes it
web technologies. At the heart of GitHubs Atom is both supporting themes, of which there are almost possible for me to customise it to
Electron, which uses Chromium as a base (the open 800 that are already available to use. There is also my needs. It enables me to take full
source core of Googles Chrome browser) and support for packages, with over 2,500 available for advantage of the JavaScript power
provides rendering of HTML, CSS and JavaScript as a expanding the editor in a multitude of ways. within the editor.
stand-alone desktop application. The JavaScript is

feature______________________________________________________________________61
:HE'HVLJ
The:HE'HVLJAnnual

Which languages
are supported?
How to theme Atom
ATOMS APPEARANCE IS STYLED BY CSS AND THE COMMUNITY HAVE
COMBINED WITH THE PACKAGES PRODUCED OVER 700 THEMES TO CHANGE ITS APPEARANCE
AVAILABLE, ATOM BECOMES A Themes in Atom are built upon the Less.js (lesscss. easily install and configure, all from within the Atom
MORE COMPLETE TOOL org) library, which is a JavaScript-based editor itself.
preprocessor for CSS. Less adds to CSS variables, These themes can come in two diferent types,
JavaScript mixins, functions and various other syntax features syntax and UI but theyre pretty straightforward.
With Atom being built on top of JavaScript, youd that can help to make CSS considerably more Syntax themes are focused on the area that is
expect it to be well supported. Packages such as manageable for you. displaying your code (or other file types) whereas UI
linter and linter-jscs can add code analysis tools This library has enabled the Atom community to themes are focused on altering the appearance of the
(linters) to catch common issues or mistakes. build up a large amount of themes which you can whole editor interface.
Turbo-javascript provides a raft of commands and

Less adds to CSS variables, mixins,


snippets to make writing ES6 JavaScript quicker.

PHP
PHP doesnt miss out on further support through
functions and other syntax features that can
packages. To complement the built-in syntax
highlighting, php-cs-fixer can be installed to
maintain your coding standards. For Atoms
autocomplete feature, install autocomplete-php
and standard PHP functions will list as you type.
help to make CSS more manageable
Discovering
Finding an Atom theme is easy. All you have to do is

File>Settings>Install from the menu. Here you can
enter the name of the theme that you wish to install,
simply proceed to the Atom theme site (by going to being sure to select Theme instead of Packages, or
CSS atom.io/themes) and youll be presented with a search for other themes. Simply click the install button
CSS gets the standard level of support from Atom directory of published themes. This collection and Atom will retrieve it.
with interesting packages from the community. includes some which have been selected
Pigments detects colour declarations and to be featured, the newest, most Chromium Selecting
displays it as a background to the text and recently updated and lists of those developer tools Within the File>Settings>Themes
linter-css checks for common mistakes. Support which have trended (by popularity) You can take a peak under menu, youll find two drop-down
is also available for preprocessors like Less. for the previous day, week or the hood of Atom by using lists of UI themes and syntax
month. As mentioned previously, a Opt/ Alt+Ctrl+I or themes that you have installed,
HTML theme will be either for the UI or View>Developer>Toggle with the currently used ones
Emmet wraps a popular tool to enable writing the editor syntax. Some themes can Developer Tools to explore the selected for you. Selecting another
HTML as CSS selectors, being expanded into be more playful, like one inspired by HTML and access theme will apply it to the editor and
actual HTML by simply tabbing after typing your Batman or you can have a more JavaScript. some themes also allow customisation,
selector. Html-entities will handle encoding and serious Material Design-based theme. presenting a cog item for you to access
decoding of special characters, autoclose-html their settings.
helps with closing your tags as you type and Installing The menu can also provide a list of themes that you
various linters can check the HTML correctness. Once youve found a theme to your liking, simply go have already installed, with the ability to remove them
back to your Atom editor and access if desired.
Go

A bigger, better Atom


As a language developed by Google in 2007, Go
has received some decent attention recently.
Go-plus provides access to the powerful toolset
that Go provides from within the editor: gocode to
power the autocomplete, gofmt to tidy up your ATOM IS A VERY EXTENSIBLE EDITOR THANKS TO PACKAGES
code, goimports to add and remove imports With the package count for Atom exceeding 2,500, which provides a search input box. Type the name of
automatically and golint to check for common there is no shortage of interesting additions you can the package you wish to install or keywords for
code issues and even building or testing code. add to your editor. something you would like to do. Youll then be
presented with a list providing a description, download
Node.js Package installation count, version, link to the webpage of that package
While Node.js uses JavaScript, which has already Under the menu File>Settings, youll find a Packages and an installation button.
been detailed, there are additional packages item. This provides a list of all the packages you have
available that provide even deeper support. For installed and ones that were included with Atom by Access the packages
example, Node-debugger hooks into the debug default (core packages). Here you can access any While this primarily depends upon the way the
support that Node has with Atom and displays the settings a package may have or disable/uninstall package was written to work, there are a few places
active line and allows execution control. them. For installation, proceed to the Install section that a package will present itself. The menu at the top

62
62_____________________________________________________________________feature
// Atom: the hackable text editor

of the Atom editor contains a Packages item that packages can provide actions under. They will also usually
add themselves to the Command Palette, so just use Cmd/Ctrl+Shift+P to bring up the palette and then type Check your code
the name of the package to filter the list and display the commands for it.
Finally, keyboard shortcuts are usually created, but these will be unique to USE LINTING TO AVOID BUGS
each package and best found by reading the documentation for it. OR BAD PRACTICES
Customising Having your code checked as you type can
Discovering packages shortcuts save a lot of time that would be lost to
Going back to the Install area for You can view keyboard shortcuts packages within Atom, you common mistakes. Atom has a package called
should see an area listed for via File>Settings>Keybindings. This Featured Packages. This is a list linter that provides that base package for
featuring some of the favourite will display a searchable list and also packages from the Atom checking a range of languages.
community. If you check out provide a link to the file in which the Atom website (atom.io/ Linter-jshint uses the JSHint project to
packages) you will find lists of you can define your own. packages that have been perform an analysis of your code. JSHint will
trending over the past day, week and month. This is a fantastic place to highlight syntax mistakes that would prevent
find out which packages are suddenly becoming popular with other your code from executing and highlight
developers in the field. suspicious usage of JavaScript that are bad
Finally, the Atom website also has a blog which contains posts doing a new package roundup. practice and even basic code styling. These
They pick several new packages that have interesting features and showcase them with fuller descriptions checks are all configurable and once installed
and screenshots. are highlighted and listed at the bottom.
Another package to complement JSHint is
Package performance linter-jscs. JSCS concerns itself with the style of
If Atom is starting to feel sluggish or takes a long time to open, its worth considering the packages that you JavaScript code, helping to ensure that you
have installed recently. code consistently. Companies like Google and
A package that Atom includes by default is called Timecop and accessed via the Packages menu. It Airbnb have produced JavaScript style guides
displays the loading and activation time of each installed package. which JSCS can help enforce.

feature_____________________________________________________________________63
:HE'HVLJ
The:HE'HVLJAnnual

Working with Grunt


USING A PACKAGE TO TAKE
CONTROL OF GRUNT TASKS
Grunt is a very useful tool for configuring sets of tasks that assist with the work youre doing with your
application. Through the use of a configuration file (Gruntfile.js) and various Grunt plugins you can
perform a variety of tasks: optimising images, checking code quality, running a server, filesystem actions
(copy, move), converting ES6 JavaScript to ES5 and much more.
If youre new to Grunt, their website has a great tutorial that shows you how to set up an example
Gruntfile (gruntjs.com/getting-started). After youre done running through this youll have some tasks
available for Atom.
Through installing the grunt-runner package into Atom, you can now gain access to an in-editor UI for
controlling your Grunt tasks. Using the Command Palette (Cmd/Ctrl+Shift+P) you can bring up the UI by
typing grunt panel, which then provides you with a button for firing of grunt tasks. When you do click the
start button, grunt-runner will display a list of tasks
that is found within your Gruntfile, and this will
enable you to either type the name, click to select or Atom Editor
navigate by using the arrow keys. It then fires of the @AtomEditor
tasks and logs the output to the UI, providing The Twitter account of the Atom editor. Allows
feedback as to the tasks being executed. you to keep up to date on each release, blog post
and highlights useful packages.

How to create a syntax theme


FOUR SIMPLE STEPS TO DISPLAYING CODE

1. Theme package files 2. Dev Mode Atom


Atom provides a built-in method for generating the initial files required. Itd be useful to see theme changes when saving a file. To do this set Atom to
These can be generated with Packages>Package Generator>Generate use your theme with File>Settings>Themes>Syntax Theme and open the
Package Syntax Theme. Enter a path and generate the files. theme folder via View>Developer>Open in Dev Mode.

.variable { cd ~/github/my-theme-syntax
color: lighten(green, 20%); apm publish minor
text-decoration: underline;
border: 1px solid green;
padding: 2px;
} 4. Share the theme
Once youre happy with the syntax theme that youve created, you may
decide that its worth sharing it with others online so that more people can
3. Less CSS reap the benefits. A command-line tool, provided by Atom, called apm, is
A form of CSS known as Less is used by Atom, which can also accept normal used for this very purpose. Before you share though, you should know that its
CSS as well as providing us with some very useful additions. Three of the important to make sure that the information contained in the package.json file
core Less files for your theme are contained within the styles subdirectory. So is correct, so do make sure that you read through the documentation at
now, lets change how variables are styled by opening up base.less and atom.io/docs/latest/publishing-a-package first before going on to share the
finding .variable. themes with others.

64
// Atom: the hackable text editor

5 Must-have Create your own package


extensions A PACKAGE TO POST HIGHLIGHT CODE FOR SHARING ON GITHUB
Initialise
Customisation is at the heart of Atom and as weve
MAKE ATOM AN EVEN BETTER already detailed, there are plenty of packages Within lib/my-package.js we can initialise the package.
CODE EDITOR available to extend the features of Atom. These Request will be used within our package and shell is
packages are written using a well-documented API part of Atom that we will use to open a link in the
Minimap which can control the editors various aspects. browser. Then register our command with Atom.
atom.io/packages/minimap var request = require('request');
Adds a thin additional column to the editor The package generator var shell = require('shell');
window that provides a preview of the full file With Atoms package generator, used earlier to var activate = function() {
contents. This can then make it easier to scroll to create a syntax theme, we can create the atom.commands.add('atom-workspace', {
specific code. base files needed for a normal package. 'my-package:create': function()
Select Packages>Package Contribute to {create();},
Git-plus Generator>Generate Atom Package packages });
atom.io/packages/git-plus and enter a location for the files. Its worth checking if a };
Source control is important and this package Theyre written in CofeeScript, but package exists through atom.io/
provides access to Git for that purpose, all from plain JavaScript can be used. packages. You may be able to Gist
within Atom so you dont have to leave the editor. contribute any changes you Now our main code, which grabs
Dependencies require, if the author is the selected text in the editor
File-icons Within the package.json alter the willing to accept them. window, submits to GitHub as a Gist
atom.io/packages/file-icons activationCommands, which tells Atom and opens posted code in your browser.
Improves the filetree view and other areas within how to execute our package and the var create = function() {
Atom by assigning colourful icons to diferent file dependencies that include a module well require. var editor = atom.workspace.
types, making it easier to see the type at a glance. "activationCommands": { getActivePaneItem();
"atom-workspace": "my-package:create" var selection = editor.getLastSelection();
Merge-conflicts }, var options = {
atom.io/packages/merge-conflicts "dependencies": { url: 'https://api.github.com/gists',
When merging branches in Git, conflicts can "request": "^2.6.0" headers: {
occur with the changes. This package provides an } Accept: 'application/vnd.github.v3+json',
in-editor: a simpler way to resolve those conflicts. 'User-Agent': 'Atom Package Gister',
Menus and shortcuts },
iMDone Our new package will be accessed by right-clicking in json: true,
atom.io/packages/imdone-atom the editor and through a keyboard shortcut. These are body: {public: true, files: {}},
Looks throughout your projects code for set within the following files: };
comments marked TODO, FIXME and others. It // keymaps/my-package.json options.body.files[editor.getTitle()] = {
then takes this information and provides a {"atom-workspace": {"ctrl-alt-o": "my- content: selection.getText(),
kanban-style board. package:create"}} };
// menus/my-package.json return request.post(options, function(err,
{"context-menu": { resp, body) {
"atom-text-editor": [{ shell.openExternal(body.html_url);

Beautify code "label": "Create Gist",


"command": "my-package:create"
}]
});
};
module.exports = {activate: activate, create:
CLEAN UP CODE MESS }} create};
Sometimes code you encounter may not be in a
very readable state, either through the way it was
written or having been put through a
minimisation process to reduce file size. This is
where atom-beautify comes into play, while it
Git and Atom Command Palette or Packages>Git Dif, you can access
a list of these modifications and jump between them.
If youre hosting your code on GitHub, the built-in
wont reverse any obfuscation, it will work its way USING GIT-BASED SOURCE CONTROL Open on GitHub package will provide many useful
through the code and insert new lines, spaces Since GitHub is behind the Atom editor, youd expect it shortcuts. The Atom community has also put together
and indentation to try and make every line to support Git in some way. By default, Atom provides packages like Git-Plus useful for providing access to
readable again. You can do this through either the a useful insight into changes youre making to a file certain Git commands from within Atom, avoiding the
Packages>Atom-Beautify menu, using Cmd/ when compared to what Git has recorded. Along the need to switch to a terminal to commit changes.
Ctrl+Alt+B or calling up the Command Palette side of the editor window, lines in the file will be Merge-conflicts provides a UI within the editor to deal
though Cmd/Ctrl+Shift+P and typing Beautify. highlighted green if they are completely new lines or with conflicting changes straightforwardly when
yellow if considered a modification of a line. Via the merging code branches in Git.

65
:HE'HVLJAnnual

Create desktop
applications with
Electron
Use pseudo elements HTML, CSS and JavaScript to create
cross-platform desktop applications

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Create desktop applications with Electron

G
itHub have created an open source which will display a standard message for the application window = null;
project called Electron (formerly just ignore this message for now and close the window. });
Atom-Shell) that combines Chromium, $ electron });
on which Googles Chrome is built, and
Node.js, a JavaScript environment designed for 3. Use package.json 5. Test the app
building applications. The result enables the building of Package.json is required for Electron to know which file To enable us to test the application so far, a HTML file
cross-platform desktop applications using HTML, CSS to execute for the application. It will also store the name can be created containing some simple HTML for now.
and JavaScript. Companies such as Microsoft, Facebook, of your application and your version, and npm will add After adding the code below, execute the command
Slack and more have started to make use of Electron. the details of any modules that you install and use. In this electron ./ within the same directory as the package.json
Electron applications normally start out with a single tutorial, the application will be used for editing file created earlier.
JavaScript file which is executed initially. The code within Markdown-based files. <html><body>
it has control over the main process, can create and { <h1>Hello World, from Electron</h1>
control new application windows and listen for important "name": "wdMarkdown", </body></html>
events. Each window that is created can be set to render "main": "index.js",
your UI through the use of HTML, CSS and JavaScript. "version": "0.1.0" 6. Install Bower
The JavaScript executed within a window can also access } Our application has a few dependencies for the UI that
special Electron APIs and the Node.js API. will be constructed. By installing Bower, these
The Chromium part of Electron is also kept up to date 4. The application and index.js dependencies can be easily retrieved along with
with the latest releases, enabling use of the latest HTML/ The index.js file is the core of the application and will anything else they may require and Bower could be
CSS features and emerging JavaScript standards. The create our first application window to display the used to keep them up to date.
Node.js environment is also well maintained, to the point application. Depending on the type of application being $ npm install -g bower
where its currently using a fork of Node.js called io.js, developed, this file will usually contain the core of your
which is capable of supporting ES6 JavaScript syntaxes application and do all the heavy lifting required. By using 7. Bootstrap framework
and can make use of npm registry modules (npmjs.com). the app object, we can find out when Electron is ready, In order to have something to display, a UI needs to be
and a browser window (appearing as a normal created using HTML and CSS. As a base theme,
1. Prebuilt Electron binaries application window) can then be created.
Compiling Electron from scratch isnt required for var app = require(app);
building applications. The project makes available var BrowserWindow = require(browser-
precompiled versions of Electron for multiple operating
systems, which can be easily installed using Node.js npm
window);
var window = null;
Desktop applications
For fuller and more complex applications,
package manager (available via nodejs.org). app.on(ready, function() { consider using npm modules (more information
$ npm install -g electron-prebuilt window = new BrowserWindow({width: 800, is available at npmjs.com) for databases,
height: 600}); network communications and more, plus a
2. Test Electron window.loadUrl(file:// + __dirname + / framework for your UI from the likes of React,
AngularJS, Backbone.
Electron should now be available on your system. This root/index.html);
can be confirmed by running the electron command, window.on(closed, function() {

Left
By using the view menu we can have the editor switch
between viewing the original Markdown content and a
rendered HTML version of the content as a preview

Top left
Here is the final UI HTML page. Its primary purpose is to
include all the JavaScript files needed to construct UI,
Bootstrap for the appearance and our main JavaScript file
Top right
Here is what the application will look like when editing a
Markdown document. The tab shows the title of the file,
and the editor contains the raw Markdown content

67
:HE'HVLJ
The:HE'HVLJAnnual

Bootstrap can be useful as it provides many useful issue with jQuery being unsure what kind of environment var ipc = require('ipc');
components and styles. More advanced applications it is operating within when inside Electron. var files = {}, rollingId = 0;
may take advantage of AngularJS or React as well. By var tabs = $('#fileTabs'), panes =
using Bower to retrieve a copy of Bootstrap well also 11. Styling $('#filePanes');
have a copy of jQuery included as its required. The Markdown editor being constructed will provide an var ActiveTab = function() {
$ bower install bootstrap edit area for altering the content and a preview of the return id = tabs.find('.active a').
HTML generated. As the app will be kept simple, the attr('href').slice(1);
8. Markdown rendering editor and preview areas will fill the application, minus an };
The app will be used for editing Markdown files. area for tabs to switch between files.
Markdown is a widely used markup language used for .editor, .preview {position: absolute 14. FileNew function
writing formatted text in a plain text file. It can then be !important; top: 58px; right: 0; bottom: 0; To create a file or handle opening an existing one, our UI
processed by a library such as Marked into HTML. left: 0; z-index:5;} needs to create a new tab and pane, as well as set a
$ bower install marked .preview {display:none; overflow:auto; relevant title and content. We will use FileNew for this.
z-index:10; background-color: white;}
9. Edit Markdown with Ace 15. Use Ace
The Ace editor project is a feature-packed code editor 12. Make the tabs With the tab, pane and content now ready, its time to fire
thats written in JavaScript and can be used within web Bootstrap provides the styling and JavaScript required to Ace editor into action. Then we can store some
pages. For this tutorial, we will be utilising Ace editor for provide the tabbed interface used for the application. information for easier referencing and switch to the
editing the Markdown files as it can provide us with Each tab will represent a file and clicking between them newly created tab.
things like line numbering, syntax highlighting and other will display a related editor or preview. For now, we only
very useful features. need very basic HTML as well build the tabs and related 16. Menu events
$ bower install ace-builds panes using JavaScript. Now we execute the FileNew function once, present a
<div role="tabpanel"> new file tab on opening, and then listen for menu events
10. Include Bootstrap and JS <ul class="nav nav-tabs" id="fileTabs"></ul> sent from the main application process. The menu
Next, make use of Bootstrap, Ace editor and Marked by <div class="tab-content" id="filePanes"></ events, which well create soon, are for creating a new file
including them in our index.html file. Make note of the div> and opening an existing one.
alternative way jQuery is included, which is due to an </div> FileNew();
ipc.on(file-new, FileNew); ipc.on(file-
13. root/app.js open, FileNew);
This file will hold our main UI code. Using the ipc module,

Debugging Electron it can subscribe and publish events for communication 17. Menus
with the main JavaScript process, that Electron executes At this point, our Electron app should start up and
To debug any window you have created using
Electron, call the .openDevTools() method on the (./index.js). Well need to identify files edited and store present a fresh new tab to edit content in. However, we
instance of that window. This will open a additional information, plus references to the tab and cant open any more or save anything we create. So in
developer tools window. pane areas of the UI. Also, we will need a small function this case, a menu is required and itll be built within the
to grab the ID of the currently active tab. main ./index.js file. The fs and path modules from Node.

Top left
Microsoft have recently released their own editor, built
on top of Electron, called Visual Studio Code

Top right
Atom is GitHubs programming editor and is where
Electron started out as part of the project
Right
The final version of the editor, showing the multiple tabs
and some Markdown formatted content

68
// Create desktop applications with Electron

Packaging
applications
Through Electrons
crash-reporter module,
you can configure your
application to let users
submit crashes to a
website under your
control. Your application
code can also be archived
into a more protective
ASAR file, before being
distributed. This requires
use of the asar command
installed through npm;
npm install -g asar.
Electron currently only
supports autoupdating on
OS X through its
auto-updater module. But
theres no reason why you
couldnt implement a
check against a URL for
newer versions of your
app and then notify the
user. GitHub provides
prebuilt versions of
Electron at github.com/
atom/electron/releases.
Your app code can
combine with these
releases and redistributed.

js will be used for handling files. Dialog and menu ]; if (err) return console.error(err);
provide opening/saving dialog boxes and an application Menu.setApplicationMenu(Menu. });
menu bar. buildFromTemplate(template)); }
/* Below window = null */ dialog.showSaveDialog(window, {
var fs = require('fs'), path = 18. Open a file filters: [{
require('path'); Within the ./index.js file, we can now add a function name: 'Markdown', extensions: ['md',
var ipc = require('ipc'); (already referred to in our menu) to show a dialog 'markdown']
var dialog = require('dialog'), Menu = (provided by Electron), open the file and pass the data }]
require('menu'); back to our UI for display. At this point, executing our app }, function(filepath) {
/* Within app.on(ready) */ will provide us with a menu where we can open a new if (filepath && filepath.length > 0) {
var SendEvent = function(name) { file and have it displayed in our editor. fs.writeFile(filepath, data, function(err) {
return function() {window.webContents. if (err) return console.error(err);
send(name);}; 19. Pass file data window.webContents.send('file-saved', id,
}; Saving a file requires a few more steps. When the save/ path.basename(filepath), filepath); });
var template = [ save as menu item is clicked, we send an event to the UI. } });
{label: 'File', submenu: [ The UI holds the data that were going to save, so it must });
{label: 'New', click: SendEvent('file- listen for those events and send the data back to the
new')}, main process for us to display a dialog and create/update 21. Rendering
{label: 'Open', click: OpenFile}, the related file. Markdown is great for quickly producing text and
{label: 'Save', click: SendEvent('file- indicating how its formatted, but its more useful when
save')}, 20. Write a file you can see how it looks when its rendered. Our menu
{label: 'Save As', click: SendEvent('file- Our UI is sending a file-save event back to our main contains an option to switch to a rendered view so our UI
save-as')}, process (./index.js), providing the reference ID, content needs to listen for it, grab the editor content, pass it
{label: 'Close', click: SendEvent('file- and path (new files dont have one). Well need to listen through marked for conversion and output it for display.
close')}, for this event, saving the file directly if a path is provided
{type: 'separator'}, or prompting for a location (save-as) first before creating 22. Closure
{label: 'Quit', click: function() {app. or overwriting a file with the content. Now we need to close a tab. Listen for the menu event
quit();}} ipc.on('file-save', function(evet, data, id, within the UI, and after that its just a matter of having the
]}, {label: 'View', submenu: [ type, filepath) { editor clean itself up, and remove the tab and pane
{label: 'HTML/Markdown', click: if (filepath) { elements. Finally, switch to another tab if one exists. For
SendEvent('view-toggle')} return fs.writeFile(filepath, data, the full code in this tutorial, make sure you go to filesilo.
]} function(err) { co.uk/webdesigner.

69
The:HE'HVLJAnnual

Build desktop apps


with NW.js and
JavaScript
Use NW.js to create JavaScript-powered desktop apps that can be
run on OS X, Linux and Windows

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Build desktop apps with NW.js and JavaScript

1. Get NW.js

O
ver the last 25 years, the browser <!DOCTYPE html>
has opened new windows (see what Installing NW.js is pretty simple, all we need to do is head <html>
we did there) on content and code on over to GitHub (github.com/nwjs/nw.js) and grab the <head>
distribution. Whole ecosystems have build for your OS. If we were so inclined we could build <meta content="text/html; charset=utf-8"
sprung up to support the creation and deployment of NW.js from scratch, and that may be advisable if you want http-equiv="Content-Type">
apps that can be accessed with a simple URL. Despite to be certain of stability, but for learning, the prebuilt <title>To Do</title>
how great the browser has become at integrating itself binaries will do. For this tutorial the 32-bit release of NW.js <link rel="shortcut icon" href="favicon.
into operating systems, we still sometimes find that we 0.12.1 was used and tested on OS X 10.10.3. ico">
want an app that we can install on our system and run at <link rel="stylesheet" href="styles.css"
any time with just that extra little bit of power. 2. Relocating the NW.js executable type="text/css" />
What we need is something with the low-level access Unzip the package we just downloaded. It contains the <meta name="viewport" content="initial-
of Node with the ease of development of browsers and a prebuilt NW.js executable that we can use to run our scale=1.0, user-scalable=no" />
way to package it all up as an app that can be run on our apps. When we get to testing and deploying our apps, </head>
traditional OS like any regular, native app. Thats what well use the nwjs app bundle included in this folder, so <body>
NW.js (formally known as Node-WebKit) is. NW.js bundles move the entire folder to a safe, memorable place.
io.js and the WebKit browser engine together in a way
that lets us access the full power of Node through the 3. Create a NW.js project
DOM. This then enables us to write web apps and also to
run them in self-contained windows that look almost
NW.js apps are supersimple with few prerequisite
dependencies, so theres no need for a project creation
Compiling code
There is no compiling per se in NW.js, which
exactly like OS native apps. tool like those found in, say, Cordova. Create a new folder means that you may want to keep your source
In this tutorial, were going to set up NW.js and create a somewhere on your system and create a HTML file code from prying eyes. There are ways to make it
simple to-do app to show how simple it is to write native called index.html and insert the code below. This will quite hard to get at your source, documented on
apps with JavaScript and NW.js. We will be doing this for make up the UI of our app and load the NW.js code to NW.js GitHub wiki (github.com/nwjs/nw.js/wiki).
Mac OS X. handle the creating of our window.

Left
We dont want to have to bundle things every time we
want to test our app. Instead, we can point the NW.js
binary to our project and run it in terminal

Top left
When we first run our app, it looks a lot like a browser. We
will need to tweak the manifest file
Top right
Once weve adjusted our manifest properly, our app starts
to look a lot more like it belongs on our system

71
:HE'HVLJ
The:HE'HVLJAnnual

To make our app look a little more like


<h1>Hello World</h1>
</body>
</html> it belong, we can remove certain
4. Create the manifest
Just like an io.js app, NW.js uses a JSON manifest to get
the wheels rolling with our app. Create a file called
package.json in the same folder as your index.html. This
is the root of your NW.js, all URIs are relative to the
elements with our pack.json manifest
our case its index.html. There are other properties that
can afect how our app runs, but for now add this::
{
$ nwjs.app/Contents/MacOS/nwjs /path/to/
your/project/root.

package.json file. "title" : "To Do Today", 8. First impressions
"main" : "index.html" A new window will have opened and a NW.js icon will
5. A simple manifest } have appeared in your dock. Were running our first
Open up your new manifest file. The simplest manifest NW.js app, and we can see our HTML file but it still
requires two properties, a main and a title. The main is 6. Point the app looks like a browser window. To make our app look a
the file that our app will launch when its first run, so in When were testing out our app, we shouldnt have to little more like it belongs, we can remove certain
package and repackage it every time we correct code. elements with our package.json manifest.
We can use the NW.js executable to run our app by
pointing it to the root of our project. Open up a terminal 9. Enhance our manifest
Node-webkit and navigate to the folder downloaded from GitHub. Weve got some system chrome we need to get rid of
now! Just after the main property of your manifest, add
NW.js is, in essence, Node WebKit. The name
change accompanied the migration of the project 7. Launch our app a window object and add the following properties to it:
from Node.js to io.js. Rumour is, all the cool kids The NW.js executable is buried in the NW.js app in our {
call it n-dubz for short enn-double-you-dot-jay- folder. The executable is the program where the io.js and "title" : "To Do Today",
ess is such a mouthful. NW.js code lives. With NW.js, we dont change the app, "main" :
we create projects that run with it. To run the app, enter: "index.html"

Top left
When we position our window with code, the top-left
corner is positioned relative to the top and left

Top right
We need to navigate the hierarchy to package our NW.js
app properly
Right
Making ICNS files is a bit of a pain, fortunately Image2icon
has us covered, but only if you distribute your app on OS X

72
// Build desktop apps with NW.js and JavaScript

Node modules
NW.js is, in part, io.js. That means that you can use modules! Well, at least in principle you can anyway. NW.js can run on any of the
major platforms, but just like a native app, your packaging process will of course vary depending on the operating system that youre
actually targeting. You cant run an EXE on a Mac, just like you cant mount a DMG on Windows for example. If you want to make use
of io.js modules that use a language other than common JavaScript, then its very likely that you will have to compile your package on
the system that youre targeting. That being said though, if youre only using Node modules written in common JavaScript (like the
fantastic moment.js module, for example), they should work straight out of the box.

"window" : { window is the width and height we defined. All thats left type="text/css" />
"toolbar" : false, of the system chrome are the close, minimise, maximise <meta name="viewport" content="initial-
"frame" : true, and title. We can remove these too, but theyre handy for scale=1.0, user-scalable=no" />
"width" : 480, UX purposes, so well leave them in. </head>
"height" : 320, <body>
"show" : true, 11. Add scripts <ol id="list">
"resizable" : Its time to start putting the component parts of our GUI </ol>
true together. Open up index.html and amend it like this: <div id="UI">
} <!DOCTYPE html> <div id="delete" class="button">
} <html> </div>
The window object afects how our window behaves. We <head> <div id="add" class="button">
can remove the frame, define height, make it persistent <meta content="text/html; charset=utf-8" </div>
in all workspaces, but for now these properties set us up. http-equiv="Content-Type"> </div>
<title>To Do</title> <script src="scripts/core.js"></script>
10. Create our GUI <link rel="shortcut icon" href="favicon. <script src="scripts/window.js"></script>
Now if you repeat Step 7 when our app launches, you will ico"> </body>
see that we no longer have the URL bar and that our <link rel="stylesheet" href="styles.css" </html>

73
:HE'HVLJ
The:HE'HVLJAnnual

The app logic isnt what were focusing


This is the markup for our list. The app logic isn't what
we're focusing on, so we wont write core.js or styles.css
from scratch, you can download them from FileSilo.
on, so we wont write core.js or styles.css
12. Access NW.js globals
Well now write window.js to ease into NW.js coding.
Create a folder called scripts in your root folder and a file
called window.js in it. Here, were going to afect the app
window with events and listeners for that native feel.
you can download them from FileSilo
more at home. OS X for example has the menu bar with
the About and Edit dialogs that are currently missing.
Adding the following to window.js will adjust our to-do

Now when our app loads, the scripts will be initialised
and will only show once scripts have finished loading.

apps menu bar with more relevant information. 16. Position the window
13. NW.js GUI and windows var nativeMenuBar = new gui.Menu({ type: When the app is ready we can position the window.
Just like a Node app, we can use require() to access node "menubar" }); When we open a native app on OS X its generally at the
modules and NW.js globals. In order to manipulate the nativeMenuBar.createMacBuiltin("ToDo", { same x and y coordinates as when you closed it. We can
properties of the window and listen to events, we need // hideEdit: true, reproduce this, just insert the following before win.show():
to require the GUI module from NW.js and abstract the hideWindow: true var initialPosition = {
window away from it. Insert the following into window.js: }); top : 50,
var gui = require('nw.gui'), left : 50
win = gui.Window.get(); 15. Hide our window };
When our app loads, we see a quick flash of white before var savedPosition = JSON.
14. The menu bar the content of our page is loaded and initialised. In parse(localStorage.
NW.js is platform agnostic, but there are small OS tweaks package.json change the value of show to false instead getItem('windowposition'));
we can make for each platform that make the app look of true. In window.js add win.show(); to the end of the file. win.on('move', function(){

Node.js and io.js, Whats going on?


Node is backed by a company called Joyent this has been great for many reasons, but a lot of people have felt that the speed at
which new JavaScript features and optimisations are being integrated into Node is too slow. These feelings led to io.js a fork of the
Node source code, but maintained entirely by the community. Io.js started to implement new features (like ES6 syntax) straight away,
and with the benefits of a rapid-release cycle being well known to the developer community, many projects, like NW.js, migrated to
io.js. Now, Joyent and the guys in charge of io.js have agreed to merge all of the changes in io.js back into Node.js and release and
develop Node under the newly created Node Foundation.

74
// Build desktop apps with NW.js and JavaScript

localStorage.setItem('windowposition', if(savedPosition !== null){ is in the global scope, so it is still possible for us to access
JSON.stringify({left : win.x, top: if(savedPosition.left < 0){ it from our app and use DOM events to change its
win.y})); savedPosition.left = 50; properties even though its technically Node.js property.
}); } Then when we click on our padlock, we will work on
if(savedPosition !== null){ if(savedPosition.top < 0){ checking the window-is-locked data attribute on the
win.moveTo(savedPosition.left, savedPosition.top = 50; DOM element to get the windows current state. If our
savedPosition.top); } window isnt locked, then we can now use win.
} else { win.moveTo(savedPosition.left, setAlwaysOnTop(true) and win.setVisibleOnAllWorkspac
win.moveTo(initialPosition.left, savedPosition.top); es(true) to lock it and vice versa.
initialPosition.top); } else { win.moveTo(initialPosition.
} left, initialPosition.top); 22. Package our app
On our win object, which is the reference to the NW.js } If you run the app now, youll have a fully functioning,
window, we've added an event listener. Every time our if(savedSize !== null){ persistent to-do list. You can minimise it, close it and
user moves their window, the 'move' event is dispatched win.resizeTo(savedSize.width, savedSize. resize it. Now we need to package it. Go to the folder you
to win. When this happens, our callback is called and we height); downloaded earlier that was relocated to GitHub. Copy
can save the coordinates that the window has been } the NWJS.app file into the root of your project folder and
moved to in localStorage. Now, whenever we move our right-click it. Select Show Package Contents and
window, its coordinates will be saved in localStorage and 19. Click to lock navigate to Contents>Resources.
the window will be restored to its previous position. At the start of this tutorial, you should have downloaded
core.js from FileSilo and then included it in our scripts 23. Copy files
17. Negative numbers folder. Now, were going to add a little bit of code to it. In Open another Finder window and copy all of the files
If our user happens to have multiple screens and our our app, you should see an unlocked padlock in the weve created (index.html, styles.css, scripts folder,
app is positioned on one of them, when the screen is bottom-right corner of our window, it doesnt do package.json and all the others) into the newly created
unplugged our app could end up being stuck where we anything at all right now, but when were finished, it will app.nw folder. Now if you got back to your project root
cant see it! If our stored coordinates are less than 0, be a toggle for locking our ToDo app on top of all other and double-click NWJS, your app will be run by default.
were going to override the coordinates and place our windows so that it is visible across all of our workspaces.
window back on the main screen. Just after 24. Edit PLIST
if(savedPostion !== null){, add the following: 20. Create the ICNS file Our app still looks like a NW.js app. To afect some
if(savedPosition !== null){ Open up core.js for editing and scroll down until you find changes like the name and the icon, we need to change
if(savedPosition.left < 0){ the addEvents function and just before the end of that the apps PLIST file. Right-click NWJS again and select
savedPosition.left = 50; function, add the following: Show Package Contents and then navigate back to
} document.getElementById(lock). Contents. Open the PLIST file. If you have Xcode, it will
if(savedPosition.top < 0){ addEventListener(click, function(){ open its editor, otherwise you can modify it with any text
savedPosition.top = 50; var isLocked = this.getAttribute(data- editor. Change the Bundle name and bundle display
} window-is-locked); name to ToDo and save.
if(isLocked === false){
18. Resize the window win.setAlwaysOnTop(true); 25. Create ICNS
Just as our window is always in the same place that we win.setVisibleOnAllWorkspaces(true); The last touch to make any app look at home is the icon
left it, it should also be the same size right? Well lets do this.setAttribute(data-window-is- it uses. You can either create your own using something
this now. Were going to repeat what weve done with the locked, true); } else { like Image2icon or you can use the ICNS file included in
move event and localStorage, but this time were going win.setAlwaysOnTop(false); our files these are available for download from FileSilo.
to listen for the resize event instead. When our window is win.setVisibleOnAllWorkspaces(false); Just simply copy this into Content>Resources.
resized, well save the dimensions to localStorage. When this.setAttribute(data-window-is-locked,
we restart our app, well set the dimensions of our app to false); 26. Affect the changes
the dimensions stored. } The icon and name changes may not take efect straight
var savedPosition = JSON. }, false); away. You can relaunch Finder or you can change the
parse(localStorage. name of the .app in your project root to anything and
getItem(windowposition)), Now, if we restart our app and click the padlock icon, it then back to ToDo. Then the icon and bundle name
savedSize = JSON.parse(localStorage. will lock and if you click another window or move to should update.
getItem(windowsize)); another workspace, ToDo will still be on top for us to see.
win.on(move, function(){ If we click the padlock again, our window will stay on the 27. Distribute our app
localStorage.setItem(windowposition, workspace its currently on and will disappear behind any We now have a fully functioning, JavaScript-powered OS
JSON.stringify( {left : win.x, top: win.y other window that has focus. X app. You can now move the ToDo.app file anywhere
} ) ); on yours or anyone elses system and fire it up, just like a
}); 21. What did we just do? regular app. When running your app on other peoples
win.on(resize, function(width, height){ Our package.json file sets up how our window looks and system, they may need to tweak their security settings to
localStorage.setItem(windowsize, JSON. behaves when we first load it, but as weve seen with the enable your app to run. To do so, simply open System
stringify( {width : width, height : moving and resizing code we wrote a little earlier, we can Preferences>Security and Privacy and enable apps to be
height} ) ); override these properities with JavaScript if we want to, run from the Mac App Store with the toggle. Now, move
}); even after the window has been shown. Our win variable ToDo into your applications folder and give it a whirl.

75
The:HE'HVLJAnnual

Get robust JavaScript


code with the
TypeScript library
Structure your JS code more rigidly than ever before
with the help of Microsofts TypeScript

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Robust JavaScript code with TypeScript library

1. Install Visual Studio

J
avaScripts liberal syntax declaration lets <button onclick="btnClicked()">Button
developers do all kinds of weird and Even though TypeScript can also be run from the clicked</button>
wonderful things. Programmers used to command line, we will use Microsofts free version of </body>
restrictive class-based systems will need to Visual Studio 2015. Download it by visiting visualstudio. //snip
aquaint themselves to the new working environment. com/en-us/products/visual-studio-community-vs.aspx function btnClicked()
Google engineer Addy Osmani collected design and install it like any other application. {
patterns which helps this process when, and only when, alert("Hello TS");
applied correctly. Duck typing is even worse though: it 2. Create a project }
permits the creation of bugs which occur only when the Click New Project in order to open the new project
code path in question is executed. Murphys law then wizard. Then proceed to opening the TypeScript tab, 4. A question of typing
ensures that this will happen on the computer of an where a new solution based on the HTML application TypeScript takes its name from its incredible typing
important client. TypeScript solves these problems by with TypeScript template is to be created. It will contain capabilities. The snippet accompanying this step in the
creating a statically typed dialect of JavaScript which is an HTML file and an accompanying TS file containing the tutorial shows a few variable declarations. Be aware
verified via a more stringent execution environment. actual TypeScript code. though, that variables dont necessarily need to have a
Transgressions are punished mercilessly, defective code
never makes it to the browser. 3. Wire a button
Microsoft does its magic via a process called The following steps will demonstrate various features of
transpilation. A special compiler transforms the
TypeScript code to vanilla JavaScript, which can then be
the runtime via an ever-expanding method. It must be
triggered from a button open the HTML file and
Vetoing Microsoft
Developers harbouring a distaste for Visual
run in a JavaScript VM of choice. State-of-the-art append the markup shown in the source code Studio can use a Node-based transpiler to
JavaScript runtimes are so fast that they can be used as accompanying this step. Then, replace the window. transform their TypeScript code into JavaScript.
execution environment for arbitrary code some onload block in the TS file with the function specified. Sadly, doing so means missing out on various
developers even go as far as to transpile C++ to a <body> comfort features.
JavaScript-based VM. <h1>TypeScript HTML App</h1>

Left
Visual Studio Community combines the formerly separate
web, Windows RT and desktop versions of Microsofts
popular IDE

Top left
TypeScript code resides in TS files. Visual Studio
transforms them into temporary JavaScript during the
deployment of the web app
Top right
The transpilation process mercilessly weeds out all kinds
of errors which traditional JavaScript developers can find
only at runtime

77
:HE'HVLJ
The:HE'HVLJAnnual

type if any is specified, the variable in question will not furthermore, prevent deployment until any and all classes. Remove the declaration of the greeter class, and
be subject to input validation. objectionable passages have been remedied. then subsequently replace it with the following bit of
function btnClicked() code. Our AircraftManager class contains a member
{ 6. Create an enum variable, a member function as well as a constructor
var myString: String; If variables are to contain but a few predefined values, which is used to set its value during the initialisation of
var myNumber: Number; using an enum is the way to go. The snippet the object instance.
var myBool: Boolean; accompanying this step demonstrates the definition of class AircraftManager {
var myAny: any; an enum handling aircraft types. After that, a new myWhatAmI: Aircraft;
} instance of the enum is created and a value is assigned constructor(aWhat:Aircraft) {
in order to demonstrate its handling. this.myWhatAmI=aWhat;
5. Validation enum Aircraft { }
TypeScripts capabilities can be validated by assigning MIG21, sayHello() {
invalid elements to the variables created in the previous MIG25, alert("Hello");
step. Visual Studio will then flag them down the very MIG29, }
moment the file has successfully been saved. It will, MIG31 }
}
function btnClicked() 8. Spawn an instance
{ The process of pawning an instance is as easy as

The playground var plane: Aircraft;


plane = Aircraft.MIG25;
invoking the new operator on the class name, which can
furthermore be used as a variable type. By and large, any
Individuals adverse to both Visual Studio and
Node.js can visit the TypeScript Playground } objects that are spawned from TypeScript classes
(typescriptlang.org/Playground). It provides a behave just like normal JavaScript objects accessing
hosted version of the TypeScript transpiler. 7. Create a class their members and member functions via the . operator
For this next step, we will now start working on real is a non-brainer.

Top left
Thanks to inheritance, the BetterManager can easily
change the message that is displayed in its instances
sayHello() function

Top right
Invoking a generic function with an invalid parameter is
punished with yet another transpiler warning
Right
Using the private keyword permits developers to hide
implementation details from pesky callers that want to
wreak havoc in their code

78
// Robust JavaScript code with TypeScript library

Type Contains what


Any Accepts any JavaScript variable, thereby
disabling TypeScript type checking
Array An Array of elements
Boolean True or False
Enum An enumeration of numeric values, adressible
via their assigned names
Number A numeric value
String Text
Void Designates that a method returns nothing, and
thus can not stand on the right side of an =

To type where no one typed before


The picture accompanying this step provides a rough overview of the types found in TypeScript. Developers experienced with Java or
C will note the lack of specific numeric types: this is due to the reliance on the common JavaScript interpretation core. It cannot keep
integers and floats apart, the weakness propagates to TypeScript at runtime. Strings share a similar fate they are but a bit of
syntactic sugar attached to a normal JavaScript var.
Void is interesting from a psychological standpoint: it informs the compiler that the element at hand will return nothing. This bit of
metadata is helpful as it ensures that such methods never find themselves on the right-hand sign of an equals operator.

function btnClicked() this.myWhatAmI=aWhat; aides known to programmers. Our snippet that can be
{ } seen below demonstrates the adding of a property
var planeManager: AircraftManager; private sayHello() { which checks the values passed into it before
planeManager = new AircraftManager(Aircraft. alert("Hello"); committing them to the data store found inside the class.
MIG21); } The getter could, in theory, also be expanded to modify
planeManager.sayHello(); } the values returned.
} class AircraftManager {
10. Yield results private _WhatAmI: Aircraft;
9. Hide a member TypeScripts zealotic quality control algorithms, of course, get myWhatAmI(): string
TypeScript treats all members of a class as public by can also make amends for all kinds of class-related {
default. This behaviour can be modified by making use oddness. We can try this out with two methods: by return "An Aircraft";
of the private keyword. This keyword can be appended attempting to invoke the constructor with a wrongly }
to both member functions and variables in both cases, typed parameter or via an access attempt addressed at a set myWhatAmI(what: string)
external access is no longer permitted by the transpiler. private variable. {
class AircraftManager { if (what == "MIG21")
private myWhatAmI: Aircraft; 11. Check values {
constructor(aWhat:Aircraft) { Accessors are among some of the oldest structuring this._WhatAmI = Aircraft.MIG21;

79
:HE'HVLJ
The:HE'HVLJAnnual

} } potentially lead to some brittle code if it is overused.


} . . . However, static elements can also be really helpful when
it is actually applied correctly. TypeScript delights its
12. Function cut short 13. Creation of parameters users with the presence of a static keyword, and this
Typing time is one of the most important time wasters Functions with a variable number of parameters can be behaves as expected:
that can be encountered during software development. extraordinarily helpful at solving some rarely class AircraftManager
TypeScript permits you to set sensible defaults for encountered problems. TypeScript provides a facility {
parameters, which can then be invoked with a shorter which makes the creation of variable-parameter . . .
parameter list. Please be aware though that all functions really easy all you have to do is take a look at static sayHello() {
non-optional parameters will need to be in front of the the code accompanying this step below. alert("Hello");
optional ones. { }
class AircraftManager { return first + " " + rest.join(" "); }
private _WhatAmI: Aircraft; } function btnClicked()
. . . {
constructor(aWhat: Aircraft = Aircraft. 14. Shared static elements AircraftManager.sayHello();
MIG21) { Static elements are shared between all instances of a }
this._WhatAmI=aWhat; class: although this commonly maligned pattern could

Learn more about TypeScript


Even though TypeScript is not particularly complex, it cannot be covered in five pages worth of tutorial. Developers
interested in finding out more about their working environment should visit the TypeScript tutorial found at
typescriptlang.org/Handbook.
Microsofts endorsement is helpful in that it ensures the presence of a lively and active community: many if not most
questions can be answered via Google. Newbies and professionals facing doubts should visit StackOverflow in order to
find help and consultation from their peers.

80
// Robust JavaScript code with TypeScript library

15. Inheritance worker(anObject); }


Making classes inherit from one another simplifies the } function btnClicked()
modelling of real-world relationships. Derived classes can, {
furthermore, overwrite the behaviour of their hosts for 18. Make parts optional genericF<Number>(22);
example, the BetterManager replaces the message that An old adage states that exceptions can prove the genericF<String>(22);
is shown by the normal sayHello() function if invoked, validity of rules. Interfaces can be configured to contain }
class AircraftManager { optional members and of course these dont necessarily
. . . need to be implemented. This feature, unfortunately, is 22. Mixin on the loose
sayHello() { not particularly helpful for us and thats because crashes Keep in mind that creating complex inheritance
alert("Hello"); can occur if the callee forgets to check the presence of structures is not always the best solution. Mixins are
} the implementation. building block classes which provide a small set of
} interface AnObject functionality, and these mixins can then be integrated
class BetterManager extends AircraftManager { into larger classes. As an example, let us take a bit of
{ myName: String; code from the documentation which creates activity
sayHello() myNumber?: Number; management logic.
{ } class Activatable {
super.sayHello(); function worker(a: AnObject) { } isActive: boolean;
alert("Greetings from the better Manager!"); function btnClicked() activate() {
} { this.isActive = true;
} var anObject = { myName: "AnElement"}; }
function btnClicked() worker(anObject); deactivate() {
{ } this.isActive = false;
var aManager: BetterManager; }
aManager = new BetterManager(); 19. Implement interfaces }
aManager.sayHello(); Classes can be designated as implementations of
} particular interfaces. This is accomplished thanks to use 23. Use applyMixing
of the implements keyword: if implements is present Mixins are instantiated via the implements keyword. The
16. Access mother object and the class misses declarations that are required in the host class must contain a stub implementation, and this
TypeScript does not hide the mother object instance interface then what happens is that a compiler error will is then overwritten at runtime by making use of the
from view. It can, instead, be accessed via the super be raised in order to notify the developer about his applyMixing method.
keyword. Our snippet below demonstrates the usage of unforgiveable omission. class SmartObject implements Disposable,
super in a constructor and in a member function it interface AnObject { Activatable {
could not be easier. myName: String; . . .
class BetterManager extends AircraftManager myNumber?: Number; // Activatable
{ } isActive: boolean = false;
sayHello() class SomeClass implements AnObject activate: () => void;
{ { deactivate: () => void;
super.sayHello(); myName: String; }
alert("Greetings from the better Manager!"); myNumber: Number; applyMixins(SmartObject, [Disposable,
} } Activatable])
} var smartObj = new SmartObject();
20. Modularise setTimeout(() => smartObj.interact(), 1000);
17. Enforce presence via interfaces The TypeScript transpiler does not merge the individual
JavaScripts duck typing is a never-ending source of pain parts of a library into one file instead, each TS file gets 24. Mix it up
and this is because everything is valid for everything, transformed into an individual JS file. Do be aware The actual deployment of the mixin must be done at
that is until a NullReferenceException occurs though. though that each JS file must be included into the runtime via the function shown in the code snippet
Using an interface enables developers to specify the website separately in order to be able to use the shown below. Due to the complexity of the mixins, its
presence of member variables and/or functions and modules content. important for you to consult documentation before
any elements that are not confirming are therefore not proceeding further.
allowed to pass. 21. Go generic function applyMixins(derivedCtor: any,
interface AnObject Developers can side-step the type-checking process and baseCtors: any[]) {
{ all they have to do to do this is make use of the Any baseCtors.forEach(baseCtor => {
myName: String; keyword. The use of generics provide a safer way to Object.getOwnPropertyNames(baseCtor.
myNumber: Number; creating type-agnostic classes and/or functions: the prototype).forEach(name => {
} parameter informs the compiler about the type that is derivedCtor.prototype[name] = baseCtor.
function worker(a: AnObject) { } going to be used by a particular instance, and this can prototype[name];
function btnClicked() then be enforced with zealotism. })
{ function genericF<T>(myVal: T) });
var anObject = { myName: "AnElement", { }
myNumber: 22 }; return myVal;

81
The:HE'HVLJAnnual

Make playlists with


your friends using
the Last.fm API
Master Fetch and Last.fms API by making a playlist from you and
your friends mutual tastes

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Make playlists using the Last.fm APIlibrary

1. Install Express

M
usic is both universal and incredibly <input class="username-input" type="text"
subjective. What one person The server for our simple app will be Node.js using placeholder="Your Last.fm username"
considers the epitome of human Express. This will then enable the scafolding process of data-ng-model="user" data-ng-model-
creative achievement another may an Express app for you and start to serve it up on port options="{ updateOn: 'blur' }">
dismiss as bad taste. In this tutorial were going to attempt 3000. Well be editing the app.js file at the root of the <!-- script tags -->
to bridge the gap by using data from Last.fm to create project later on. Well also use a wrapper for the Last.fm </body>
playlists of songs you and a friend have in common. API on the server to help with authentication.
Last.fm was founded in 2002 by two university 4. Define module
students and has since been bought out by CBS 2. Install client-side packages Back in the public folder make a JavaScript file called
Interactive. It ofers a place to store what youve listened Code that is served to the user is stored under the playlist-app.js. The module app is what the ng-app
to and has a number of API services that enable public folder. Navigate to this folder and run the attribute in the previous step looks for; likewise with the
developers to dig into this rich mine of data. following Bower command. Alternatively you can install controller and its definition. Were also injecting a
To help us achieve this were going to use a new Angular 1.3, angular-query-string (npmjs.com/package/ LastFmService which well create later on. Note the
method for making requests called Fetch (more angular-query-string) and Underscore manually, and dependency on angular-query-string as well which
information at fetch.spec.whatwg.org). Fetch is currently Meteor will automatically restart. provides UrlQueryString.
supported by Chrome 42, Firefox 39 and Opera 29. Fetch
aims to replace the old and somewhat hack-y 3. Capture username
XMLHttpRequest introduced by Microsoft in 1999. The Now well start writing our Angular app. We want to
web has come a long way since then and Fetch is
designed around streams and promises.
capture a Last.fm username so that we can start the
process of finding friends on Last.fm. Create index.html
Network red herring
If youre using the Network tab in your Web
The front-end portion of this tutorial is relatively at the root of the project and a text input which updates Inspector to debug requests made by Fetch, they
straightforward but previous experience with Angular will the user model when focus moves from it. wont appear under the XHR tab as theyre not
aid understanding. The server-side portion is covered <body data-ng-app="app" data-ng- XMLHttpRequests!
briefly but the full source code is on FileSilo. controller="FriendController" data-ng-cloak>

Left
When a username is entered we can use it to get a list of
their friends and display it

Top left
By using Bower to manage our packages we can include
multiple projects at once and increase the projects
maintainability as well
Top right
This input captures the username input and is tied to the
user model. Updating on blur keeps requests low

83
:HE'HVLJ
The:HE'HVLJAnnual

The Promise API means that we can


angular.module('app', ['angular-query-
string'])
.controller('FriendController', ['$scope',
'$window', 'LastFmService',
chain multiple asynchronous functions
'UrlQueryString', function ($scope, $window,
Lastfm, UrlQueryString) {
}]);

5. Get friends
with then

lastfm.getFriends(username).then(function
(data) {
$scope.friends = data.friends.user;
};
})

As a user enters a username we want to make a request $scope.$apply(); 7. Last.fm API call
to the Last.fm API to get a list of their friends. There are }); Were going to be using the experimental Fetch API to
many ways to do this, one alternative is to add a function } make a request to user.getFriends (last.fm/api/show/
to the input which updates on blur, the same as the }); user.getFriends). Fetch works with streams and
model, but well watch the user property for changes. promises which are often a little bit exotic, which is nice.
$scope.$watch('user', function (username) { 6. Create Angular service The Promise API means that we can chain multiple
if (username) { You may have noticed that we called lastfm.getFriends asynchronous functions with then. Response.json()
but currently lastfm doesnt exist in our app! Well rectify returns a stream so that the reading of large files can be
that by adding a service to the app module. Youll need progressively rendered.
to register for a Last.fm API key by going over to last.fm/ getFriends: function getFriends (username) {

An extensive API api/account/create.


.service('LastFmService', function () {
return fetch(url + '&method=user.getfriends&
recenttracks=1&user=' + username)
Last.fm has 133 documented services for you to
use, ranging from user information to var url = http://ws.audioscrobbler. .then(function (response) {
geographical events. You can read about in more com/2.0/?api_key=YOUR_API_KEY&format=json'; return response.json();
detail at last.fm/api. return { });
/* next step */ },

Top left
A request made by the Fetch API contains all of the same
information as the trusty XHR request

Top right
We will need to hand the user a link to see their newly
created playlist and cement their friendship
Right
Taking the user to the Last.fm site provides a handy
breakdown of what theyre enabling the app to do

84
// Make playlists using the Last.fm APIlibrary

Last.fm authentication
Weve used a library to deal with the authentication process for us. You make a request with your API key and in return (after the user
has granted permission) Last.fm gives you a token that can be saved to make subsequent requests without having to reauthenticate.
The trickiest part of this process is signing your calls to API methods that require authentication. They require parameters to be
supplied alphabetically and UTF-8 encoded, then hashing it with the MD5 algorithm. Any language can be used and Last.fm has a list
of recommended wrappers including Python and .NET. It could even be done client-side but this would mean exposing your apps
secret key, which is not recommended.

click="chooseFriend(friend)"> $scope.chosenFriend = friend;


8. Display friends <img src="{{friend.image[0] lastfm.compare($scope.user, friend.name)
Fetch is making the API call and weve already written a ['#text']}}">{{friend.realname || friend. .then(function (data) {
handler for it by populating $scope.friends with the name}} var artists = data.comparison.result.
result. As a last step to finish showing our users Last.fm </li> artists.artist;
friends we will just need to write a simple repeater which </ul> return artists;
will then show a list of the friends. Were outputting a </section> }).then(function (artists) {
small simple image and we will prefer the real name /* next step */
over the username. 9. Choose friend });
<section class="friend-container" data-ng- You should now have a list of friends appearing and };
show="friends.length"> when the user clicks one of these friends we want to
<h4>Choose a friend to create a playlist start the comparison process. Create a playlist array 10. Get tracks
with: which will contain the track objects to display and call Anticipating the response from that, well loop over each
</h4> compare on the lastfm service. Then pass it the mutual artist thats returned from Last.fm. For each artist
<ul> username of who we are and the friends name. we call another service which looks for tracks by a given
<li class="user" data-ng-repeat="friend in $scope.chooseFriend = function (friend) { artist that our friend has listened to and select a random
friends" data-ng- $scope.playlist = []; two from the list returned. For those two tracks we call

85
:HE'HVLJ
The:HE'HVLJAnnual

Fetch can also be used in service


another method we havent written yet called addTrack.
artists.forEach(function (artist) {
return lastfm.getTracksOfArtist($scope.
chosenFriend.name, artist.name)
workers this means your asynchronous
.then(function (tracks) {
_.sample(tracks.artisttracks.track, 2).
forEach(addTrack);
});
processes can spawn more!
+ user1 + ' &value2=' + user2).
then(function (response) {
return response.json();

This will ensure that the track has a name and loops
through the array to make sure the Last.fm ID isnt
already in there. If it is, it will add an other track and then
}); }); shufles the playlist to mitigate the same artist being
}, played sequentially.
11. Last.fm API calls getTracksOfArtist: function (friend, artist) var addTrack = function (track) {
The compare and getTracksOfArtist methods follow a { if (track && track.name) {
similar format to the previous API call with Fetch. In both return fetch(url + '&method=user. var inPlaylist = $scope.playlist.
cases we parse the response as JSON and then pass it getartisttracks&user=' + friend + '&artist=' some(function (t) {
onto the next function so that we can access the + artist).then(function (response) { return t.mbid.length && t.mbid === track.
response in the controller. The comparison is done via return response.json(); mbid;
Last.fms tasteometer, which also returns a compatibility }); });
rating between 0 and 1. }, if (!inPlaylist) {
compare: function (user1, user2) { $scope.playlist.push(track);
return fetch(url + '&method=tasteometer.comp 12. Add track $scope.playlist = (_.shuffle($scope.
are&limit=30&type1=user&type2=user&value1=' The logic for adding a track to the playlist is reused, so to playlist);
keep things in line with DRY (the dont repeat yourself $scope.$apply();
principle) weve chosen to make it a separate function. }

Fetch: gotchas and how to use it today


A few gotchas to look out for is that you can only read a Fetchs stream once. If you write response.json(); response.text(); the
second will throw an error because the stream has already been read. If you want to do this then write response.clone().text(). Also,
there is no way to cancel a request but this may be fixed in the future. This is due to the Promise-based nature of Fetch. Fetch doesnt
have comprehensive support and to tackle this, GitHub developers wrote a polyfill which wraps XHR with the Fetch API (see github.
com/github/fetch). Fetch can also be used in service workers, unlike XHR requests which cant. This means that your asynchronous
processes can spawn more asynchronous processes!

86
// Make playlists using the Last.fm APIlibrary

} $scope.savePlaylist = function () { var authUrl = lfm.getAuthenticationUrl({


}; var data = JSON.stringify({ 'cb' : 'http://localhost:3000/auth' });
name: $scope.chosenFriend.name, res.send(authUrl);
13. Get loved tracks tracks: $scope.playlist, });
You could use this project to play some songs when });
youre both in the same physical space. Being a good lastfm.savePlaylist(data).then(function 20. Last.fm authentication
host, youll probably add some songs for your guest so (url) { In the last step we told Last.fm to send the user back to
well add a couple of their loved tracks to the playlist. if (~url.indexOf('last.fm')) { http://localhost:3000/auth once theyve provided the
.then(function () { $window.location = url; app access to their account. This process returns us a
lastfm.getLovedTracks($scope.chosenFriend. } unique token which we can use to then create a session.
name).then(function (data) { }); app.get('/auth', function (req, res) {
_.sample(data.lovedtracks.track, 2). }; var token = url.parse(req.url, true).query.
forEach(addTrack); token;
}); 17. Fetch POST request lfm.authenticate(token, function (err,
}); POSTing data with the Fetch API is slightly more involved session) {
than the previous GET requests. Instead of encoding the lfm.setSessionCredentials(session.username,
14. Loved tracks request data in the URL, this time the data is sent with the POST session.key);
The actual API call is similar to the last few. Most of the request body. Its essential that we set the Content-type // next step
Last.fm services return a subset of the total results and header to application/json for the server to identify it. });
has a pagination system so you could loop through savePlaylist: function savePlaylist (data) { });
incrementing the &page value. You can also limit the return fetch('http://localhost:3000/
results if you know you want less than 50 results. save-playlist', { 21. Add tracks
getLovedTracks: function getLovedTracks method: 'post', To create the playlist we need a title and description.
(user) { headers: { Then we use a callback function to add each track to the
return fetch(url + '&method=user. 'Content-type': 'application/json; playlist. Weve set a timeout of 500 milliseconds between
getlovedtracks&user=' + user) charset=UTF-8' each request or else only some tracks will be added.
.then(function (response) { }, Then we redirect with parameters indicating its URL.
return response.json(); body: data lfm.playlist.create({
}); }).then(function (response) { title: data.name,
}, return response.text(); description: 'Generated by Playlist-o-
}); matic.'
15. Display playlist } }, function(err, playlists) {
Weve got some tracks coming back from the API so lets data.tracks.forEach(function (track, index)
display them! Create an ordered list and display the track 18. Authenticate on server {
name, artist and album with a hyphen between them. Now were going to jump to app.js at the root of the setTimeout(function () {
Diferent services will either return .name or .#text. project. Were going to work around the code thats lfm.playlist.addTrack(playlists.playlist.id,
<section class="playlist-container" already there so you might want to append the following track.artist['#text'] || track.artist.name,
data-ng-show="playlist.length"> to the end of the file or copy the contents of the included track.name);
<h1>Your playlist with {{chosenFriend. resources from this tutorial on FileSilo. Const is a type of }, 500 * index);
realname || chosenFriend.name}}</h1> variable introduced in ES6 which cannot be altered. });
<ol> var LastfmAPI = require('lastfmapi'); res.redirect('/?playlist=' + playlists.
<li class="track" data-ng-repeat="track in const LASTFM_API_KEY = YOUR_API_KEY; playlist.url + '&friend=' + data.name);
playlist"> const LASTFM_API_SECRET = YOUR_API_SECRET; });
{{track.name}} <span data-ng-show="track. var lfm = new LastfmAPI({
artist.name || track.artist['#text']">-</ api_key: LASTFM_API_KEY, 22. Share playlist URL
span> {{track.artist.name || track. secret: LASTFM_API_SECRET When the user is redirected we will display a message to
artist['#text']}} <span data-ng-show="track. }); confirm that the playlist was created. That complete the
album.name || track.album['#text']">-</span> process! Enjoy your playlists.
{{track.album.name || track.album['#text']}} 19. Express routes // client///playlist-app.js
</li> To ensure everythings running in the same place, serve if (UrlQueryString.friend) {
</ol> the index.html file at the root level. The /save-playlist $scope.created = {
<button data-ng-click="savePlaylist()">Save route is what we POSTed the playlist data to; this is stored friend: UrlQueryString.friend,
playlist</button> in a variable that we can access elsewhere for now. url: UrlQueryString.playlist
</section> app.get('/', function (req, res) { };
res.sendFile(path.join(__dirname + '/index. }
16. Save playlist listener html')); //index.html
We added a button to save the playlist. To create one, }); <p data-ng-show="created">Your playlist with
authenticate the user on the server. Now send over the app.post(/save-playlist', function (req, {{created.friend}} <a href="{{created.url}}"
name of our friend and the tracks. As we receive a res) { target="_blank">has been created!</a> <a
response it sends us to authenticate on the Last.fm site. data = req.body; href="/">Create another?</a></p>

87
The:HE'HVLJAnnual

The complete
guide to

88
Git
How to take control of projects and maintain
multiple versions of one system
// The complete guide to Git

Why you need Git


THE VERSION CONTROL SYSTEM
How Git works with GitHub
HAS A HOST OF BENEFITS THE WEB-BASED REPOSITORY AND INTERFACE IS ESSENTIAL
Linus Torvalds faced an unsurmountable problem Going decentral is beneficial in that it makes your or two clicks; issues, improvement requests and
when his Linux kernel became bigger and bigger. At codebase more resilient: an ofice fire is much similar metadata can also be centralised in a
some point, using ordinary VCS systems could not less critical if the data is safely tucked away in the GitHub repositiory.
keep track with his work. cloud. This knife, of course, cuts both ways if Projects working on 3D or PhotoShop files profit
He developed Git to address this pain point so that GitHub goes down for maintenance (which it will from embedded viewers: a WebGL-based utility
large codebases could be kept track of. Furthermore do from time to time), then any work will ensures that everyone can take a look at a
its based on a decentral concept and this means that certainly grind to a halt. preview of the files contents.
every developer has a fully fledged repository on his Benefit number two involves Documentation can furthermore
workstation: network access is required only when value-added features. GitHub is be hosted in the form of a wiki,
data is to be synchronised. best-known for a well-designed which comes with every
web interface that provides its repository and is maintained by
Whats it good for? clients with a large variety of GitHub automatically.
If you think your company like many other small additional functions which Finally, GitHub has
companies does not need a version control system, make wrangling with code tremendous reach. Open source
think again. The availability of a VCS improves the easier. Code hosted on GitHub code tends to be hosted on
productivity regardless of size. This is accomplished can also be accessed from a GitHub as it tends to get the most
by multiple factors: first of all, code hosted on a VCS is browser of your choice, with views there: if a project manages to
more likely to survive ofice fires, ransomware strikes commonly used folders being provided get enough likes then this placement is
and similar occurrences of bad luck. as a ZIP archive. enough to ensure extra attention.
Secondarily, code hosted in Git is much easier to These utilities are tied into a complex social Developers tend to be experienced with the
modify. You can freely try out something new: if it network. Figuring out which projects are being value-added features of GitHub: subjecting them
turns out to be a disaster, undoing it is a matter of one worked on by which developers is a matter of one to a diferent user interface might lead to friction.
click. Finally, using a VCS makes synchronising
multiple devices so much easier.

Working with describes an operation which shoves the current


state of the project into the repository:
Installing Git
repositories tamhan@TAMHAN14:~/GitHouse$ git commit -m
"Initial commit"
[master (root-commit) 3c7c91f] Initial commit GETTING STARTED WITH GIT IS
NOW WE KNOW THE BENEFITS LETS 1 file changed, 6 insertions(+) REALLY EASY
CREATE A CODE STORAGE SPACE create mode 100644 somecode.cpp When working with an Unix-like operating
The first step involves selecting a folder of choice. system, getting Git is as easy as invoking the
Enter the git init command in order to create the Git dif can then be used to perform an analysis correct package manager command. On an
hidden metadata directory: comparing your local data with the one that was found Ubuntu workstation, use the following:
tamhan@TAMHAN14:~/GitHouse$ git init in the repository. Pushing new code to Git is sudo apt-get install git
Initialized empty Git repository in /home/ accomplished via a combination of the git add and Developers using Windows or Mac OS X can
tamhan/GitHouse/.git/ git commit functions. obtain a working version of the toolkit by
Getting back to an older version can then be downloading the prepared installers from
After copying files to the repository, enter git status to accomplished via a combination of git reset and git git-scm.com/downloads. Using them is really
see the current state. Git will inform you that the new checkout -f. The relevant sequence is shown in more easy just treat them like another typical
files need to be added via add if your file goes by detail in the screenshot on page 76. set-up routine. Nothing prevents you from
the name somecode.cpp, add it as per the following: Even though Git is usually used with server-based compiling your own version of the product
tamhan@TAMHAN14:~/GitHouse$ git add repositories, the product can also generate patch files should push ever come to shove: and you can
somecode.cpp sent via email. Patch files spawn via git format-patch: find the source code at git-scm.com. Git
the command expects the Secure Hash Algorithm requires a username and an email address of
Git is now aware of the existance of somecode.cpp (SHA) sum of the first commit to be considered and the current user and these can be set via the
and this knowledge enables us to perform a commit: it creates one .patch file for each commit. following commands:
tamhan@TAMHAN14:~/GitHouse$ git config

Git diff can then be used to perform an --global user.name "TAMHAN"


tamhan@TAMHAN14:~/GitHouse$ git config
analysis comparing your local data with the --global user.email
"tamhan@tamoggemon.com"
one that was found in the repository
89
The:HE'HVLJAnnual

14 Git commands every What are


user needs to know
THE GIT COMMAND-LINE TOOL PROVIDES A LARGE SELECTION OF
USEFUL FEATURES. FIND OUT MORE ABOUT THE CREAM OF THE CROP
branches?
WORK ON COMPLEX PRODUCTS IS
1. Partial upgrade 8. Harness the shortcut RARELY COMPLETELY LINEAR, AND
Sometimes, an outdated local codebase needs just Entering frequently used Git commands over and THIS IS WHY WE USE BRANCHES
one or two specific changes. In that case, git over again is boring and tiresome. Use git config Imagine yourself to be working on an application
cherry-pick <id> is your friend it applies just the --global alias.<shortcut> <forwhat> to create a made up of two parts: a custom user interface and a
changes specified under <id>. time-saving reduced version of the command third-party computational engine, which is to be
passed to <forwhat> accessed via an intermediary layer. Sadly, issues at
2. Add a note the side of the supplier force a change of calculation
Commits can be documented with a note 9. Speed me up! provider. In this case, the developer responsible for
containing further information unlike commit Gits internal management structures can become changing the engines transforms himself into a
messages, they can be changed later. Note messy as time goes by. Cleaning up can be roadblock: work cannot proceed until the interface
management is handled via the git notes accomplished by invoking the integrated garbage has been updated. Branches can solve this problem in
command family. collector. Doing so is easy all you have to do is an elegant fashion.
just enter git gc. The codebase is broken down into two pieces as
3. Track down regressions per the flow chart on the right: the user interface
If old bugs suddenly show up again, git bisect will 10. Local copies developers keep hacking along on the main trunk,
track them down using a divide and conquer Use git clone <url> to copy a remote repository. while the person responsible for the adaption toils
algorithm. Simply set the good and bad The command downloads the current state of away on the newly created branch.
commit IDs, and test each of the the code and the metadata commonly Git takes care of keeping the two workflows
codebases provided. Good found in the .git subfolder, thereby separate and each team then work independently
coding giving you a complete local copy. from one another. Once the adaptation is complete,
4. Emailing patches When a mistake is found in
If your team coordinates itself a branch it should be fixed. To 11. List ignored files
via a mailing list, patches can stop bouncing around from branch Advanced users use .gitignore
be sent automagically by using
the git send-email -to
<recipient> <files> command
to branch, try out the git checkout
command. Go to bit.
ly/1OZHHmR for more
to block any unnecessary files
from the version control system.
Entering git ls-files --other
GitLab vs
sequence. File will accept
wildcards such as 00**.
information. --ignored --exclude-standard lists
all files which the version control
system will not accept.
GitHub
5. Send-email command HERE COMES THE COMPETITOR:
On most Unix-like operating systems, Git will not 12. Remove a file GITLAB IS READY TO CHALLENGE
recognise the send-email command by default. When a file is no longer needed you can make use GITHUB ON EVERY LEVEL
This is due to the email package being hosted of git rm to inform the version control system that The company added a variety of interesting features
separately install it via apt-get install git-email. the element in question should not be contained in to both stock Git and the add-ons provided by
future checkouts. GitHub. First of all, collaborative tools received a
6. The blame game significant boost: issues can receive attachments
Ever wanted to find out whose drunken coding 13. The Git menu containing further information about the task at hand.
spree caused the system to fail and mess up all Like most Unix command line utilities, Git is In addition to that, a fine-grained rights management
your hard work? Use git blame it annotates your shipped with a compact help system. Enter git system permits you to set access levels on a
source file with information about each lines --help in order to receive a list of commonly used need-to-have basis. Branch protection prevents lowly
change history along with the SHA ID of the commands along with a short description of the users from pushing code into important branches,
individual commits. role of each. thereby accelerating the deployment of mission
critical features.
7. Sign a tag 14. Tell me more! Enterprise customers benefit from proprietary
Developers working on highly sensitive code will Invoking a subcommand with the --help parameter extensions to the underlying VCS. It can handle very
be delighted to hear that Git provides a way to tends to yield loads of extra information on the large binary files efortlessly and it is possible to add
create tags by making use of a digital signature. If parameters taken in. If youve done this but this these pesky PR assets to VC.
GnuPG is correctly wired into Git, then the process still does not solve your problem, then rest assured Finally, GitHub has been in the news recently due to
of signing a tag can be accomplished by simply that a quick Google session will provide you with the upload of some shady scripts and other political
passing -s to git tag. all the help you need. strifes. People who believe that vendors should steer
far away from politics can use GitLab as an alternative.

90
// The complete guide to Git

The life of a project


How to undo
Branch

HOW TO SOLVE COMMON


DEVELOPER PEEVES USING GIT
Fixing bad local changes is best
accomplishing by checking out the afected
files once again: Git will replace your
Mainline

borked-up copy with a brand new one. Sadly,


Murphys law (anything that can go wrong will
go wrong) ensures that problems are likely to
occur only after the code in question has
already been uploaded to version control.In
the two branches can be merged into one another state of the project in principle, a tag is little more this case, git revert <id> is the remedy of
again. Git assists this process by making use of a set of than a symbolic link pointing at a version. They are choice. It isolates the bad commit, and creates
advanced comparison tools you can easily find out commonly used to designate releases users can a new one containing the projects state before
which changes and/or conflicts might occur. easily find the code used to create a specific artefact the mishap. This measure is important in that
Git identifies the individual branches via the SHA by tracking down its tag. Git aims to present a complete and accurate
sum of the individual files. Sadly, handling these long Gits unique structure makes the creation of state of the development process: under its
and unwieldy strings is not particularly comfortable: branches and tags very cheap: unlike SVN and CVS, philosophy, mistakes should be conserved for
addressing them by strings would be easier. This can codebases can regularily be found which contain further study.
be accomplished by adding a tag to identify a specific thousands of branches and tags. When working with services such as GitHub,
the situation is more complex. Uploaded files

Git takes care of keeping the two cannot be removed reliably, as users could
have forked or downloaded them further
workflows separate and each team then information on that topic is available should
you wish to read it at help.github.com/articles/
work independently from one another

Get connected master


Username for 'https://gitlab.com': TAMHAN
remove-sensitive-data.

command sequence:
tamhan@TAMHAN14:~/GitLab$ git clone https://
Password for 'https://TAMHAN@gitlab.com': gitlab.com/TAMHAN/ImagineRepo.git
HOW TO EXCHANGE CODE Counting objects: 3, done. Cloning into 'ImagineRepo'...
So a local version of Git turned out to be quite Delta compression using up to 8 threads. remote: Counting objects: 3, done.
helpful. Gits true power can be harnessed only when Compressing objects: 100% (2/2), done. remote: Compressing objects: 100% (2/2), done.
combined with a server: it lets multiple developers and Writing objects: 100% (3/3), 279 bytes | 0 remote: Total 3 (delta 0), reused 0 (delta 0)
their various devices exchange code independently bytes/s, done. Unpacking objects: 100% (3/3), done.
from one another. Total 3 (delta 0), reused 0 (delta 0) Checking connectivity... done.
To https://gitlab.com/TAMHAN/ Host it
Getting on a server ImagineRepo.git yourself? Finally, code is to be returned to the
The following steps that we will take you through here * [new branch] master -> master Gits server-side repository all with a process known
will use a free GitLab account which will host an open Branch master set up to track components integrate as a push:
source project. Sign up at gitlab.com/users/sign_in, remote branch master from themselves into the user tamhan@TAMHAN14:~/GitLab/
and click the New Project button to create a new origin. management system of the OS. ImagineRepo$ git commit
project. GitLab will ask you for a name and a set of This leads to increased [master bfbd81b] Uploading now
accessibility criteria which define who is able to access After entering git push, your local administration eforts a 1 file changed, 1
the files contained within. After completion, a URL code is automatically transferred into problem solved by insertion(+), 1 deletion(-)
similar to gitlab.com/TAMHAN/ImagineRepo.git will GitLabs storage. You can inspect it via Gitolite.
be returned if you click the HTTPS button. the Files tab of the web interface. However, you should always keep in mind
that all repositories are not created equal: some
Contribute and maintain a project The common workflow approach maintainers permit pushes from anybody and
With that, our repository is ready and waiting. The Now its time to introduce a second developer into the everybody, while others may limit themselves to
GitLab UI provides you with a sequence of commands equation and their first act involves the downloading uploads from known team members. A popular
which copy it to your workstation. Since we already of the code that needs to be worked on. Git works a bit example for the second approach is that of Microsofts
have a repository from the steps on page 73, we will, diferently from other version control systems out .net framework: even though the framework was open
instead, deploy it to the cloud by entering the there in that it forces the developer to obtain a sourced recently, changes can only be accepted from
following commands: complete copy of all code that can be found online a the Microsoft employees that are assigned to the
tamhan@TAMHAN14:~/GitHouse$ git push -u origin job which is easily accomplished via the following relevant teams.

91
The:HE'HVLJAnnual

Git Log emits a Commands like


list of commits git reset provide
leading to the a summary of
current state. The listing changes.
string shown In our simple
after the commit repository, the
header is a hash file somecode.
ID which cpp is shown to
identifies the receive changes.
individual
transactions.

92
// The complete guide to Git

Command-line benefits Customising Git


WORKING IN THE COMMAND LINE DOESNT HAVE TO BE TIME-CONSUMING
Gits development was inspired by classic Linux and Secondarily, the relatively complex command ADJUSTING BEHAVIOUR LEADS
open source books such as The Cathedral and the structure makes for a great training opportunity. TO BETTER UX
Bazaar. Due to this, the products native client takes In addition, should you use bash as your shell of Gits configuration is collected from multiple
the form of a command-line tool: both GitLab and the choice, make sure to visit git-scm.com/book/en/v1/ places. Systemwide settings are stored in /etc/
graphical frontends mentioned on page 74 are mere Git-Basics-Tips-and-Tricks in order to obtain the gitconfig, while each users home directory
shells which invoke the Git client for you. Auto-Completion script. This script makes work so contains a GITCONFIG file with further settings.
Hitting the command line yourself ofers multiple much easier and quickly as you can simply press the Finally, each repository can have its own
benefits. First of all, the lack of an intermediary layer Tab key to receive IntelliSense-like suggestions and attributes set via custom config files in its .git
means that you can access Gits features directly. automatically fill commands. subfolder. Be aware that low-level files
overwrite upper-level ones: a project can
overwrite systemwide default settings.

Data recovery creation command, and feast your eyes on recovered


files.Another eeker involves the uploading of large
By far the most important piece of
configuration involves the setting of user data,
which is best accomplished via the git config
GIT PROVIDES DEVELOPERS WITH files: each and every git clone will proceed to commands that were mentioned in the
AMPLE OPPORTUNITY TO SHOOT download the content in its entity even if it has been installation instructions:
THEMSELVES IN THE FOOT removed from recent commits. tamhan@TAMHAN14:~/GitHouse$ git config
By far the most common error involves the loss of Even though this problem can in theory be --global user.name "TAMHAN"
commits due to the deletion of a downstream solved with Git itself, using the BFG RepoCleaner is tamhan@TAMHAN14:~/GitHouse$ git config
element. In this case, the data still remains accessible significantly faster (as in minutes instead of days) and --global user.email "tamhan@tamoggemon.
if you happen to know its SHA1 ID, that is. is furthermore easier to use. Simply download the tool com"
Figuring out the SHA1 ID of a recently performed from rtyley.github.io/bfg-repo-cleaner/ and follow Another interesting bit of configuration
commit is best accomplished via the reflog command. the instructions to clean up your repository once and involves the colouring of command line output.
Simply feed its output into a checkout or branch- for all. By default, Git will colour messages intended
for display this can be disabled via the
following property:
git config --global color.ui false
Attributes can be used to provide Git further
information about the file types handled. For
example, some binary file formats might be
difable with special commands which can
be registered by setting an attribute.
Finally, hooks permit you to run
scripts in response to specific
Scott Chacon changes taking place in a
@chacon repository. Further
A GitHubber, open source information on the various
developer and Git evangelist, properties can be found in the
Scott is also a writer and worked Book of Git, which is accessible
on Atoms Flight Manual. via bit.ly/1Mxk9Hu and bit.
ly/1tOhgtG. Be aware that config
files are PlainText you can always
modify them with gedit if you distrust the
work performed by the config command.

4 Essential Git tools ADD IMPRESSIVE FEATURES TO YOUR GIT WORKFLOW


EGit eclipse.org/egit GitHooks bit.ly/1I19ccZ Git-Extras bit.ly/1H1U772 GitK and friends bit.ly/1LYfZZ7
Command line git is so Seventies. VCS systems should be integrated into This frequently maintained package If IDEs like Eclipse or Visual Studio do not
Integrating the version control system the development workflow so that unit contains a group of scripts adding all interest you, a dedicated Git browsing
with an IDE makes work easier. Eclipse tests can be run as new code is checked kinds of interesting features to Git. Take a utility might suit. Unix heads use gitk,
does not support Git out of the box but in. GitHooks lets you run arbitrary scripts look at its documentation to find out while Windows developers are best
EGit solves this problem efectively. in response to repository events. more you will save time in the long run. served with TortoiseGit.

93
:HE'HVLJ
The:HE'HVLJAnnual

20 BEST
GITHUB
PROJECTS
GitHub acts as a harbour for impressive code and this selection of
extraordinarily cool projects will certainly enrich your coding

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// 20 best Github projects

GET TO GRIPS WITH FULLPAGE.JS


fullPage.js <script type="text/javascript" src="jquery. Even though the individual slides can be formatted via
github.com/alvarotrigo/fullPage.js fullPage.js"></script> CSS, the mandatory bring-up of the framework can also
Use for: designing slideshow-like webpages In the next step, the actual content needs to be defined. be used in order to provide additional context such as
This is accomplished by adding the following <div> background colours:
Generations of badly designed PowerPoint slides have structure to your website: $(document).ready(function() {
accustomed users to full-screen presentations. This <div id="fullpage"> $('#fullpage').fullpage({
JavaScript framework provides a quick and convenient <div class="section">Some section</div> sectionsColour: ['#1bbc9b', '#4BBFC3',
tool which transforms websites into full-screen <div class="section">Some section</div> '#7BAABE', 'whitesmoke', '#ccddff'],
PowerPoint-like presentations. Since its initial release, <div class="section">Some section</div> anchors: ['firstPage', 'secondPage',
both large and small companies enthusiastically <div class="section">Some section</div> '3rdPage', '4thpage', 'lastPage'],
embraced the framework: it was even used on apple. <div class="section active">Some section</ });
com for some time. div> });
As with most other bits of JavaScript code, the usage </div> In this snippet, both the background colours and a set of
of the fullPage.js framework will require the inclusion of By default, fullPage.js displays the section at the top of anchors are provided. The latter simplifies the creation of
the jQuery library along with some helper files. Our the DOM tree. You can modify this behaviour via the internal links, which permit you to approach individual
example here uses the bare minimum of files advanced section active attribute shown below our snippet would pages easily.
scrolling efects will require the inclusion of additional start out by displaying the last item from the list. The Describing all parameters of the JSON object passed
helper libraries: individual sections can contain multiple slides which are to the initialisation function would require an entire extra
<link rel="stylesheet" type="text/css" displayed in a horizontal fashion: volume of this annual edition to fully explain the way it
href="jquery.fullPage.css" /> <div class="section"> deserves to be explained. Because of that, please consult
<script src="http://ajax.googleapis.com/ <div class="slide"> Slide 1 </div> the readme file at github.com/alvarotrigo/fullPage.js in
ajax/libs/jquery/1.11.1/jquery.min.js"></ <div class="slide"> Slide 2 </div> order to learn more, and discover everything there is to
script> </div> know and discover.

95
:HE'HVLJ
The:HE'HVLJAnnual

BUILD SIMPLE MOBILE APPS


Ratchet As for the actual application, a large selection of controls
goratchet.com is provided. For example, tables can be spruced up with
Use for: making apps with simple components various useful gadgets conveying extra information.
Creating good-looking user interfaces for mobile Apps are made up of forms, each of which is to be
applications constitutes an art of its own. Ratchet is contained in an HTML file of its own. They are connected
managed by the team behind the well-known Bootstrap to one another via the Push.js framework by default, all
framework: it aims to simplify this endless task. links are processed by it.
After downloading Ratchet, prepare yourself for a Fortunately, designating external links is as easy as
complete rearrangement of your application. The adding the data-ignore property to their declaration. This
framework requires you to adhere to a strict sequence of is necessary for all references which point outside of
controls firstly, all bar items must be right below the your app the following Google link would be a classic
<body> tag of the individual pages: example of such a task:
<header class="bar bar-nav"> <a href="http://www.google.com" data-
<button class="btn pull-left"> ignore="push">Google<a>
Left Ratchet difers from classic GUI stacks such as jQuery UI/
</button> Mobile due to the availability of two stylesheets which
<button class="btn pull-right"> seek to mimic the design of the host operating systems
Right controls. Sadly, Ratchets platform support is limited to
</button> recent versions of Android and iOS. The developers have
<h1 class="title">Title</h1> not yet decided whether they want to embrace Windows
</header> Phone as for BlackBerry 10, you dont even need to ask.

CODE CUSTOM BUTTONS EMBED A FONT ICON SET


Buttons mfglabs iconset
github.com/unicorn-ui/Buttons mfglabs.github.io/mfglabs-iconset
Use for: implementing fully customisable buttons Use for: embedding icons using a web font or CSS
Buttons are the epitome of touch-screen user interface design: where there is a According to a well-known proverb a figure can be worth a thousand words and
touchscreen, expect large and small, red and green, round and square knobs en these icons will surely say what you want without the text. Most desktop products
masse. The ubiquity of this common control has motivated a group of developers to provide their users with a symbol bar providing quick access to commonly used
start working on a GUI framework dedicated solely to the display of buttons. This insular functions. Mfglabs iconset will difer from normal icon sets in that it is implemented via
approach is beneficiary in that external dependencies are minimised. Getting started a custom font mapped into the Unicode codespace. This is beneficial to us because
with Buttons is as easy as including the following files to your web project additional fonts contain vector information. Your icons will thus look great at all display resolutions
resources are needed only for drop-down menus and symbols: and the pixelation that is commonly found in bitmap icon sets will not occur.
<!-- Buttons core css --> Deploy iconset by copying all relevant resources to a folder of your web application.
<link rel="stylesheet" href="css/buttons.css"> Then proceed to adding the following snippet in order to load the stylesheet and
Buttons developer team took great care to cover all possible approaches to deploy an icon:project additional resources are needed only for any drop-down
development. You can create buttons both via <a> and <button> tags: menus and symbols:
<a href="" class="button button-pill button-tiny">Go</a> <link rel=stylesheet href=css/mfglabs_iconset.css>
<button class="button button-square button-tiny"><i class="fa <i class=icon-paperplane></i>
fa-plus"></i></button> User interface designers will be quick to point out that misuse of symbols is among the
Buttons is able to implement a few hundred knob types by default. Since most apps are most common mistakes found to impact usability severely. A symbol should be used
unlikely to require the entire palette, a customisation utility is provided. It enables you to only when its meaning is 100 per cent clear to the target audience, so absolutely no
strip out unneeded button types, resulting in the preparation of a custom set of confusion or second-guessing on their part. Ensuring this becomes especially dificult
resources which take up less server space and/or bandwidth. once products get internationalised.

96
// 20 best Github projects

ANGULAR ALERTS
ng-notify
matowens.github.io/ng-notify
Use for: notifying the user with error messages
A small German startup introduced slide-in notifications in a long-since-
forgotten iPad competitor. But ever since Windows Phone 7 brought this
concept into wider usage, slide-in alerts have been in ubiquitious usage all
over the mobile market.
Ng-notify is a truly tiny add-on for AngularJS apps. It provides developers
with a selection of diferent notification styles which can be deployed with a
single function call.
Ng-notify is to be deployed like any other AngularJS module the code
shown in the snippet should be familiar to every AngularJS head:
var app = angular.module(demo, [ngNotify]);
Dispatching actual messages can then be accomplished by invoking the set
method found in the ngNotify object:
ngNotify.set(Your error message goes here!, error);
In addition to that, Ng-notify permits you to create custom notification
styles: customise colours, slide directions and other properties.
Please note that dialogs and alerts spawned by Ng-notify are not modal.
This means that they are displayed only while your app is on the screen: if
the product is in the background, the user will not see the information.

NO-CODE FAKE REST LOW-LEVEL CSS TOOLS FIX COMMANDS


json-server BassCSS The Fuck
github.com/typicode/json-server basscss.com github.com/nvbn/thefuck
Use for: optimising development Use for: lightweight CSS styles Use for: correcting commands
The initial stages of a client-server Getting colours just right is a balancing Get one character wrong with the Unix
project tend to resemble a classic act between readability and design: command line and the whole command
chicken-and-egg problem. Front-end great looks and great readability are is refused. The Fuck is a workaround that
development work cannot commence as two kettles of fish. BassCSS is a analyses wrongly entered commands; it
long as the back-end functions have not collection of interesting, core CSS suggests fixes like this Python example:
been set in stone. Json-server addresses elements which can be integrated into apt-get install vim
this problem by providing a surrogate. your application with minimal efort. In E: Could not open lock file /
You specify the desired responses, and addition to that, a selection of 96 var/lib/dpkg/lock open (13:
treat your json-server instance as if it readable and good-looking colour Permission denied)
DISPLAY DATA SETS were the actual production server. schemes, layout and typographic utilities, E: Unable to lock the
Clusterize.js Json-server automagically takes care of and reuseable layout modules are administration directory (/var/
nexts.github.io/Clusterize.js returning data as required. provided for you. It claims to be lib/dpkg/), are you root?
Use for: improving the frontend Using the product is sensible not only responsive by default as its lightweight fuck
Displaying large amounts of from a front-end perspective. and flexible enough to work on any sudo apt-get install vim
information in a list is challenging and device. You can use one or more of them
having to handle thousands of DOM in your app by simply copying its style
elements can overwhelm even the declaratons into your CSS file.
fastest of browsers. Clusterize.js helps us
solve this problem of data by recycling
the display widgets in a creative way: the
framework holds a small amount of
templates, which then gets populated
with data as soon as the user starts to
scroll. Scrollbars are then fooled into
accurate positioning via the use of
dummy elements. Websites that are
working with the Clusterize plugin will
tend to work significantly faster. Its simply
a must-have if you are using big data sets.
on your site.

97
:HE'HVLJ
The:HE'HVLJAnnual

IMAGE ZOOM JQUERY PLUGIN


Zoom.js opens a pop-up with the image in its full glory: this is <script src=js/transition.js></script>
github.com/fat/zoom.js ideally suited for device reviewers wanting to provide Any individual <img> tags must also then be enhanced
Use for: creating a CSS image dialog their readers with an optional, larger view of interesting with a bit of markup in order to display the images in a
pictorial material. larger fashion:
Displaying images inevitably becomes a balancing act Embedding the Zoom.js plugin can be accomplished <img src=img/blog_post_featured.png
between visible detail and screen real-estate by adding the following three files to your web data-action=zoom>
consumption. Photographers and infographic designers application. Transition.js is not a part of the main Keep in mind that Zoom.js is no solution for the
obviously want their creation placed in the limelight UI framework, but is instead made available as part of the bandwidth demands of large images. Loading a large
designers tend to focus their attention on reading flow. bootstrap framework: image takes some time even if it is displayed in the
Zoom.js solves this problem by transforming small <link href=css/zoom.css rel=stylesheet> scaled-down version: as of writing. Zoom.js is not able to
images into large clickable galleries. Clicking an image <script src=js/zoom.js></script> load a diferent resource as images get clicked.

98
// 20 best Github projects

FIVE TO Tom Preston-Werner


@mojombo TOP TOOLS
FOLLOW Finding himself run out from his company by a (now
disproven) scandal, Tom deserves credit for being the
coder with the idea to give GitHub to the world.
Justice.js
github.com/okor/justice
Use for: analysing web performance
GitHub Figuring out more about website performance can be
@github Chris Wanstrath dificult. Justice displays a helpful footer with key metrics.
Do you use a GitHub service? Then you better follow @defunkt
GitHubs oficial Twitter account, which provides a The current co-CEO of GitHub takes to Twitter from time DeckOfCards
never-ending source of all kinds of information which to time. Following him might be interesting if you are into github.com/crobertsbmw/deckofcards
are interesting for the Giterati. adding a bunch of prominent people to your Follow list. Use for: simulating a card efect with an API
This library re-creates a realistic deck of cards. It is ideally
GitHub Status Linus Torvalds suited to all kinds of card or poker games.
@githubstatus @linus__torvalds
Like most other computer systems, GitHub will go A feature on GitHub wouldnt be complete without a SigmaJS
down from time to time. Following githubstatus is an mention of Linus Thorvalds. The world-famous sigmajs.org
easy way to get notified of planned maintenance and programmer created Git in order to maintain the source Use for: drawing graphs
unplanned server outages. code of the Linux kernel. Displaying graph data can be dificult. This framework
takes care of rendering and even manages interactivity.

RESOURCES & GUIDES Go Pro! Glyphs


enterprise.github.com/home webhostinghub.com/glyphs
The GitHub docs GitHubs free service is not for everyone but you can pay Use for: treating icons as fonts
help.github.com a bit extra and demand the best by going Pro! Its WebHostingHub provides this custom font containing a
Learning about version control systems used to be a definitely worth a try. load of nicely designed symbols.
daunting task. Fortunately, the team at GitHub strives to
make its product as accessible as possible. Visiting the The GitHub blog Bourbon
help pages provides a torrent of information about both github.com/blog bourbon.io
simple and advanced features of their various free and Gossip, updates and the latest news from the house of Use for: enhancing CSS
premium oferings. GitHub can be found in the oficial blog. Sass simplifies long CSS declarations. Bourbon adds
mix-in support in order to make your CSS even shorter.
Search syntax Git Manual
help.github.com/articles/ git-scm.com VideoJS
searching-github GitHub is a hosted instance of Git. More information on videojs.com
Find code with advanced searching syntax in Search box Git looms in the documentation on the website. Use for: showing of video in a widget
This is a svelte-looking widget dedicated to HTML5 video.

slick
github.com/kenwheeler/slick
Use for: making HTML5 carousels
Slick delivers what its name promises: a highly eficient
carousel for highlighting website content and products.

AwesomePlete
github.com/LeaVerou/awesomplete
Use for: autocompleting code
Users hate typing. This slick AutoComplete text box does
its magic without needing bulky external frameworks.

RandomColour
github.com/davidmerfield/randomColor
Use for: generating colours
Generating sensible random colours is an act of art. This
helper library is dedicated to doing one task well.

App Launch Guide


github.com/adamwulf/app-launch-guide
Use for: learning how to launch an app
This repository is a guide containing a list of hints that
makes sure that your app gets attention!

99
The:HE'HVLJAnnual

Build a friendly bot


to enhance your
Slack group
Create a custom bot using Node.js to interact with your Slack
group and help automate processes

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Build a friendly bot to enhance your Slack group

T
eam collaboration is a big part of the for your project and run the npm init command. You are function initSlackBot(botToken) {
development world now, especially as then able to select the default values for most of the var slackAPI = require('slackbotapi');
more of us work remotely. If you work on options here. var slack = new slackAPI({
your own remotely its very important to be npm init 'token': botToken,
able to still chat, share code and ask for help from a 'logging': true
community. Couple these requirements with the benefit 3. Install dependencies });
of being able to control, in some way, your development Use your command line to install the required Node return slack;
processes and you have Slack, the real-time messaging packages and dependencies, adding the --save flag to };
system that you can build upon. automatically save them to the package.json file. The
In this tutorial we will see how we can extend the Slack slackbotapi will form the basis for our project as the 6. Detect changes
features and functions by creating a custom automated wrapper to the Slack API. The bot will work on detecting particular events and
bot, written in Node.js and open source plugins and npm install slackbotapi async lodash request reacting accordingly to these events. Now we will create
packages. We will interact directly with the bot to create walk is-up express body-parser node-slackr -save a function that will output a response when a user (and
custom commands. Well also intercept and manage not the bot itself) joins or leaves the Slack group. We can
incoming data from the Slack servers and services based 4. Autorun function make use of an internal function, getUser, to retrieve the
upon transaction type. We will create an HTTP server in Create index.js in the root of your project. This will user details from a provided ID value.
Node.js that will work with the bot and Slacks custom Slash contain, primarily, the Immediately Invoked Function slackBot.on('presence_change', function(data) {
Command features to run specific tasks and receive input Expression (IIFE) to autoexecute on startup. Provide your console.log(data);
from an incoming Webhook feature. bot name and bot token values and then define a var user = slackBot.getUser(data.user);
With the highly configurable tools and services reference to slackBot, a return object from a new console.log('presence_change detected');
available to integrate by default, as well as those available function, initSlackBot. if (user.name !== botName) {
to enable and develop upon like our bot, Slack is an (function bootstrap() { if ( data.presence === 'active') {
emerging dynamic way for developers, teams and 'use strict'; console.log(user.name + ' has joined.');
communities to share, chat and collaborate. var botName = jeeves'; } else {
var botToken = YOUR_BOT_TOKEN; console.log(user.name + ' has left.');
1. Configure slack integration var slackBot = initSlackBot(botToken); }
Sign up to Slack to get your free channel. Head to the // code to go here }
Integration page (yourteamname.slack.com/services/ })(); });
new) from the menu and scroll to the bottom to see the
Bot option. Enter your chosen bot name and details and 5. Initiate the bot
copy the API token value you are given. Create the initSlackBot function inside the IIFE. This
accepts the bot token as the parameter and then makes
Customise settings
You can customise your bot and have it send a
2. Create Node configuration use of it to instantiate a new Slack API connection. It is random response from a list defined by you for any
To start the project of, you will need to create your Node this connection value that we send back from the message it receives. Check the settings page for
package.json file. You can use the command-line wizard function. We will then reference as slackBot throughout more options on how to do this without coding.
to do this. Now navigate to the desired directory location the application.

Left
Configure your bot and give it some personality with a
name and avatar, should you wish, from the options page
when setting it up

Top left
The application will log to the console when a user leaves
or joins the Slack application, pulled from detecting a
presence change event
Top right
The bot detects the character command in the channel to
run the isup request and then responds with information
for the user

101
:HE'HVLJ
The:HE'HVLJAnnual

7. Plugin management stat.name); isUpRequest has been fired. What we will do next is
To pre-empt our bots functions growing and making our try { define how that event is fired.
single file harder to manage, well create a function that slackBot.use( require( root + '/' + stat. emit.on('isUpRequest', function(data) {
will load in all JavaScript files within a plugins directory. name ) ); isUpRequest(data);
This will enable us to group all of the plugins in specific plugins.push( root + '/' + stat.name ); });
files for ease of maintenance and separation. }catch (err){
slack.loadBotPlugins = function console.error( err ); 11. Make the request
loadBotPlugins() { } When the event is emitted it will run the following
var plugins = []; } function and send in the data from the message. Here
var walk = require('walk'); next(); we strip back the URL from the message text and if its a
var walker = walk.walk('./plugins', { }); reasonable size, send it to the isup method. The bot will
followLinks: false }); walker.on('end', function(){ post back to the channel with a response for the user
// more here console.log('plugins loaded: %s', plugins); using the sendMsg function.
}; }); function isUpRequest(data) {
slack.use = function use( plugin ){ var url = data.text.split('');
plugin( slackBot ); 9. The first plugin url.shift();
}; Now we will create a new file in the plugins directory url = url.join('').toLowerCase();
called isup.js. This will call the isitup.org API for any given url = url.replace('https://', '');
8. Load plugin files URL that we pass the bot. Now we will require the events url = url.replace('http://', '');
Inside the plugin loader we can call the walker object to module as well use the emitter to detect requests. Inside url = url.split('|');
check each file and load every one with a JS extension. It the module we will need a blank bot variable as well as if ( url.length > 1 ) {
will require that file directly for use and also add it to an loading in the is-up package. url = url[1].substr(0, url[1].length - 1);
array that well use in the end event to display all of our 'use strict'; isup(url, function(err, up){
loaded plugins. var events = require('events'); bot.sendMsg(data.channel, url + ' is ' +
walker.on('file', function(root, stat, next) var emit = new events.EventEmitter(); (up ? 'up' : 'down') + ' for me' + (up ?
{ module.exports = (function(){ '...' : ' too.') )
if ( stat.name.slice(-3) === '.js' ){ var bot; });
console.log('loading plugin %s/%s', root, var isup = require('is-up'); } else {
// more here bot.sendMsg(data.channel, 'Did you send me
})(); a real URL? I couldnt match it.' )
}
Running an IRC bot? 10. Emit on <Action> };
If youre running an IRC bot built in Node then you Our module will detect a character in a posted message
wont be alone). Transferring that code to work with and then run a function. In order for us to manage the 12. Module init and detection
the Slack API is incredibly simple and very few
event transmission we will need to request an event emit The return from the plugin module initialises the entire
changes would need to be made.
to run that function for when an event called thing. Passing in the Slack reference we can detect an

Top left
Configure a new Slash Command for your group and
specific channels with custom command options to call
reliable services or remote APIs

Top right
For another example of setting up the slackbot package
check out the official GitHub repository here: github.com/
xBytez/slackbotapi
Right
Generating an incoming Webhook URL for your
application will enable you to send data via HTTP directly
into Slack for custom commands

102
// Build a friendly bot to enhance your Slack group

Free hosting for your bot


One important factor to consider when building your bot is where to host it. You may already have suitable servers (whether physical
or virtual) at your disposal that can serve your Node application accordingly, or it may be enough to run it on your own local machine
during the day and close it down when you finish.
Should you wish to use the Slash Commands to GET or POST to an HTTP server you will definitely need something remotely
accessible, and there are many free options available to you for hosting. OpenShift, by RedHat, ofers a free tier of Node.js hosting (as
well as other cartridges or languages) and has the benefit of deploying your code automatically with every commit to a private Git
repository it creates.

incoming message. Using some string functions we can 13. Incoming Webhook integration // code to go here
then subsequently check for the existence of a specific In a browser visit your Slack group channel integration })();
character to lead the request. If found we are then able menu and select enable an Incoming Webhook. Select a
to fire the isUpRequest event. We can easily do so by channel and then copy the generated Webhook URL as 15. Slackr Webhook
using the following: well need that to associate incoming JSON data from Within the module require the packages to enable our
return function init( slack ){ our application to post back into the channel. Express server. The node-slackr package manages our
bot = slack; Webhook integration as we pass it our generated URL.
slack.on( 'message', function( data ){ 14. Express server plugin Configure your Express server details with IP/host name
if (data.hasOwnProperty('text')) { Create a new plugin called express.js. This will run a and port number.
if (data.text.indexOf('^') === 0 && data.text. Node express server that the bot can interact with. Once var express = require('express');
length >= 4 && data.text.split(' ').length === again, define a module for the plugin and require the var bodyParser = require("body-parser");
1) { necessary files at the top for event management as well var app = express();
emit.emit('isUpRequest', data); as for making HTTP requests. var slackr = require('node-slackr');
} 'use strict'; var webhook = new slackr(your_incoming_
} var events = require('events'); webhook);
}); var emit = new events.EventEmitter();
}; var request = require('request'); var config = {
module.exports = (function(){ "web": {

103
:HE'HVLJ
The:HE'HVLJAnnual

"ip": 'your_server_ip', config.web.ip); 18. Create Slash command


"port": 9999 return server; Back to the Slack group Integration menu, We will now
} }; enable Slash Commands. Create a new command /
}; facepalm. Provide the URL for your Express server route,
17. Notify the Webhook select the HTTP GET method. Customise your command
16. Default route Add any additional routes below the default base. Here for user assistance with hints and descriptions.
The return statement of the module will initialise the we will create a /facepalm route that uses a query
Express server and set up the routes. Here well create a parameter sent in a GET request as the name of the 19. Express in action
default base route for our web app. This can be useful for recipient. The JSON data is sent to the Incoming Run the application using the node index.js or supervisor
sending uptime requests to the domain to make sure Webhook for processing and a response sent via Express index.js command. Visit your express server in your
your bot is always up and running as well as looking out for standard output. browser and test endpoints are accessible. You should
for any issues. be able to send the query parameter to the endpoint to
return function init( slack ){ rapp.get('/facepalm', function (req, res) { generate the expected response to send to the bot.
app.use(bodyParser.urlencoded({ extended: //Webhook notification
false })); webhook.notify({ "text": req.query.user_name 20. Get inspiration
app.get('/', function (req, res) { + Due to its incredible ability to allow custom integrations
res.send('nothing to see here... move ' facepalmed ' + req.query.text }); and extensions, Slack is a popular tool for many
along'); // Express out developers who have built their own open source bots
}); res.send('You just facepalmed ' + req. and plugins. Make sure that you check out the oficial
// custom paths go here query.text); repository listing for inspiration from members of the
var server = app.listen(config.web.port, }); development community: api.slack.com/community.

Top left
Test the endpoints are accessible from your running
Express server in your browser. Also note the default
route and custom command route with expected outputs

Top right
The Slash Command Webhook notification prompts the
bot to send a channel-wide message as well as notify you
of your action
Right
Custom integrations are available for selection, such as the
bot and Slash Commands, to help you create something
specific for your group

104
// Build a friendly bot to enhance your Slack group

Integrations available by default


One of the many benefits of using the Slack service is
the number of services that are already available to
be added and integrated into your group. Whilst free
tiers are limited to a certain number, you will still
have the freedom to choose from those that will
benefit your workflow or the requirements of your
team or community.
The services include a built-in Bitbucket or version
control commit hooks, notifying you of who changed
what; issue tracker services and monitoring tools to let
you know what has broken and helps you to fix it; and
Giphy API tools when nothing but an animated GIF will do
to brighten the day and share some fun.
Couple these with your own custom commands and
you can build something really powerful.

105
The:HE'HVLJAnnual

Create API schemas


with Swagger
Improve your API skills and generate detailed API schemas with
minimal coding and well-crafted documentation

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Create API schemas with Swagger

A
PIs are great they expose content to window and enter the following command. The swagger project edit my_music_app
clients and developers, and can help additional flag will install Swagger as a globally available
manage the state of data across a module so that it is accessible from any directory on 5. Interactive file updates
number of platforms and systems. your machine. You will notice now that the swagger.yaml document is
However, both the creation and consumption of APIs can npm install -g swagger open in the left, and that the parsed readable content is
be tricky when there is untested code or poor on the right, generated by Swagger. Any changes that
accompanying documentation for your references. 2. Project creation are now made to the open file now will be instantly
Ideally you want your code to pass tests and you want Within the CLI navigate to the desired location of your visible in the right as well as automatically saved to the
your clients or consumers to know what to send and project. Run the Swagger create command, providing file in your local code editor. Try changing the title value
what to expect back from each response. Providing these the name of your new project. The module will display to test this out.
crucial details without spending too much time on options for you to choose your desired Node REST
creating this information is key, and Swagger is here to framework to work with. Were selecting Hapi.js but feel
help you do just that. free to choose your own.
In this tutorial we will take a look at Swagger and how swagger project create my_music_app
we can build an API and its underlying definitions and
documentation using common Node.js frameworks. 3. Run the API
We will start of by installing the required Node With the project created, lets see what the skeleton
modules and libraries to get up and running, look at application has built for you. Run the command to start
some of the available features of Swagger to generate your Swagger project, which will run the underlying
skeleton applications and sample code to use as a Node server on a local port instance. Visit the URL
reference, and finally we will learn how to run local provided in the command-line interface to see the
iterations of your API with and without writing any sample REST endpoint in action.
underlying server-side code. swagger project start my_music_app -d
Using the highly readable YAML markup structure and
4. The Swagger editor
the flexibility provided by the Swagger library and Node
implementation, you will be writing and releasing In this step we will now run the following command to
Unit testing
If you want unit tests, then you can always put
well-documented, well-structured APIs in no time at all. open the editor and load up the current project. This will
Swagger to work and make it generate tests by
run a local server and automatically open up in your using the information that you have already
1. Install Swagger default browser to show you the associated given it about your schema definitions. Take a
To begin with, you will need to install the Swagger Swagger.yaml file and this will form the core of your API look at Step 20 to find out how.
module. Open up your terminal or command prompt definition and documentation.

Left
Install the required Swagger Node module as a global
dependency to make it available in whatever directory
you choose to work in

Top left
The project creation wizard will guide you and offer a
selection of industry-standard proven API frameworks for
you to work with
Top right
Here we are running the built-in server in debug mode,
using the optional flag and calling the default API method
directly in the browser

107
:HE'HVLJ
The:HE'HVLJAnnual

6. Live testing here dictates the name of the method in the controller to 9. Error response definition
The generated sample application includes an API call for this route. The API will respond with some form of info and we need
endpoint, /hello, which can be accessed directly in the paths: Swagger to be able to manage these responses, whether
browser if the Swagger API is running. It can also be /artists: they are good or bad. Create a response element and set
tested live using the Swagger editor. Click the Try this x-swagger-router-controller: artists the default schema to reference an error response
operation button to use the editor to interact with your get: definition for anything other than a 200 status code,
API and view returned header and body information. description: Returns an array of artists which we get to in the next step using the $ref syntax.
operationId: getArtists responses:
7. Create your own path default:
Now we will work on the paths, so under the paths 8. Send parameters description: Error
declaration, lets now create a new path for /artists. The Our route definition will be used to filter a remote API to schema:
custom Swagger route controller will map this path to a query for information. As such, we will want to send $ref: "#/definitions/ErrorResponse"
new artists.js file that we will be creating shortly. We want values through to the endpoint as well as ensure we
to manage a GET HTTP request. The operationId value document these too. Set the parameters block and then
nest a resource called artistName, a string which will be 10. Successful responses
expected as a URL query parameter. Add the successful response definition to the block,
parameters: setting the status code as the success requirement. Any

Automate tasks - name: artistName


in: query
200 status will be classed as a success and will therefore
use the applied schema reference which well set here as
You could further optimise your Swagger tasks
and unit tests by adding them to a Grunt or Gulp description: the name of the artist to getArtistsResponse.
task file. You could then run your tests with every search for "200":
file save to make sure that your tests required: true description: Success
continuously pass. type: string schema:
$ref: "#/definitions/getArtistsResponse"

Top left
Open up the Swagger editor on a local private port
server to edit your YAML file and interact with the API
through the available testing interface

Top right
The editor uses a common module to manage the actual
code editing and the interface acts and behaves like a
standard editor tool complete with code folding
Right
Testing the API default method directly from the Swagger
editor gives you information on the headers and body
response for quick visual debugging

108
// Create API schemas with Swagger

Swagger specifications
The Swagger.yaml file forms the core of your API definition process and is the key ingredient to Swaggers interpretation of your API
requirements. Written in standard YAML markup, its very easy to read and manage. There are a lot of options and sections or
properties for you to use, should your API require them. They may seem a little overwhelming at first glance though, but there is a
wealth of options available that can help you to build your perfect API definition.
You can find out all you need to know and all of the available Nodes, properties, types and options that are open to you in the
incredibly detailed Swagger specification document, available on GitHub here: bit.ly/1Lw18nU.

}, type: "object"
11. Response data modelling properties:
In our example we now have the intended structure of "followers" : { artists:
the response JSON data from the API a benefit of "href" : null, type: object"
calling a remote third-party solution. We can use this "total" : 23552 description: "The core artist response
structure, to build up our response schema for Swagger }, properties:
validation, documentation and testing purposes. total:
{ type: "number"
"artists" : {
"href" : "https://api.spotify.com/v1/search? 12. Core response model 13. Nested arrays
query=butch+walker&offset=0&limit=20&type=ar Create the success response schema within the The oficial API response will return an array of
tist", definitions section, as we have referenced previously in information within the artists block called items. Add this
"items" : [ { Step 11. We will now expect an object back with the root to the schema by setting the type accordingly. If you
property of artist, which we will expect to be an object. declare an array now, Swagger will require you to then
"external_urls" : { By building up the nested properties we can set the set the children for each item, using the second nested
"spotify" : "https://open.spotify.com/ definitions for our API response. items block.
artist/7qKoy46vPnmIxKCN6ewBG4" getArtistsResponse: items:

109
:HE'HVLJ
The:HE'HVLJAnnual

type: "array" description: "The artists popularity"


description: "The array of artists matching uri: 17. Import the module
the criteria" type: "string" Here well be using a Node module packaged and ready
items: description: "The artist uri" for use to make our interactions with the third-party
type: "object" Spotify API easier. Install the module and save it as a
dependency to your project so it is registered with your
15. Run in mock mode package.json file.
14. Continue as required Creating such a detailed response definition and setting npm install spotify-web-api-node --save
Now continue to build up the expected response each property type lets you mock a response as you
schema for as many properties as you need too. The write your Swagger doc. By running the internal server in
benefit of writing this in the YAML structure is the ease of mock mode, you can obtain a sample response using 18. Create your controller
readability and maintenance, and thats due to the the provided types without writing any controller logic. Create a new file called artists.js in the api/controllers
nested properties. You can add description blocks here swagger project start -m directory of the project. This filename matches the one
to help enhance the generated documentation too for or given for the x-swagger-router-controller value earlier.
API consumers. swagger project start mock The operationId value matches the method exposed in
properties: the controller, in our case getArtists.
id: 'use strict';
type: "string" 16. Compare mock response
description: "The artist id" With the internal mock server running, hit the artists var util = require('util');
name: endpoint in your browser. The mock data will be basic var SpotifyWebApi = require('spotify-web-
type: "string" low-level responses but they will match the type api-node');
description: "The artist name" specified for each property you created earlier. Compare
popularity: it to the oficial API response and confirm your structure var spotifyApi = new SpotifyWebApi();
type: "number" is as intended. module.exports = {

Top left
The desired response that we get from the third-party
API request will now enable us to fine-tune our internal
API response definitions

Top right
Add as much information to the response schema as you
can. Document every property where possible to improve
user adoption
Right
Running the server in mock mode helps your definitions
improve as you build them without writing any server-side
controller code

110
// Create API schemas with Swagger

Above
Using the CLI tool, contextual help is always at hand with the inclusion of the optional -h flag with each command }, function(err) {
console.error(err);
});

};

20. Generate tests


Use Swagger to assist your code quality and delivery.
Running the following command will ask the library to
create a test suite for you using the route options and
response definitions that you have declared in your
Above Swagger.yaml file.
The Swagger editor will parse and verify your config file as you work on it and will let you know if you make a mistake
sudo swagger project generate-test

swagger project run-test


getArtists: getArtists function getArtists(req, res)
} {
var artistName = req.swagger.params. 21. Separate modules
artistName.value; Swagger is versatile, and can be used with pretty much
19. Method definition spotifyApi.searchArtists(artistName) any programming language or framework that you
The getArtists method will be called by the API route, .then(function(data) might prefer. Each toolset, including the editor, the live
and it will need to check for the artistName value, sent { testing user interface and the core module itself, are
through in the request context as a parameter. We are console.log('Search artists by "' + available to download separately should you wish to use
then able to send that value to the third-party API and artistName + '"', data.body); them. A great resource for tools and community
forward the JSON response on to the end user as might language additions can be found here: swagger.io/
be required. res.json(data.body); open-source-integrations.

111
:HE'HVLJ
The:HE'HVLJAnnual

FUTURE
HTML
Web Components, the new standard in
modular HTML development

Tom Dudfield Tim Stone


Senior developer Lead front-end developer
@tomdudfield @timofetimo

Web Components are a huge step towards Web Components will soon become the de
a truly modular way of developing facto way to code reuseable widgets.
front-end interfaces. This mirrors design Support isnt universal because it relies on
practices that have been so successful and implementing four standards, but you can
stable within C# development use it today with polyfills.
for some time.

112
s GET
ILO

ON FILES

TH
IS FEATU
// Future HTML

DE
RE
S FULL CO

file

er
sil
o.c ign
o.uk/webdes

Luke Fribbens W eb Components are a totally new way of


building parts of a website that replaces
HTML, CSS and JavaScript and are only really
Development director at IA Digital used by the mysterious, masters of the web,
who tell us all how such things should be done,
@iadigital right? Wrong. Web Components have been
around for a long time, hiding just beneath the
surface of our beloved HTML. They are simply a
combination of HTML, CSS and JavaScript
packaged together as an HTML element.
Web Components are a developers dream.
Web Components actually account for many
We have seen componentisation and its
of the huge strides that have been made with
advantages in other parts of development
for years this is the next big step. The best HTML5. One of the best examples is the <video>
thing since HTML5! element, by simply adding a src value to this, your
video is displayed in the browser with button
controls and time indicators, you have a player
from just this one HTML element. These are all
actually Web Components, we just never thought
to stop and look at them all. When you saw this as
part of the HTML5 specification you may have
thought, Wow thats great, but have you ever
wondered how this was all built? How are the
components we use and take for granted every
day actually created?
Matthew Bowden Plus, we cant just define HTML spec for
Creative director at Vitality Health ourselves, can we? Well that is exactly what we
can do. Browsers have been working really hard,
@matthewbowden over the past year or so to give developers access
to this hidden part of HTML. We are not quite
there, but the direction taken by all browsers to
do just this is a good sign of things to come.
There are also a host of JavaScript polyfills
Tuck away the code we love to tinker with
and youre left with components exhibiting available to give us the methods needed to take
consistent behaviour, rendering correctly full control of our own HTML.
and most importantly, enabling a coherent Web Components are constructed with four
brand experience across applications. core elements of support that browsers have
been working on. Custom Elements enables the
creation and manipulation of custom HTML
elements. HTML Imports can import packaged
HTML, CSS and JavaScript into an HTML page,
whereas HTML Templates holds content or
information that is not rendered on page load, but
is available to render at runtime. Finally, Shadow
DOM enables the structure of a web component
to be separated from the DOM of the page

Simon Hutchings providing encapsulation. These four elements will


be explained in more detail on the next page.
Owner of Visualise Graphics The importance of this change in HTML
@Simonhutchings development cannot be overstated. The evolution
of HTML as a language, although excellent, has
been pretty slow going. This is mainly due to it
being in the hands of the browser vendors, with
possible developments/ideas submitted by the
general development community. These
Web Components provide so much more browsers then prioritise areas of development
control of our markup this is a and gradually define new specifications and build
fundamental shift in how we develop support for these into their applications. But the
for the web. ability to build our own Web Components gives
the entire community control to directly
contribute to the evolution of HTML.

113
:HE'HVLJ
The:HE'HVLJAnnual
Future HTML

The four core


elements Web Components V
Custom Elements
Probably the most obvious aspect of a web
Web Components Pros Web Components Cons
component is the ability to create, modify and
control HTML elements. The introduction of Custom
Elements into browser standards enables us to break
A wealth of UI components are already Standards could be ignored causing a
being built and reused by the confusing array of HTML elements,
away from the limited vocabulary that HTML ofers. This development community. many of which are doing the same job.
means we can create true markup semantics that are
really meaningful in context of the application, whatever
Complex UI functionality can be Working with code created by another
that may be. Gone are the days of endlessly nested <div> achieved using very little HTML markup developer could be confusing and
tags with a littering of classes trying to suggest a within the page DOM. dificult to use.
structure as Custom Elements provide us with the ability
to write truly beautiful HTML. All of a components CSS and JavaScript The current amount of documentation is
There are a range of new JavaScript methods that is encapsulated, and this provides currently limited. However, as the
enable you to create, register, style and add JavaScript separation from the page DOM and standard develops support for HTML,
stability as standard. builds will only increase.
properties and methods all within one new HTML
element, and these are outlined really well at html5rocks.
com/en/tutorials/webcomponents/customelements.
One thing that is worth noting is that standards have This can be achieved by using the <content> tag within This is where HTML Imports come in, the <link> tag
been defined for the naming conventions of Custom your template and then attaching that template to the can be used with a rel attribute value of import, and this
Elements. Any element must contain a hyphen, this desired element with content. tells the browser to import the contents of the source file
ensures that Custom Elements are easily identified as Anything within a template is not rendered in the into your page. It seems just like an include but when we
such amongst core HTML elements, as well as mitigating browser on load but simply made available to be combine this with the HTML Templates we can keep our
the risk of any conflicts with future core HTML elements. integrated with the DOM using JavaScript. Any content template code blocks, including any CSS and JavaScript,
within a template can be used and reused as you wish in separate files. Our working code becomes just as well
. and if bound to new Custom Elements within it, then the written as that seen by the browser, and templates are
HTML Templates Shadow DOM can be kept out of the DOM as we know it. even easier to share and reuse.
Templating HTML markup is not a new concept, there
are many frameworks that provide this type of
approach to building a user interface. They all provide HTML Imports Shadow DOM
a more streamlined way of managing blocks of HTML, So if we are creating a load of new Custom Elements So last but most definitely not least, we have the
but HTML Templates as a defined part of HTML spec is and templates and bringing these components Shadow DOM, this is arguably the most powerful part
much more elegant. together, our HTML markup is going to get cluttered of Web Components. Each HTML element in the DOM,
The new <template> tag can be used to bundle HTML, and confusing really quickly. This could rapidly lead to whether it is core or custom, can have its own DOM
CSS and JavaScript together and keep all of its contents unmanageable markup and even more verbose code hidden within it.
encapsulated. Think of these blocks of code as reuseable than before we were using these new techniques. One of The JavaScript method createShadowRoot() can be
snippets that are easily shared with other developers and the key benefits of using Web Components is the used to create this for a new Custom Element. A template
projects. The time spent writing the same HTML elegance of the code that can be produced, its all good that has been imported can then in turn define the
structures will be dramatically reduced without the need for your code in the browser to be beautiful, but if the structure of this Shadow DOM. It works by bringing all
of a framework to do so. Content can be used within a code you are working with is a mess then something is four elements together and giving us a fully functional
template that resides outside it within a DOM element. obviously isnt quite right. web component to work with.

Tutorial 1. Install Node.js and Bower D:\Web Designer Mag\Web Components Feature\
The recommended way to use Polymer is to install using my-component
Hands on with Web Bower via Node.js. Make sure Node.js is installed and bower init

Components install Bower. The -g flag installs Bower globally too. bower install --save Polymer/polymer#^0.5

3. Create your first element


T his tutorial will take you through using and
creating Web Components within your projects.
As browsers are still undergoing development to
npm install g bower

2. Add Polymer to your project


Use an HTML Import to use Polymer to create your
Custom Element using <polymer-element>. Add this as a
support Web Components, Polymer will be used. Now use Bower to install Polymer within your project. new HTML file. The name of this element is added as an
Polymer is a component polyfill and library created by Make sure you are within your project directory and then attribute and the contents held within a <template> tag.
Google (polymer-project.org). This adds support to all install it in your CLI as shown. The bower init command
modern browsers as well a host of preset components will ensure a bower.json file is created. The --save flag will <link rel="import" href="../bower_
ready to use. add Polymer as a dependency within this file. components/polymer/polymer.html">

114
// Future HTML

Chrome

Firefox
S Standard HTML

Opera

Safari

IE
Standard HTML Pros Standard HTML Cons
Browsers know how the current HTML The development of new elements is
standard works and ofer wide support. currently a slow process.

Taking control of new elements is Restricted by decisions and


restricted and standardised by the prioritisation of browser dev, which goes
current set of browsers. against the open web as a concept.

The best thing about the current HTML .


Large complex HTML structures are
standard is that it is already a universally required to produce common UI
recognised language. This means that elements. Our UI elements are not
millions of designers and developers encapsulated from the rest of DOM,
already know how to use it. causing CSS.

There is much more going on here than it may seem, Check out Polymers
Elements collection
the Shadow DOM is not just a way of hiding code, it for ready-made web
components
actually deals with the encapsulation issues inherent in bit.ly/1NJDruG Key Supported Draft Unavailable
HTML, CSS and JavaScript.
For example, if you styled a selector that just
happened to match a selector within your Shadow DOM
you would expect it to be afected. But the Shadow DOM Browser support
protects its contents from this, keeping a defined scope The specifications for Web Components from
for the component. This is vital in enabling the production W3C are still in progress but browsers are
of reuseable components. The door is not completely working to these. Chrome and Opera are leading
closed though, you can style the contents of a Shadow the way with stable support for all four aspects of
DOM by using the ::shadow selector in CSS, or Web Components. Firefox have full support for
alternatively style an element from its own Shadow DOM Templates and both Custom Elements and
using the :host selector. Shadow DOM support are close. Safari supports
The Shadow DOM seems like black magic at first, but Templates, and Internet Explorer are collating and
when you use it youll notice that its used everywhere. prioritising their development roadmap for Web
Components. All these browsers are working to
the same goal, which is the future of HTML as we

Custom Elements provide know it. It can be dificult to stay up to date with
support of so many development paths, the site
us with the ability to write truly jonrimmer.github.io/are-we-componentized-yet
provides links to information on the paths.
beautiful HTML

<template>

<polymer-element name="my-signup" noscript> <!DOCTYPE html>
<html>
5. Style your element
Within your element file, add a <style> tag to the template
<p>Hi this is <strong>my-signup</strong>. <head> and adjust how the <p> tag is displayed. Add another <p>
You are looking at the Shadow DOM</p> <script src="bower_components/ tag to your index.html.
</template> webcomponentsjs/webcomponents.min.js"></
</polymer-element> script> //elements/my-signup.html
<link rel="import" href="elements/my-signup. <polymer-element name="my-signup" noscript>
4. Create your app html"> <template>
Add an index.html file to your project root. Load the </head> <style>
webcomponents.min.js polyfill from bower_components. <body> p {
Import your new Custom Element and then reference <my-signup></my-signup> font-family: Verdana, sans-serif;
this. When viewed in a browser you will see your Shadow </body> font-size: 1.2em;
DOM content and be able to inspect this using Chrome. </html> color: #912A07;

115
:HE'HVLJ
The:HE'HVLJAnnual
Future HTML

Four great building tools Understand


the standards
Before you dive in, make
sure that you get your
TOOLS, RESOURCES AND DEMOS THAT HELP ESTABLISH A NEW CODING APPROACH head into the standards
and best practices. We
will all benefit from this
in the long run, all
Polymer POLYMER-PROJECT.ORG developers have been
The Polymer project was started by bitten by maverick
Googles development team coding at some
and makes the Web point. If you
Components landscape havent already,
much easier to move to. Any then you will be
polyfills required to support Web soon enough.
Components across browsers is
immediately available. On top of that
Polymer ships with two element
collections of prebuilt elements ready
for production use Core and Paper.
The Core elements encompass many
useful, single purpose components for
core functionality. These work with layouts,
inputs, data handling and general application
structure components. The Paper collection
Bosonic BOSONIC.GITHUB.IO
covers much more UI-focused elements that
are highly visual and interactive, and incorporates Bosonic is a good alternative to Polymer, it
controls, interactions and UI transitions. provides similar polyfills and the tools required
There are a wide range of demos within the to build Web Components across even older
Polymer project that can help you get up to speed browsers (including IE9). The syntax for the
with using and building Web Components. There are element creation matches the current W3C
tutorials demonstrating key aspects of web component specifications exactly and working with it is
builds and the actual API documentation is excellent. very similar to working with Polymer.
The Polymer project team have even produced a There are a range of elements available
Designer tool for quickly prototyping apps using for production. This is all available on
Polymer and the ability to save experiments within GitHub github.com/bosonic/bosonic
GitHub (polymer-designer.appspot.com). and open to community contributions.
Polymer is built based on the (still-in-progress) W3C The getting started guide and
specifications for Web Components, with the view that when documentation is structured in a step
browsers have adopted full support the transition from the by step, making it great for learning about
polyfills to native support will be smooth. All Polymer code is Web Components. If you want to get involved in
available on GitHub (github.com/polymer), and benefits from developing and contributing to a Web Components framework,
ongoing open source development. Any bugs can be reported Bosonic is a good choice. It is well structured and open but without the
directly and visibility of upcoming releases is readily available. scale of contributors as Polymer (at present).

} 6. Style the element host 7. Style the element from your app
</style> If you add :host as a selector to your element styles, you Any new Custom Element can be styled from its parent
<p>Hi this is <strong>my-signup can style the parent element of your Shadow DOM, ie page (in this case this is index.html). If you add styles to
</strong>. You are looking at the Shadow style the Custom Element tag in your index.html from this page for your new element they will overrule those
DOM</p> within the element itself. set using the :host selector. But the elements within your
</template> Shadow DOM will still be protected.
</polymer-element> <style>
//index.html p { <style>
<body> font-family: Verdana, sans-serif; my-signup {
<p>This text is within the page DOM and is font-size: 1.2em; background-color: red;
unaffected by component styles.</p> color: #912A07; }
<my-signup></my-signup> } my-signup p {
</body> </style> color: white; /* this will not work */

116
// Future HTML

WebComponents.org
WEBCOMPONENTS.ORG

This resource site brings together the best


practices, updates and developments of
everything Web Components related. It provides a
wealth of useful content, from presentations and
podcasts given by web component framework
developers to the current state of native browser support.
The explanations around the base polyfills (used by all
libraries) can give good insight into the work that has
already gone into enabling us to work with Web
Components today. There are also key links to galleries,
libraries and the web component development community,
many of which are instrumental in the development of the
tools we have already mentioned.
One of the best things to take a look at on this site are the
presentations, they are often an opportunity to see how other
X-Tags X-TAGS.ORG
developers are using Web Components or what they are trying to
X-Tag is the ofering from the Mozilla team, achieve. This is a great place to keep coming back to and will help
and is a small library providing the ability to build, you to keep up to date in the Web Components landscape.
extend and manage your Web Components. This is built The core vision of this site is to provide a reference point for
from the same W3C polyfills that are provided by the Polymer everyone in the open development community, ensuring that
project with extensions to ofer IE9 support. Web Components best practices are defined and followed,
This library uses JavaScript to register new elements and making life easier for all of us.
this script references any HTML Template elements that are
to be used, opposed to the Polymer approach of the
<script> being integrated into a <polymer-element>
alongside the HTML Template. Internet Explorer 9
One of the most comprehensive examples of use is Remember Polymer does not support
Mozillas Brick (mozbrick.github.io), a collection of ten Internet Explorer 9, so if you do actually
UI components that can be reused in production for need to support this older browser for
building interactive UIs. It is actually available as a Bower installation your project then X-Tag or Bosonic would
and is a really quick way to start using these components in your project. This be a better choice of library.
library could rapidly evolve, but at present it doesnt have the uptake that Polymer has.

Essential polyfilling lessons have been learnt from previous technology This concerted efort to work to a best practice
SUPPORT MUST BE DONE CONSISTENTLY developments. There is a base set of Web approach means that as native support increases,
As with any new browser technology, it takes time Components polyfills available on webcomponents. the removal of such polyfills will be easier. Currently,
to establish a stable specification, consistent js (webcomponents.org/polyfills) that are actually these fixes are a necessity, but based on the rapid
rollout across all browser vendors, and the best used consistently by web component libraries. progression of support and the wide range of
practices to be defined by the community. Web Some of these aforementioned libraries extend reuseable components already available, it wont be
Components are no diferent, but it does seem that them but this core set remains. long before they are no longer needed.

}; }; 10. Add values to your inputs


</style> </style> Extend the input elements to have values that are set to
namespaces within handlebars templating syntax. This
8. Overruling shadow styles 9. Build the signup form will make any value entered available within the context
If you use ::shadow you will find that any styles defined Add the signup form markup and default styles to the of our component. You should see the name value
within a component can be altered. template. The styles dont afect the rest of our page so within the <p> tag as you type.
base CSS selectors can be used without conflicts.
<style> <p>{{name}}</p>
my-signup { <polymer-element name="my-signup" noscript> <div class="form-row">
background-color: red; <template> <label>Name:</label>
} <style> <input type="text" id="signup_name"
my-signup::shadow p { :host { value="{{name}}" />
color: white; /* this will work */ display: inline-block; </div>

117
:HE'HVLJ
The:HE'HVLJAnnual
Future HTML

goals of many application frameworks of today. The main

The community diference is that this approach will be standardised


across browsers in the future.

One key diference between the development Share what you find Share your code
community for Web Components and that of other Dont assume that just because the blog post you have Most libraries of Web Components provide the means for
new technologies is the sheer amount of people that found is a few months old, you are the last to find it. Share users to submit their own elements for inclusion, if you
Web Components does and will afect. It will be it with your network and talk to your colleagues about have written something useful, it will probably be useful
impossible for anyone working in web development to what you find out. Only by doing this and encouraging to someone else too. Additionally most Web Components
completely avoid using Web Components and it is easy others to do the same will the community as a whole be projects are available on GitHub, if you find or fix issues
to underestimate the impact this may have on the able to drive forward maintaining the rate of progression then do so here so that everyone can benefit.
industry. With all this in mind the collaboration of we have seen over the past year. There is an established community of developers who
everyone involved is vital to ensure that the road to full are already contributing to the Web Components
web component support and take up is as smooth as it landscape. If you arent sure about something then they
possibly can be. Using Web Components can help and answer your questions. We will probably
Even if you start on a small scale, Web Components are see a lot more conference talks and presentations on the
all ready for use in your projects. They provide excellent subject over the next two years, so keep an eye out for
Keep up to date code separation and reusability which is one of the key those as well.
Keep an eye on the progress of W3C specifications,

Most Web Components projects are


browser support for all of the key aspects of Web
Components and the elements that are added to libraries
in any updates. All of these areas will continue to drive
and define the best practices that will end up being
available on GitHub, if you find or fix issues
followed by all, keeping us on the same dev path.

11. Introduce some script


Add a <script> tag to your element. Within this, call the
then do so here so that everyone can benefit
component and doing something with them. Add the
nameChanged method to your script and whenever it is
15. Match the email fields

This can now be used to validate that both email fields
core Polymer class and set a default value for the changed, the name will be logged out in console. match. Adjust the validate function to check the fields
{{name}} property weve defined in the markup. Remove against each other and create a new email_match
the noscript attribute from the <polymer-element> tag. <script> property within the component for tracking the fields.
Polymer({
<polymer-element name="my-signup"> nameChanged: function() { validate: function(oldVal, newVal){
<template></template> if(this.name){ if(this.email === this.email_confirm){
<script> console.log('Hi ' + this.name + ' I am this.email_match = true;
Polymer({ listening!') }
name: "Luke" // you can set a default value } else{
here } this.email_match = false;
}) }) }
</script> </script> console.log(this.email_match);
</polymer-element> }
14. Watching groups
12. Pass data to your component Another change watcher Polymer provides is the 16. Display an error
If we know the users name we can prepopulate it. Add observe method. This can watch multiple properties and Add an error message within the element to be
an element attribute and include it as a listed attribute on fire when any of them change. Add an observe list to displayed to the user. Use the hidden attribute bound to
our Polymer element (the attributes value can be a both email properties and bind these to a validate our email_match property. This only appears when the
comma separated list to define multiple attributes). method. The values will be logged out when changed. emails dont match. We have field match validation here.

//elements/my-signup.html <script> <div class="form-row">


<polymer-element name="my-signup" Polymer({ <label>Confirm Email:</label>
attributes=user> observe: { <input type="email" id="signup_email_
email: 'validate', confirm" value="{{email_confirm}}" />
</polymer-element> email_confirm: 'validate' <span hidden?="{{email_match}}">Your email
//index.html }, addresses do not match</span>
<my-signup name="Luke"></my-signup> validate: function(oldVal, newVal){ </div>
console.log(newVal)
13. Watching properties } 17. Set default validation
Polymer has a range of changed watchers that are }) You may notice that the error message is appearing
excellent for reacting to property changes within your </script> before the user has even started to enter an email

118
// Future HTML

Inspecting the Discover more


Shadow DOM
HOW CAN WE WORK WITH THE HIDDEN DOM?
EXPLORE A WEALTH OF COMPONENT EXAMPLES
TO USE, ADAPT OR MAKE YOUR OWN

Accessing the Shadow DOM feels a bit like spying but Custom Elements
it is actually quite simple. In Chrome developer tools CUSTOMELEMENTS.IO
access the settings using the cog on the right of the With over 900 elements, Custom Elements is a
inspection panel. Under Elements check Show user huge gallery of Web Components created by
agent Shadow DOM, then restart the browser. Now the development community. If you need an
when you inspect the HTML of the page you will see a element fast, this is the place. It is open to
new node wherever a Shadow DOM is present named submissions and each element is available to
#shadow-root, you can expand this node to see what is fork on GitHub for any adaptations.
actually in the Shadow DOM. Without this it would be
very dificult to debug any of the problems within our
Web Components.
Additionally this gives us the ability to interrogate
other Web Components that we havent created
ourselves. By doing so we can ascertain how to adjust
the styles of a core HTML component such as changing
the colours of the HTML5 video player, or enable us to
understand how a Custom Element has been built. Its
worth taking some time to dig around looking for the Component Kitchen
Shadow DOM and seeing what you find, you may be COMPONENT.KITCHEN
surprised how prevalent its use is already. The Component Kitchen combines some good
tutorials alongside a comprehensive library of
Custom Elements. Each element has its own
address, this is because the email_match property does 20. Use Polymer core elements page with usage information and fully working
not exist until these properties are changed. Add a Polymer has a range of core elements that can be demo. Within the Developers section of the site
default value for this as true within your Polymer script. used. We will utilise the core-ajax element and this you can find out how to register your own
will enable us to POST the form data to a web elements with Component Kitchen including
<script> service. All you have to do is import the core- setting up your demo page.
Polymer({ components-page.html into your element and add
email_match: true the element to your HTML with the form data set as
the body attribute.
})
</script> <link rel="import" href="../bower_
components/core-component-page/core-
18. Style the validation component-page.html">
Add some further styles within your element to display
the error message to go alongside the Confirm your 21. Make the POST url dynamic
email field. Again there is no need for a specific error To use this signup element in multiple instances you Polymer Elements
class here as this is the only instance of a <span> tag will need to be able to change the POST url. Make BIT.LY/1OICUL0
within the component. sure that you add this as an attribute on the element Although not as large as the previous two
in index.html, extend the listed attributes on the component libraries, Polymer Elements is
span { polymer element itself and finally reference this excellent and consistently built. The
font-family: Verdana, sans-serif; property in the core-ajax element. documentation for each of these is very easy to
font-size: 0.8em; follow and the range available provides most
display: block; //index.html base application functionality and UI interactions
width: 294px; <my-signup name="Luke" url="http:// to help you build engaging Web Components-
margin-left: 148px; dummypostservice.com"></my-signup> based solutions right now.

19. Add a submit method 22. POST your data to a service


Now add a submit function and bind to an on-click event Finally add a handleResponse function to your script
on the button. Within this function bring the name and and call the go method on the <core-ajax> element
email properties together so that they are ready to be within your formSubmit function. This will POST the
posted to a HTTP service. formData and the response will then be returned to
the given method (you will need a POST service
submitForm: function(){ available to fully run this last step, but you can stub it
this.formData = { using Node.js).

119
' H V L J
122: Your best CSS ever

130: Create a colour swatch


tool with Vibrant.js

134: Alter page element colour


138: Build custom layers
with CSS

142: Expert guide to web 3D


150: Interactive 3D game
with WebGL
154: Image-based
pop-up menus

156: On-click popup tooltips

158: On-click transitions

160: Latest CSS4 selectors


164: Circular on-hover
animation

166: Flick background image

168: Slide down on scroll menu


170: The importance
of typography

178: Animate type & text

182: UX design
188: Enhance UX with
Hover CSS

120
150
142

178
188
:HE'HVLJ
The:HE'HVLJAnnual

N I Q U ES ANND
H
S E NTIAL TECG PERFECTIO
ES I N
T O P TOOLSI,CE FOR STYL
THE BEST ADV
THE
// The best CSS ever

Analyse your CSS 5 top tools


ESSENTIAL TOOLS & TECHNIQUES TO GET PERFECT CODE EVERY TIME GET YOUR CSS IN TIP-TOP SHAPE

C SSLinting is just like any other type of linting, in


that it is a tool that flags suspicious usage in
software written in any computer language (from the
more specificity later in the stylesheet, heading styles
should be declared once and not need to change.
Again, this is a bit extreme for the everyday project
CSS Beautifier
html.fwpolice.com/css
Wikipedia page on programmatic linting). Front-end team. Its likely that the complexity and number of A quick and simple option for creating easy-to-
developers are likely aware of JSONLint and JSLint. Well heading styles that can be seen on any website is read code.
now theres CSSLint, which analyses CSS and helps defined by the design team.
developers write CSS that conforms to a set of
performance and syntax of best practices. Dont use too many floats
Helps is understating it really, CSSLint throws errors Lots of floated elements on an individual page cause
and if used as part of a build server say, TeamCity for longer paint times because of the extra layout
example it will cause builds to fail. calculations that browsers have to go through. However,
This is both a good and a bad thing. It means the rules unless you organise your CSS on a per-page basis, this
are enforced with harsh penalties, but bad rules will rule is completely arbitrary.
create an upsetting development environment.
Thats the rub really some of the out-of-the-box Dont use adjoining classes
defaults of CSSLint are controversial, so it pays the This is blacklisted because of browser support. IE6
project team to take time customising the rule set. Here doesnt support selectors that look like this: ProCSSor
are some of the ones that draw controversy for many. class-one.class-two { tools.maxcdn.com/procssor
/* */ Helps clean and organise CSS the way you want it.
FIVE RULES TO FOLLOW: }
Turn this rule of if the project ofers legacy support
Dont use IDs towards IE6 users.
Its not that there is anything inherently wrong with IDs,
just that the Object Oriented ideology CSSLint was born Better code hygiene
of rejects them. OO-CSS says all CSS should be All of these bad defaults make CSSLint look like a bad
reuseable, so the concept of writing an ID into a CSS tool. It really isnt there are real advantages to rolling this
selector is very foreign. OO-CSS takes the stance that tool into a project teams build processes.
there should be no unique CSS. CSSLint enforces syntax and code standardisation
For the everyday project team, this is likely an extreme across the project team on a project-by-project basis.
view, and it isnt relevant if OO-CSS methodology isnt This code hygiene should make it easier to developers
being employed. working on the project and make the codebase easier to W3C CSS Validation service
work with as a whole. Accessibility can be enforced with jigsaw.w3.org/css-validator
Style headings once, globally styles like outline:none being outlawed. CSSLint also Built by the community with three options for
What CSSLint is getting at here is when developers write enforces the bulletproof font-face syntax the best way validating code.
styles for heading elements and then redefine those with to implement @font-face.

Style secret
CSSLint has a Wiki over at GitHub To follow
that details all of the default rule
options. Each rule has its own page CSS-Tricks
which goes into depth of what the @Real_CSS_Tricks
rule covers and the idealogy The official account for CSS-Tricks.
behind it. Check it out at com, a web design community Format CSS code
github.com/CSSLint/csslint/wiki/ curated by CSS legend cssportal.com/format-css/index.php
Rules. @chriscoyier. Pick your presets, add code and format to get the
code you want and need.

CSScomb
CSSLint enforces syntax and code csscomb.com
standardisation across the project team on a Build your own configuration to get the exact
code you want.
project-by-project basis
123
:HE'HVLJ
The:HE'HVLJAnnual

Bring design and Style secret

build together
CSS PREPROCESSORS DONT JUST BEEF UP YOUR CSS WORKFLOW, THEY
With Sass, treat @extend like
classes in other languages. It
should be immediately clear that a
style inherits other rules from
somewhere else, so list your @
CAN BE USED TO UNITE DESIGN AND BUILD TEAMS! extends first. This also helps with
At this point its fair to say that CSS preprocessors have themselves. In it, the colours are probably named so overriding styles later.
captured the imagination of the industry and have simply name variables after these colours and maintain
become prevalent in production the most well them in a file that is specific to the purpose. We do this
known being: Sass and SCSS, Less and Stylus. At this because it will make it easy to ensure colours are
point in time there isnt much to tell these preprocessors consistent, and this is so that even if the codebase is very codebase. No longer does the biography pod (contains
apart. They all have fairly similar capabilities, just with large, designers will be able to look at the preprocessor a persons biography) have to sit in the middle of a
each going about it a diferent way and with a slightly CSS and immediately understand the colour scheme of a massive stylesheet.
difering syntax. component. Theyll easily be able to tweak colours of At a glance, the build team and designers alike should
The basic premise of CSS preprocessing is to provide concepts at later stages in the project, which will no be able to see all the components in the website. This will
more powerful tooling to developers and also enable longer create headaches for the build team. give everyone a feel for the complexity of the site and
more expressive code. This has its pros and should make code reuse and time estimation easier.
cons the more advanced the tool is, the Organise Name font stacks
more skill it will take to use it efectively.
components Most websites have more than one Flexibility
In line with this, some of the most font stack and theyre often used in CSS preprocessors allow you to craft a more flexible
Split your components into
basic and easiest to use features of combination with each other, for codebase. Within a project, changes introduced late
folders. Widgets belong in a
CSS preprocessing are also the example headings and body text. shouldnt cause as many headaches for the build team
widgets folder same for pods,
most powerful. Monitoring the number of as before. Within a team, resources should be easier to
components (think header,
These basic features can be used diferent stacks in regular CSS can scale with the demands of a sprint or iteration because
footer and so on) and global
to bring design and build teams become a bit of a chore. Find and the separation of concerns is more apparent. Within a
modules (grid systems
closer together, creating codebases replace can also be a bit haphazard company, the front-end discipline should become one
and the like).
that are more flexible, easier to should two similar, but diferent, font that can deliver realistic prototypes with the design team
understand and, on the whole, much better stacks contain the same font family. without having a negative impact to the project timeline.
to work with. Naming font stacks has similar benefits to naming
colours. It enforces consistency and makes recognising Points to consider
Name colours incorrect font assignment easier for both designers as qMaintaining components in separate files so they are
Design teams are usually in possession of brand well as developers. ready to be combined in diferent ways.
guidelines from the client or have created their own by qSensible use of variables, enabling for changes to be
Componentisation made later on in projects without costing time, for
Take advantage of a preprocessor and split the styles up example accessibility issues caused by poor colour

6 tools WRITE BETTER


CSS TODAY
in a logical manner that helps introduce and describe the contrast can be easily remedied.

CSSLint analyze-css Sass


bit.ly/1IfwYPn bit.ly/1MMTh52 bit.ly/1nTLuD5
CSSLint is a tool to help point out problems with Analyze-css generates reports on selector Sass is the most stable and powerful professional-
your CSS code. complexity and performance of stylesheets. grade CSS extension language in the world.

124
// The best CSS ever

Beware of
bad code
WHAT TO AVOID AND WHY
Excessive nesting
CSS preprocessors make it very easy to write long
selectors by enabling nested code. Long selectors
come at a performance cost, so consider that
when nesting code.

Vendor prefixing
Most preprocessors have options or third-party
middleware that will add vendor prefixes
automatically. Double-check the output of this
behaviour old prefixes for tools like Flexbox can
cause weird behaviours.

Length of output
When dealing with many small files its easy for a
qThe ability to retire code quickly and easily when It must be said that the most valuable of these arent build team to create a rapidly growing main
crafting components. If the client doesnt need a specific the run once then throw away the results type, but stylesheet. Look at the output regularly and
component anymore, finding and deleting it is now easy. instead tools that run on build. A build team that has a minify as part of a build process.
qArchitecting preprocessor files to allow for variations of build server, which creates release builds automatically,
the website to be easily generated. This can be easily could benefit from having a performance report Build errors
achieved by importing selected components into new generated for example. Developers not previously exposed to
parent preprocessor files. preprocessors may be horrified to find that
qUsing a preprocessor to quickly make colour scheme/ writing erroneous syntax now results in build
typography changes site-wide, in other words errors. But this is still better than weird browser
prototyping. No longer does the design team have to To follow behaviour, however.
slave away producing variations in Photoshop.
CSS Author Lack of comments
The advance of CSS tooling @cssauthor Its rare in vanilla stylesheets to need comments,
Perhaps the single biggest benefit of using one of the big A web design and development so preprocessors present a bit of a mindset
CSS preprocessors is the tools that feed into them. There blog that tweets the best resources change when it comes to functions and mixins.
is a vast range of workflow tooling that can be used to and tools for designers and Good comments can explain what the developer
analyse performance, automate tedious tasks and hint at developers is thinking.
code improvement among other things.

Stylus {less} Calibre


bit.ly/1paZXwg lesscss.org calibreapp.com
Stylus is a revolutionary new language, providing Less runs inside Node, in the browser and inside Continuous website quality and performance
an eficient and expressive way to generate CSS. Rhino as well. telemetry. Think Google Analytics for the frontend.

125
:HE'HVLJ
The:HE'HVLJAnnual

Style guides: why you need them


HOW TO BUILD WORKING DOCUMENTS FOR CONSISTENT DESIGNS

Style guides are a brilliant idea, however they are An out-of-date working document is pretty useless project that it gets bumped in favour of any higher
usually woefully executed in practice. The idea is that because the project team cant use it for anything theyre priority tasks.
at any point in time there is a working document visible working on at that moment it simply gathers dust, The style guide idea is brilliant so long as the style
to the project team that captures the look and feel of becoming a relic. guide maintains itself after the initial incarnation.
core components and this includes typography, There are probably many reasons for stale style Thankfully, modern tooling can help improve this
buttons and form fields. What actually happens though is guides, but the biggest standout is the associated situation somewhat.
that the working document becomes stale and maintenance cost. The cost to design and build a style
discarded by most of the project team, and thats guide once is mostly absorbed, as it should mirror the Build tasks
because it captures the look and feel of the project from initial stages of the project. Its only when it takes extra Create a build task to distribute postprocessed files to all
two months ago. time to keep this document in sync with the working relevant locations instead of just to the website. This

126
// The best CSS ever

should ensure that the style guide is up to date with any The colours example is very easy, but this could be The design team picks up basic aesthetic changes,
CSS or JavaScript as its committed to the project. applied to typography, buttons, form inputs and many of giving more control over the result of the build. Theyre
the other simpler aspects of build. The limit here is going also free to adjust margin and padding on elements.
Team visible to be the design teams knowledge of CSS, but This should then free up the build team to focus on
Make the style guide available internally by hosting it on fortunately though, these are the easiest aspects of CSS more fundamental and specialist problems, such as box
an internally available URL. This gives everyone within that a person can pick up. model layout, code architecture and also flexboxes.
the project an easily accessible and now up-to-date

A making contributions document


aesthetic reference.
Its also worth considering authoring a making
contributions document, which provides guidelines on
how to contribute to the style guide project, all without
provides guidelines on how to contribute to
actually being a developer.

Seek design team contributions


Once a style guide is up to date and team visible, its time
to turn the style guide into the working document it was
the style guide project

born to be. Its time to ask the design team to learn some Style secret
code sort of.
Following on from the CSS preprocessors section, the Consider choosing a styleguide To follow
advice was to create a colours.scss or similar. This file generator that has a GUI which
should contain all of the colour definitions used within a allows for non-technical users to CSS3
project and be trivial to update. make adjustments without having @CSS3
Its worth giving training on this process and basics on to write code. Sc5- styleguide has a An account that is dedicated to
the preprocessor to the project team. This will enable the demo for just that via CSS. It offer news, previews,
design team to have input on the look and feel of the site demo.styleguide.sc5.io. tutorials and more for the
through the actual code, rather than being one step discerning designer.
removed with concepts.

Get better style guides


A Maintainable Style Guide Style Guide Generator Roundup gulp-kss
bit.ly/1glFg13 bit.ly/1zKLmQm bit.ly/1LA8BDy
Craft a maintainable style guide, using it as a tool. A look at style guides that run on platforms. A gulp extension to help create of a style guide.

sassdown StyleDocco
bit.ly/1JiMITr bit.ly/1NAY3Ep
Build living style guides with Handlebars. Generate documentation from your stylesheets.

127
:HE'HVLJ
The:HE'HVLJAnnual

5 Photoshop extensions
HOW TO ADD MORE POWER FOR FRONT-END DEVELOPERS

CSS Hat
csshat.com
Including any plugin that writes code for the developer is always
going to be controversial, but CSS Hat does an okay job. When it
comes to trying to scratch something together in minutes or
unpicking several font styles at once it can be a handy pallette to
have, especially for those who dont have a mental CSS encyclopedia.

render.ly
render.ly
If something needs exporting, render.ly is the right tool for the job.
The basic premise is that each top-level group in a PSD is a screen.
and child groups with names beginning with & get exported as
separate states of that screen. Render.ly also generates webfonts for
icons in vector format. No more manual image exporting from PSDs.

InVision
invisionapp.com
InVision takes designs and provides an interface for adding
interactions enabling designers to craft interactive prototypes
complete with gestures, transitions, and animations. InVision also
provides real-time presentation, collaboration and project
management features. Its a cheaper route to designing efective UIs.

Renamy
klaia.com/Renamy
Renamy is a layer renaming power tool. It allows for renaming of
multiple layers the right way. It can find and replace and even
handles regular expressions. Those who grew up with CS2 would be Built-in
jealous of this tool. An alternative use is to rename a colleagues PSD function
layers from New Layer 102 to Old Layer 102 just to upset them. There are lots of Photoshop
extensions that do amazing
things, but Photoshop also comes
Ink with a built-in batch file processing
bit.ly/1K0SPl0 function (File>Automate>Batch).
Ink is a free Photoshop plugin that generates documentation with Now, tasks like image
detailed information on Photoshop documents and their layers/ resizing become kind
styles. For typefaces this is information on font family, weight, of trivial.
leading, size and colour. For images and other layer assets,
dimensions are output. It spots minor inconsistencies at a glance.

128
// The best CSS ever

Improve performance
TAKE THE PAIN OUT OF CSS SPRITES. AUTOMATE WITH CSS-SPRITE!
CSS sprites can really help cut down on the number of What is particularly good about css-sprite is that it is
HTTP requests made on each page load. When done capable of laying the sprites out in multiple ways. Vertical
efectively, sprites can have a big impact on performance, and horizontal are options, but the best is binary-tree.
especially on mobile, where the number of simultaneous This will find the most optimal layout for all the sprites, Sprites that have been generated from
connections is limited or perhaps the data connection is creating a smaller final image though this is slower that gulp task
just plain slow. because more calculation is required. This is unlikely to
Unfortunately, theyre also quite costly to create and afect most everyday projects however, and for those it
maintain when done manually especially if icons need does it is unlikely for the file size to need optimising.
to change sizes late in the build. This is where css-sprite The best thing about automating this process is that Style secret
(an npm package) comes in: give it a bunch of images the design team doesnt have to commit to final versions
and it returns a stylesheet (in your preprocessor of of icons until later in the project. Theyre free to change File size still matters for CSS sprites
choice) and a single image. dimensions in response to client/user feedback. even when the process for creating
them is automated. Its worth adding

a compression task to your workflow


What is particularly good about css-sprite for the final output. Also consider
is that it is capable of laying the sprites out in grouping images into different
sprites where it makes sense.
multiple ways

Complete your CSS toolkit
TEN MORE TOOLS THAT WILL MAKE YOUR CODE BETTER THAN EVER Skyline
skyline.is

Critical Path CSS generator


bit.ly/1ygfAsw

Editr
lab.idered.pl/editr

DeSVG
SpaceBase benhowdle.im/deSVG
spacebase.space150.com
A Sass-based CSS framework that provides the Pleeease
launchpad for builds. Boasts a boilerplate layer. pleeease.io

Reuze
derny.github.io/reuze

CSS MenuMaker
cssmenumaker.com

CSS Sans
bit.ly/1Fn86Ys

CSSColorEditor
bit.ly/1NXTP9l

129
The:HE'HVLJAnnual

Create a colour swatch


tool with Vibrant.js
Extract colour swatches from your images to use in your
designs by dragging images onto the interface

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Create a colour swatch tool with Vibrant.js

5. Start the CSS

G
rabbing colours can be useful for a the right look. Do feel free to customise the name and
whole variety of uses and specifically logo for your own purposes. Now move back to the head section of the document
extracting colours from an image. and add the stylesheet tag, then link to the Open Sans
Android developers have access to the 3. Add the image holder typeface from Google Fonts. This is added to the body
Palette class in the Android support library, but When a user drags an image onto the page the image tag so that all text will be in this typeface. The background
unfortunately this isnt available for general web needs to be displayed somewhere. An empty div tag with of light grey is added as is the font size for the document.
developers. Jari Zwarts has taken the Android Palette the ID of image is created so that the image will be <style>
class and converted the code into JavaScript, meaning displayed in here later on when a user adds one. @import url(http://fonts.googleapis.com/
that anyone can use this in their own web projects. div id=details> css?family=Open+Sans);
This provides a great opportunity for us to create our <div id=image></div> body {
own design tool that will extract colours from an image <div class=col><span class=swatch font-family: Open Sans;
and display them on the webpage so that they can be colorVibrant></span><span class=txt background: #dbdbdb;
used in our own designs by taking the hex colour. If you textVibrant></span></div> font-size: 24px;
took this a little further, you could easily write some PHP <div class=col><span class=swatch }
to mail them to yourself, then you have a saved record of colorMuted></span><span class=txt
great swatches for future use. textMuted></span></div> 6. Add the header
Another way this could be used is if the user is creating <div class=col><span class=swatch Next in the CSS is to add the style for the header tag and
a profile on a website and they drag their own image in. colorDarkVibrant></span><span class=txt we will give this round corners and white text to go over
Using Vibrant.js it would be possible to set the users textDarkVibrant></span></div> the background image. The background is a striped grey
background to a personal colour from the image. What bar image that repeats to fill the size of the div tag.
this ofers is a way to influence a personalised design for 4. Hold the swatches
the user based on their image. When the image has been added it will be analysed using 7. Design is in the details
the Vibrant.js library, this will return the coloured swatches The details section will display the image, the swatches
1. Link up Vibrant library that will be displayed here on the page. There is also a and the drop zone for image. The col is the column to
Open the start folder from the project files on FileSilo in a drop zone created so that images can be dropped on hold each swatch colour and text with the hex number.
code editor such as Brackets. Open the index.html page the page and then analysed. #details {
and add the code below inside the head section of tags, <div class=col><span class=swatch text-align: center;
which will link up the Vibrant JavaScript library. You can colorDarkMuted></span><span class=txt }
download the library from github.com/jariz/vibrant.js, textDarkMuted></span></div>
but its included in the project files as well. <div class=col><span class=swatch
<script src=js/Vibrant.min.js></script> colorLightVibrant></span><span class=txt
textLightVibrant></span></div> Three basics of CSS
There are three ways to style your content with
2. Add the header <div id=drop>Drop image here
CSS. A full stop in front of CSS targets a class, a
Scroll down to the body tags in the HTML document and <small>(Uploaded image data works in Chrome
hash symbol targets an ID and just using a word
add the header tag so that there is an image and heading only)</small></div> will target the HTML tag.
on the page. This will be styled up later with CSS to give it </div>

Left
The tutorial uses the Vibrant.js code library which is found
on GitHub. The files are already included on FileSilo for
your convenience

Top left
At this stage all of the HTML that is needed is in place, but
there is no styling yet on the design of the page

Top right
The heading section of the page is designed with the logo
visible and the right typeface in place. The background in
here is a repeated PNG image denoting swatches

131
:HE'HVLJ
The:HE'HVLJAnnual

.col { text-transform: uppercase;


display: inline-block; } 12. Drop an image
padding: 20px 0 5px; #drop { The following code will be called when an image is
width: 80px;} padding: 40px 0; dropped onto the drop zone part of the page. There are
margin: 20px; some variables declared here and the event is stopped
8. Add the swatch text-align: center; from propagating and any default action is prevented
When the swatch of colour is ready for display it is placed border-radius: 5px; from running as we are defining our own.
in a circle with a three-pixel grey border around it. This background: #ccc; handleFileSelect = function(event) {
then fades in in one second with new colours inside. color: rgba(#000, 0.5); var data, f, files, parseFile, progress,
swatch{ } reader;
display: block; event.stopPropagation();
height: 60px; 10. Add the image event.preventDefault();
width: 60px; The small text is placed into the design with a slightly
margin: 0 auto; smaller typeface and the image is given appropriate CSS 13. Read the file
border: solid 3px #aaa; to display it on the page. As you can see the image is As the image is dropped it is possible that multiple
border-radius: 50%; never displayed greater than 50% of the browser width. images might have been dropped, so the code reads
-webkit-transition: 1s; small { only the first image. A variable reader holds the JavaScript
-moz-transition: 1s; display: block; file reader object in there and is used later. The progress
} font-size: 18px; function reads the image and extracts the colours.
padding-top: 10px; files = event.dataTransfer.files;
9. Display the hex number } f = files[0];
The TXT CSS rule displays the hex colour under the #image img{ reader = new FileReader;
colour. The drop ID is the area that the image can be width: 50%; progress = function(event) {
dropped onto, in order to extract the colours. } var el, el2, image, results, swatch,
.txt { </style> swatches, vibrant;
padding-top: 5px; image = new Image(200, 200);
text-align: center; 11. Add the functionality
You can display the page in the web browser but it wont 14. Read the image
do anything yet. Move to just before the closing body tag The image variable grabs the event of dropping the
and add the script tag as shown, then declare the image, takes the target which is the image and stores it.

Writing to the page variables we are using. The dropZone is the area that the
image will be dropped on the screen.
The image is displayed in the image div tag on the
screen. Vibrant is used to read the image and the
Using the innerHTML command in JavaScript
will automatically replace the HTML inside the <script> swatches are stored in the swatches variable.
tag you are referencing with what you are var dropZone, handleDragOver, image.src = event.target.result;
currently adding to update the page. handleFileSelect; document.getElementById(image).innerHTML =
dropZone = document.getElementById(drop); <img src= + event.target.result +

Top left
Now the drop zone for the images is clearly defined so
the user knows that they have to drop the image on this
section of the page

Top right
As the user hovers the image over the drop zone the
users cursor changes so that it shows that the image can
be added to the page
Right
Once the image is dropped onto the drop zone, the
JavaScript analyses the image and brings back the colour
scheme extracted from the image as swatches

132
// Create a colour swatch tool with Vibrant.js

An app for that


You may look at the
Vibrant.js library and be
thinking that this would be
great to use with a mobile
app. However you may
also be thinking that
unfortunately the user
cant drag and drop with
mobile, so how can this
library work? Well, by
using PhoneGap the
designer or developer will
have access to either the
users camera or photo
library. Once the image is
on the page, Vibrant will
then be able to read the
data of the image and
extract the colours
providing a very handy
mobile app. An example of
reading an image that is
on the page is available on
the demo site for Vibrant,
and this can be found at
jariz.github.io/vibrant.js.
As you can see, this
makes the Vibrant library
a great tool for creating
your own resources and
creative tools.

/>; the swatch, which is then stored as a background CSS calls the progress function. The image file is read as a
vibrant = new Vibrant(image); property. The actual swatch hex is also displayed as text data URL from the drop zone.
swatches = vibrant.swatches(); in the HTML of the page. parseFile = function(theFile) {
results = []; for (i = 0, len = ref.length; i < len; i++) return progress;
{ };
15. Loop through the swatches el = ref[i]; reader.onload = parseFile(f);
The for loop code iterates through each of the swatches results1.push(el.style.backgroundColor = return data = reader.readAsDataURL(f);
that has been brought back from the image. The swatch swatches[swatch].getHex()); };
is read and then the results array gets ready to have the el2 = txt[i];
coloured swatch results pushed into it. results2.push(el2.innerHTML = 20. Drag over
for (swatch in swatches) { swatches[swatch].getHex()); When the image is dragged over the drop zone the
if (swatches.hasOwnProperty(swatch) && } following function is called. This will stop any default
swatches[swatch]) { actions that are part of the way the interface behaves.
results.push((function() { 18. Return the results The image is copied and stored in the event.
var i, len, ref, txt, results1, results2; This part of the code is simply closing down all the handleDragOver = function(event) {
brackets of the if statements as well as the for loops. At event.stopPropagation();
16. Store the results the end of each section the results are returned, including event.preventDefault();
At this point the code checks the HTML and finds the no result if the image cannot be read or the file dropped return event.dataTransfer.dropEffect =
appropriate colour class and the appropriate text class to is not an image. copy;
add the colour to it so the user will be able to see it. return; };
Arrays are created to hold the results of the colour and })());
the text, the square brackets show an empty array. } else { 21. Event handlers
ref = document.querySelectorAll(.color + results.push(void 0); Now the final step is to attach the event handlers for
swatch); } dragging a file over and dropping it on the drop zone in
txt = document.querySelectorAll(.text + } the display. These call the functions that have been
swatch); return results; created earlier. Now save the page and test it on a web
results1 = []; }; server or by clicking the live preview button in Brackets.
results2 = []; dropZone.addEventListener(dragover,
19. Connect the functions handleDragOver, false);
17. Loop through the display As the image is dropped on the drop zone the code here dropZone.addEventListener(drop,
For each of the swatches available on the HTML screen, connects up the functions already created. As the image handleFileSelect, false);
the for loop moves through each and takes the colour of is loaded the parseFile function is called, which in turn </script>

133
The:HE'HVLJAnnual

Alter page element


colour on click
As seen on yenue.com
Hidden treasures
A small glimpse of each
project can be found
hiding away behind the
plus icon. Call into action
for a full-page image.

On-click colour
The page elements
including site title, page
names and bottom strip
are coloured coded to the
last project page visited.

Flexible navigation
The site is easily
navigable and the
projects can also be
viewed one after another,
as a slideshow.

Unique elements Intriguing efect


The minimalist interface Just like in The Wizard of
is not constrained by Oz, the site starts in
typical structures, colours greyscale and changes to
or styles that are typically colour, drawing the
used to build a website. viewer in to find out more.
// Alter page element colour on click

T
his workshop explores just a small detail of design techniques that actually have much broader
of London based-artist Yenues portfolio applications. Yenue says: I tailored my website to
site that may even have been overlooked enhance the connections between the index and the
by the casual visitor. Its a subtle individual projects. Each project is unique, so each
technique that changes the hover colour of the elements background is customised to suit each project. I
on the homepage to the background colour of the continued to find ways to connect diferent sections with
previously visited page. It neatly speaks to an important small design features, such as the index border
artistic concept, the memory and experience of viewing overlapping with the border of the project as you switch
a piece of art. Yenues website of surreal and sometimes between them; the overlapping border is still visible. The
Dali-esque work inspires contemplation on the meaning colours of the index page are impacted by the design
and presentation of art, and, through this small detail of you choose to view. I felt that all of these features
colour change, we have an opportunity to learn a range enabled me to connect my projects and overall website.

Mi casa es su casa
My portfolio website is another design project for me, where I show all the
projects in which I have invested a large portion of my time. It is like my
<comment> home on the internet and so I wanted to create something very special and
What our visual for anyone visiting.
experts think
of the site Yenue

Technique 3. Set the stylesheet


Immediately before this, our helper will enable vertical
1. Head first centring. A JavaScript call sets a cookie that the
SVGs are popular for their flexibility but to take full JavaScript at the top uses to set the stylesheet. Note the
advantage of this, it needs to look inline. You could add attributes of the image that are used by the SVG inliner.
graphics to HTML but Drew Bakers (bit.ly/1ciz3Cc) SVG <span class="helper"></span><a
inliner is a great solution. Dem Pilafians Two Line Style href="javascript: document.cookie='style=2';
Switcher (bit.ly/1CxTh10) provides a neat and efective window.open('stpauls.html','_self');"><img
method for changing a colour scheme as required. id="stpauls-icon" class="svg stpauls"
<html> src="images/stpauls.svg"></a>
<head>
<title>Change colour on hover</title> 4. Style switch
<script src="http://ajax.googleapis.com/ajax/ In this solution the style is switched on when exiting the
libs/jquery/1.6.2/jquery.min.js"></script> homepage, and it could be argued that its only
<script type="text/javascript" src="scripts/ necessary to include the switcher code in one file here.
svginliner.js"></script> The portfolio pages are similar to the homepage but the
<script> background colour is changed to the new theme colour.
var styleFile = "style" + document.cookie. <script>
charAt(6) + ".css"; #royalalberthall-col {
document.writeln('<link rel="stylesheet" float:left;
type="text/css" href="styles/' + styleFile + width:100%;
'">'); position:relative;
</script> left:0%;
overflow:hidden;
2. CSS in the HTML text-align:center;
To keep things simple, the styling that is specific to each background-color:#baa5a0;
page that does not want to be switched has just been }
added direct to the HTML. Centring elements in CSS can
be tricky but if you follow through each divw and 5. Theme styles
EXPERT ADVICE experiment with changing the settings that should help Its necessary to follow the naming system of style.css,
Vision and technique make things clearer. If you havent come across the style2.css and so on. In this solution each element is
Make sure you also check out
facebook.com/yenue.studio, where helper class before then that is worth exploring. coloured the same but the technique provides plenty of
Yenue showcases other ongoing <style> flexibility to switch the styling of any page element.
work. The typographical plasticine .helper { #stpauls-icon:hover path{fill:#9d7554}
creations are especially interesting display: inline-block; #housesofparliament-icon:hover
and his projects demonstrate original
thinking and first-class execution
height: 100%; path{fill:#9d7554}
something that designers from any vertical-align: middle; #royalalberthall-icon:hover path{fill:#9d7554}
field will appreciate. } #toweroflondon-icon:hover path{fill:#9d7554}

135
The:HE'HVLJAnnual

Create a rotating
product viewer
As seen on nuabikes.com Signposted URL
Getting sales for the bike
is key so a large pre-order
label in the top-right of
the screen will always
provide access to it.

Fixed menu
The menu is fixed into
position on the left side of
the screen and remains in
place as the rest of the
page is scrolled through.

Fullscreen photos
The photography is key to
this site and the large,
fullscreen images provide
a way to view the bike
from diferent angles.

Fluid sections Pausable scroll


The page is a one-page The right-hand navigation
site that enables the user controls the images and
to scroll down each the user can click on the
section or use the menu image, pause it or watch it
on the left-hand side. from diferent sides.
// Create a rotating product viewer

N
ua Bikes produce a very elegant and change automatically and gives the user a chance to see
clean urban bike that has a minimal the design of the bike in detail. When the product you
impact on the environment due to the are designing for has such clean, elegant lines and is
simplicity in its design. The bikes are made from quality materials such as titanium, carbon
handcrafted and reflect the conscious commuter who fibre and aluminium, then it is important that the styling
needs to get around urban environments with ease. of the site reflects the construction aesthetic. It is so
The website needs to reflect the styling of the bike easy for designers to get carried away by adding more
and this is always easy to do with photography when and more complex content to sites but sometimes all
there is a strong product on display. The homepage that is needed is good typography, navigation, simple
features a large, fullscreen image of the bike that has colour and the product itself. Organising the content
been photographed from diferent angles so that the can be tricky, but the Nua Bikes site has managed to do
user can see the bike rotating on screen. The images this without overstating the simplicity of the design.

Innovative but intuitive


The website uses the minimum number of elements to do its function.
Innovative but intuitive at the same time, the site shows the product and
<comment> enhances its qualities. A single guided scroll shows all components while the
What our user can contemplate how beautiful the bike is a website to be enjoyed on
experts think
of the site different devices. Alicia Gomez Garcia, freelance digital art director and graphic designer

Technique <script src="https://code.jquery.com/


jquery-2.1.3.min.js"></script>
1. Add the images
To create a rotating image of a bike, we need to add 4. Move through the images
five images to the body section of the page. Using After the link to the jQuery library the following code
jQuery a simple image rotator can be created which can be added. This hides all the images except the first
moves the image on every few seconds. one. They are positioned within the div tag so that they
<div id="fader"> will be in the right position when they are called to fade
<img src="img/bike1.png"/> in with the code in the next step.
<img src="img/bike2.png"/> <script>
<img src="img/bike3.png"/> $(function() {
<img src="img/bike4.png"/> $('#fader img:not(:first)').hide();
<img src="img/bike5.png"/> $('#fader img').css('position', 'absolute');
</div> $('#fader img').css('top', '0px');
$('#fader img').css('left', '50%');
2. Style the images $('#fader img').each(function() {
Now move to the head section of your page and add var img = $(this);
the style tags for the div tag that holds the images. This $('<img>').attr('src', $(this).attr('src')).
simply positions them relatively so that the JavaScript load(function() {
can change the images later on. img.css('margin-left', -this.width / 2 +
<style> 'px');
html, body{ });
height: 100%; });
background-color: #f0f0f0;
padding: 20px; 5. Switch images
} The fadeNext function does the hard work of fading
#fader { out the old image while fading in the next. This is called
position: relative; every three seconds by the set interval, which in turn
width: 100%; calls the fadeNext function. Save this now and test it in
EXPERT ADVICE height: auto; your browser to see the images appear on the screen.
Keep navigation simple } function fadeNext() {
On the homepage the navigation is
hidden away in an ofscreen menu, </style> $('#fader img').first().fadeOut().
giving space on the page to create appendTo($('#fader'));
more of a showcase for the site. As 3. Library link $('#fader img').first().fadeIn();
the user moves through onto The images have to be hidden and positioned on top }
content pages, the menu is on hand
of each other, so a link to the jQuery library is needed. var rotate = setInterval(fadeNext, 3000);
to provide easier browsing and there
are even previous and next buttons This will aid the adding and removing of CSS to make });
to move through the content. each of the images appear at the appropriate time. </script>

137
:HE'HVLJ
The:HE'HVLJAnnual

Construct T
here are so many remarkable
and exciting things that we
designers can now achieve using
just CSS. Not only can we animate

custom web
elements to jazz up our pages, but
we can now create some really
interesting shapes using CSS
transforms. These shapes will not afect the flow of the
content inside or around them. That is, if you create a

layouts with triangle with CSS, for example, the shape created does
not define or afect the way the text inside it flows, or
the way inline text flows around it.
With the introduction of CSS Shapes into the web

CSS Shapes
design workflow, wrapping content in custom
nonrectangular shapes and re-creating print designs
and layouts on the web becomes a breeze! CSS
Shapes enables us to wrap content around custom
paths, which lets us break free from the constraints of
the rectangle we have been accustomed to.
Build layouts using shapes, and wrap content So in this tutorial well take a look at how we can
use CSS Shapes to create a custom layout. We wont
without affecting content flow be looking at all the new properties, but rather just the
tools | tech | trends HTML, CSS DOWNLOAD TUTORIAL FILES ones that enables us to create an interesting layout
expert Neil Pearce www.filesilo.co.uk/bks-809 based on a visit to a world-famous landmark.

1. Get started container div may be the only one well be using, but Weve left a gap after the second <p> tags, because in
As with all new projects, lets begin with a new HTML well wrap that within a page wrapper in case we need it. the next step, we will be adding in a few extra elements
document and start adding in our HTML markup. Were <div id="wrapper "> such as an arrow and profile picture.
going to create just the one style sheet and then below <div class="container"> <p>Lorem ipsum dolor sit amet, consectetur
that we will use HTML5 Shiv to compensate for IE users </div><! END container > adipiscing elit.</p>
when using HTML5 elements. </div><! End wrapper > <p>Lorem ipsum dolor sit amet, consectetur
<head> adipiscing elit.</p>
<meta charset="utf-8" /> 3. Shape up <p>Lorem ipsum dolor sit amet, consectetur
<title>CSS shapes</title> You can apply a shape to an element using one of the adipiscing elit.</p>
<link rel="stylesheet" type="text/css" shapes properties and its function. In this case, well be <p>Lorem ipsum dolor sit amet, consectetur
href="css/style.css" /> adding the polygon function to the background image of adipiscing elit.</p>
<meta name="viewport" Stonehenge so we can create an interesting shape. So
content="width=device-width, initial- just underneath the container div, place a div with a class 6. Arrow, circle and profile image
scale=1.0"> name of shaped. As mentioned in the last step, we are going to add in
<div class="shaped"></div> some additional elements within our paragraphs. What
<!--[if IE]> we want to achieve here is a green circle with an arrow
<script src="http://html5shiv.googlecode. 4. Content and title pointing to a profile image. And within the green circle
com/svn/trunk/html5.js"></script> Our page is going to have a heading and we are going we will have some text saying this is me!. Then we can
<![endif]--> to make the first word the slightly smaller than the use this profile image to demonstrate our second CSS
<!--[if gte IE 9]> other words. So to accomplish this, we will need to wrap shape in a later step.
<style type="text/css"> it within a <span> tag. Our page title, along with <div id="arrow"></div>
.gradient { everything else for the page, will be placed within a main <div class="circle"><p>This is me!</p></
filter: none; content element. div>
} <div class="content"> <img src="imgs/man.jpg" alt="profile image"
</style> <h1><span>The</span> Visit To <br/> class="profile_img" />
<![endif]--> Stonehenge</h1>
</head> </div> 7. Put in a blockquote and footer
We are going to finish up our HTML by adding in a
2. The page wrap 5. Add in paragraphs blockquote and footer to the bottom of our page. The
Now that we have the head meta information done, Our page is going to have a few paragraphs, so within blockquote could be styled, so we encourage you to play
lets start adding some structure to our HTML file. First, the content div put about four or five <p> tags and fill around with that idea, but we will leave the footer alone
we will add in a few divs that will give us some control them with either dummy text or go ahead and add in as its there for semantic purposes only.
when positioning elements on the page with CSS. The some proper information relating to our topic. <div class="blockquote">

138
// Construct custom web layouts with CSS Shapes

Top left
With most of the markup
added, we are starting to
see our page come together
Top right
Now we have the profile
image added as well as the
content blockquote and
footer
Bottom left
The page has some
structure to it now and our
first shape has been created
on the main image
Bottom right
Weve now styled the main
content and things are
looking a lot more cleaner

Custom paths container relative, which will now enable us to absolute


position any element anywhere on the page.
are outside the defined shape.
-webkit-clip-path: polygon(0 0, 100% 0,
CSS Shapes enable web designers to wrap
content around custom paths like circles, .container{ 100% 100%, 30% 100%);
ellipses and polygons. overflow:hidden; -webkit-shape-margin: 20px;
height: 100vh; }
width: 100vw;
position: relative; 12. Style the content
} Now we need to add some styles to our main content.
<blockquote></blockquote> This is going to be pretty straightforward and by looking
</div> 10. Background image at the CSS rule, you can see clearly what we are doing
<footer> This page is about Stonehenge, so its obvious we here. You might want to play around with the padding
<p>&copy; Copyright 2015 The Visit To want a main image of Stonehenge. We are going to and font size to get a slightly diferent look, but thats up
Stonehenge</p> attach this to the Shaped class, set the viewpoint and to you.
</footer> make sure that the image is centred from the top and .content {
doesnt repeat. We then need to make sure this is floated padding: 30px;
8. Box sizing to the right. color: black;
Now create a new CSS file and call it styles.css, and .shaped{ font-size:15px;
place it in its own folder called CSS. At the top of your height:100vh; text-align: justify;
CSS file, we are going to add in the box-sizing rule. This width:40vw; line-height: 23px;
will apply a natural box layout model to all elements, but float:right; font-family: Verdana, Arial, sans-serif;
enabling components to change, and its now considered background: black url(../imgs/stonehenge. }
best practice to add this to your CSS. jpg) center top no-repeat;
* { background-size:cover; 13. Page title
-moz-box-sizing: border-box; } The main page title is going to be nice and big, so it
-webkit-box-sizing: border-box; grabs attention straight away. Weve used a Google
box-sizing: border-box; 11. Create our first shape Font called Sintony. Now, this is where we use our
} Having added our main image, lets now create our second shape. By using shape-outside: polygon() we
first shape. Each shape is defined by a set of points. can create another shape that targets the main text. To
9. Set the width and height Some functions take points as parameters, but they all make things interesting, we are going to shape it the
Modern websites nowadays have fullscreen sections eventually draw the shapes as a set of points on the opposite way to our main image.
on their homepage and this is what we want. To element. We are going to use the polygon function here .content h1{
achieve this, we set the viewpoints height and width to and create points to create our desired shape. Using the font-family: 'Sintony', sans-serif;
100 per cent. Then we are going to position the clip-path property will clip all the parts of the image that font-size:50px;

139
:HE'HVLJ
The:HE'HVLJAnnual

Top left
The page title is now styled
and our second shape is
now created for the text
Top right
The page title is finished off
by making the word My
small
Bottom left
We can now start to style
our profile image and make
it into a circular shape
Bottom right
Now with the green circle
and arrow added, we have
finally finished our page

Polygon shape Stonehenge, it would make sense to add a small profile .circle {
The minimum number of pairs to specify a
polygon is three, which is of course a image to the page. And doing so will give us another width: 100px;
triangle shape. chance to play with CSS Shapes. But first we are going to height: 100px;
add some styles to our image and float it to the left. background: #9fb876;
.profile_img { -webkit-border-radius: 130px;
float: left; border-radius: 130px;
width: 180px; position: absolute;
line-height:1; height: 180px; top: 350px;
float:left; border-radius: 50%; left: 180px;
width:350px; border: 10px solid #f1f1f1;
height:100vh; margin-right: 15px; }
margin-top:0; padding: 0px;
padding-top:20px; } 18. Circle content
color: #3f3f3f; The green circle is going to have a little bit of text
-webkit-shape-outside: polygon(0 0, 100% 0, 16. Shape our profile image within it. By targeting its <p> we can make sure the text
40% 100%, 0 100%); At the moment our content is pushed over to the is styled how we want it and fits within the circle nice and
} right-hand side of our image and theres no shape to it tidy. Were going to set the colour to the same colour as
other than a square shape cut out of the text. But we our page title.
14. Finish up the page title want the text to flow around our image in a circluar .circle p {
Now that we have used the page title (h1) to shape our shape. We can achieve this by adding shape-outside: margin: 20px 0;
content, the only thing left to do is simply to make the circle(); and some margin and border. font-size: 1em;
word My nice and small by adding some styles to the -webkit-shape-outside: circle(); text-align: center;
span tag. Then we can pull in the word visit by adding -webkit-shape-margin: 10px;
some negative right margin. border: 10px solid #f1f1f1; color: #3f3f3f;
.content h1 span{ } }
font-size:.5em;
display:inline-block; 17. Circle styles 19. The arrow
margin-right:-10px; To practice with creating other shapes using CSS, we are Creating other shapes without using the new CSS shape
} going to add a green circle that floats next to our profile functions is good fun. In this next step we will create a
image. This circle is created by using border-radius. Then small arrowhead purely using CSS and we will then
15. Style our profile image we will give it a nice green colour that represents the feel of position it between our main profile image and the green
Because this page is about someone visiting our main Stonehenge image, and position it accordingly. circle. You can play around with the rotate value using

140
// Construct custom web layouts with CSS Shapes

Understanding the clip-path property


The clip-path property takes the same shape functions and values as the shape properties. If we pass the same polygonal shape we used in the shape-outside property
to the clip-path property, it will clip all the parts of the image that are outside the defined shape.
The clip-path property is supported with prefixes and will work with the Chrome -webkit- prefix added. The clip-path property is an excellent companion to the shape
properties, as it helps visualise the created shapes and clip out any parts of the element that are outside the defined shapes. You will probably find yourself using it a lot
in conjunction with the shapes properties.

transform: rotate(), but setting it to 5deg should work pointing to our profile image. .blockquote {
quite well too. #arrow:after { text-align: center;
#arrow { content: ""; }
position: absolute; position: absolute;
width: 0; border: 0 solid transparent; 22. Final thoughts
height: 0; border-top: 6px solid #9fb876;; The current CSS Shapes specification is merely the first
top: 380px; border-radius: 20px 0 0 0; step. Soon, new options will give us even more control
left: 300px; top: -24px; over creating shapes and wrapping content in and
border-top: 18px solid transparent; left: -18px; around them, making it a lot easier for us to turn our
border-right: 18px solid #9fb876;; width: 24px; mockups into live designs with just a few easy lines of
-webkit-transform: rotate(5deg); height: 24px; code. So this tutorial is just the beginning, giving you the
} -webkit-transform: rotate(45deg); first steps to bigger and better page layouts using the
} power of CSS Shapes.
20. Finish up the arrow #arrow:after {
Now that we have created a small arrowhead, we can 21. Style the blockquote content: "";
now create its tail. So again using border and border- To finish this page of, we are going to add some simple position: absolute;
radius we can create an arrowtail and position it absolute, styling to our blockquote. So all we are going to do here border: 0 solid transparent;
using transform: rotate(45deg) to place it exactly where is centre our text so it looks tidy. You can add more styles border-top: 6px solid #9fb876;;
we want it to be. So now we have a nice little arrow to it to see if you can achieve something slightly diferent. border-radius: 20px 0 0 0;

141
:HE'HVLJ
The:HE'HVLJAnnual

expert guide to

WEB
add wow to
your site with

WEBGL, HT
HTM
ML5,
CSSS3, THREE.JS
CS
142
142___________________________________________________________________feature
// Expert guide to web 3D

How web 3D is influencing web design


3D MODELS ARE LEADING THE WAY FOR THE WEB TODAY

I t is an exciting time in web development in regards


to 3D. In the Nineties we had 256 colour animated
GIFs of spinning text and email icons. In the 2000s we
several ways we can execute all of those tricks and
efects depending upon our individual skills or the needs,
requirements and assets of our projects.
The big three
grew up a little by interacting with and spinning At its most complex level, immersive design, content WebGL
prerendered image sequences, but we had to use the and interaction can now be created in the browser with This JavaScript API is great for rendering
Flash plugin to do it. Later Flash added features that actual 3D models, textures, particles and assets using interactive 3D and 2D graphics within any
enabled actual 3D rendering but development became libraries like three.js which tap into the power of the compatible browser without using plugins. A
painfully dificult for many developers. Then the Flash hardware-accelerated WebGL drawing API. We can finally great library for animating 2D (and soon basic 2D
bomb dropped and the rise of mobile browsers design, develop and dream of rich interactive 3D objects in 3D space) with WebGL is the Pixi.js
began. Our designs and content had to content, and the best part is that most libraries rendering engine, which also has Canvas fallback.
simplify to pure HTML solutions in order 3D fall back to Canvas API, which has even
to be supported by all devices. and iOS larger support. Canvas is a simpler HTML5 Canvas
Otherwise we would be wasting Want to produce 3D for drawing API that can create believable The HTML5 Canvas element is part of HTML5 and
development time and money Apple devices? Well now that plexus animations, particle systems, allows for dynamic, scriptable rendering of 2D
building multiple versions of the latest iOS versions support emitters and mouse trails to look like shapes and bitmap images. It can be used to draw
websites. With Flash slowly dying, WebGL we can create dreamy 3D (although it does not support graphs, make photo compositions, create
modern browsers thankfully began content for the desktop that also true 3D drawing like WebGL). animations, or even do real-time video processing
upping their game to support new work on a large percentage At a simpler level, CSS 3D has or rendering.
features. Developers have worked hard of mobile devices been a welcome addition to interactive
to create libraries that help us create as well. 3D design and development of pure Three.js
interactive content to capture that old-school HTML elements. It has helped to add life to As a JavaScript 3D library, three.js makes WebGL
Flash magic again. otherwise boring flat responsive design and basic UX simpler. While a simple cube in raw WebGL would
As a result of these changes over the past few years grids. CSS 3D is easy to develop with, and anyone with a turn out hundreds of lines of JavaScript and
we can finally render, animate and interact with content basic understanding of CSS can easily upgrade their shader code, a three.js equivalent is only a
in the 3D space without the need for plugins. All of those designs. Its also robust enough that when combined fraction of that and much easier to create
ideas, tricks and lessons that were learned in the days of with libraries like three.js or animation libraries like environments with.
Flash are now being revived. And fortunately we have GreenSock can create jaw-dropping results.

We can finally render, animate and


interact with content in the 3D space without
the need for plugins

The current state of browser support
UP TO UP TO UP TO UP TO

46 41 46 41

9
Note: three.js runs in all browsers that support WebGL

CANVAS WEBGL
Shane Mielke
@shanemielke
WebGL, designer, developer, 5
animator, photographer, author and UP TO UP TO UP TO UP TO

Cyberdyne Systems Model 101. 9 11 9 11


Previously worked at 2Advanced.

143
feature____________________________________________________________________143
:HE'HVLJ
The:HE'HVLJAnnual

3D web graphics Textures and graphics 3D and mathematics


For me the number one selection for 3D web graphics is When it comes to textures and other graphics, its still I dont think you need any more tools than that. But what
Fuse (fusetools.com). And yes, you can export WebGL Photoshop that wins (adobe.com/fi/products/ you do need is more knowledge and skills (along with
with it. As a side product youll be able to produce native photoshop.html). years as well).
applications for mobiles as well, which makes a lot of Creating 3D is a lot about mathematics and rendering
sense for heavy duties like 3D. techniques, so you better know your trigonometry. I

The
Fuse gives us a new programming language, called would recommend refreshing your memory of it by
Uno, and it makes creating complex 3D renderers so watching Khan Academys videos about trigonometry by
much easier. going to bit.ly/1FjSTEV (really wish I had resources like

ultimate
this when I was a kid!).
Also no matter what language or tools youre using,
the same rendering techniques will apply. When you

3D toolkit
reach a certain level, Nvidias GPU Gems can come in
handy: bit.ly/1EBuXCo.

WHAT RESOURCES AND GUIDES DO


YOU NEED TO START CREATING?
As weve already mentioned, in the world of
web 3D the big technologies and tools are
WebGL, HTML5 Canvas and three.js. These
3D modelling are at the forefront of bringing a new
I do a lot of my 3D modelling in procedural fashion, with dimension to the web. But to build beautiful creations, as
maths. But once in a while you need to work with actual every designer developers knows, a collection of your
models. Here I would select Blender blender.org, simply own favoured resources are always needed. Web
because its free, easy to use and has a big community Designer spoke to real-time graphics craftsman and the
behind it. Its easy to find freelancers to help you in case man behind apexvj.com Simo Santavirta. He gave us an Inspiration
of an emergency. insight into the tools and resources he uses to help If youre in need for inspiration try pouet.net. This has
create his dynamic online experiences. Check out his pretty much every real-time graphics demo ever made.
6 more 3D resources work at simppa.fi. A must-see for those looking to get into web 3D.

threejs.org/editor/ shdr.bkcore.com shadertoy.com

unity3d.com playcanvas.com meshlab.sourceforge.net

144
// Expert guide to web 3D

Making fireworks with three.js


BUILD A SIMPLE SCENE, ADD TEXTURES TO MATERIALS, CREATE LIGHTS AND BLOW THINGS UP
WebGL is one of the best things about the modern moonlight = new THREE.PointLight( 0xffffff, 1, 8. Particles and CPU cycles
web. We, as developers, looked at 3D modelling, shading, 100 ); When our firework explodes, we want to see colourful
rendering and all the other things that come with the moonlight.position.set(0, 10, 5); sparks, but do we really want to render dozens of new
realm of the third dimension. The use of 3D graphics in scene.add( ground ); objects to do so? No, we dont. Instead, we can create a
the browser enables us to make the best of real-time scene.add( moonlight ); point cloud, which is a fancy way of saying a particle
graphics generation with just pure JavaScript. Rendering system. This is basically one big object, but made up of
anything in 3D is a far more complex process than 4. Rendering loads of little bits with space in-between, its much
drawing a square on a <canvas> element, but with Now that we have some things in our scene that we friendlier for our graphics card.
complexity comes dificulty in implementation. want to see, we can tell three.js to render them. We use
Fortunately, three.js is here to help us. Its a JavaScript requestAnimationFrame() to call our render function 9. The sparks
library that helps us write WebGL content without having which will draw our scene as close to 60FPS as your On lines 38 44, we create a point for each spark that we
to worry about a great deal of maths or 3D rendering computer can handle with renderer.render( scene, want to have and give each a random velocity. On lines
computer science (well, not too much). Think of three.js as camera );. Right now, youll only see illuminated turf. 47 53 we tell three.js what size and colour we want our
a kind of jQuery for WebGL, everything is simpler and renderer.render( scene, camera ); particles to be and then we add them to the point cloud
follows patterns. Theres no more fiddling about with requestAnimationFrame( render ); on line 55. As a cheat, we add a JPG to each of our
polyfills or trying to get things to light consistently. Get the sparks to fine-tune how each point should look. On lines
full code for this tutorial at filesilo.co.uk/webdesigner. 5. Set off a firework 100 110, we check how high our firework is, whether or
If you press Space, a colourful firework will set of into the not it should explode and whether or not we should be
1. Grab the resources sky and then detonate. In addEvents(), we push a new animating it if the explosion has started.
Three.js has a ton of helper libraries and other code bits firework() to our fireworks array and once there, our var sparks = new THREE.Geometry();
to help it get on with its work. Were going to use the core render function will work through and draw every for (var i = 0; i < Math.random() * 1000 | 0;
three.js library and the OrbitControls.js library to handle firework weve set of. i ++ ) {
our camera movements. Download the project files from window.addEventListener('keydown', function(e){ var spark = new THREE.Vector3(0,0,0);
FileSilo and have a look around the scripts folder. if(e.keyCode === 32){ spark.velocity = [ Math.random() Math.
// (Radius, Width, Height, Color) random(), Math.random() Math.random(), Math.
2. Set up the renderer fireworks.push(new firework( 0.2,32,32, new random() Math.random()];
The meat of our program is in scripts/fireworks.js. In the THREE.Color( colors[Math.floor(Math.random() * sparks.vertices.push( spark );
init function on lines 181 199 we create a renderer, which colors.length)] ) )); }
is where our 3D scene will be drawn to. We then create ground.material._needsUpdate = true; this.sparkMaterial = new THREE.
and position a camera to see with and point it at 0,0,0 of } }, false); PointCloudMaterial( {
our scene. Whatever happens in front of our camera is size: 1.5,
what will be shown on our rendering element. 6. Detonation map: THREE.ImageUtils.loadTexture("assets/
renderer.setSize( window.innerWidth, window. What is a firework anyway? Well, in this context, its an images/spark.jpg"),
innerHeight ); object that will keep track of the position, velocity, sparks blending: THREE.AdditiveBlending,
document.body.appendChild( renderer.domElement and light sources of our firework as it travels to its transparent: true,
); beautiful, but ultimately tragic demise. Once our firework color : color
camera.position.x = 2; reaches a certain height above our ground, it will explode });
camera.position.y = 43; and animate our explosion with the detonate() function this.particles = new THREE.PointCloud( sparks,
camera.position.z = 35; on lines 60 82. this.sparkMaterial );
camera.lookAt( new THREE.Vector3(0,0,0));
7. Light em up 10. Remove particles
3. Set the scene Our fireworks need to make light that shines on other A firework doesnt last all night. So once its petered out,
Next we call createScene(). Here, we create the ground things around it. The material that makes up our its probably best to forget about it, otherwise its just
for our scene and some light (which we call moonlight) fireworks in flight cant (easily) do this on its own, so going to clog up our computers memory. If we pass
to light up our scene. Without light in our scene we wont instead, we create a new light the same colour as the through our firework and its lights to the
be able to see anything. The ground and the moonlight firework in the same place. Do this with this.light = new removeObjectFromScene() function on lines 19 22,
are added to our scene with scene.add(OBJECT);. THREE.PointLight( color, 10, 4 );, which you may notice is three.js will remove our asploded fireworks from the
var groundTexture = new THREE.ImageUtils. the exact same way we created moonlight. scene and GC will take care of the rest.
loadTexture( '/assets/images/ground.jpg' ), // Line 29 // Lines 106 110
groundGeometry = new THREE.PlaneBufferGeometry( this.light = new THREE.PointLight( color, 10, } else if(f.hasDetonated && f.explosionLight.
150, 150, 32 ), 4 ); distance <= 1){
groundMaterial = new THREE.MeshPhongMaterial( // Lines 96 98 removeObjectFromScene(f.explosionLight);
{side: THREE.DoubleSide, map: groundTexture} ); f.light.position.x = f.object.position.x; removeObjectFromScene(f.particles);
ground = new THREE.Mesh( groundGeometry, f.light.position.y = f.object.position.y; fireworks.splice(aa, 1);
groundMaterial ); f.light.position.z = f.object.position.z; }

145
The:HE'HVLJAnnual

How did they build this?


CHIEF DEVELOPER AND CREATIVE CARLOS ULLOA REVEALS THE SECRETS BEHIND
THE BUILD OF THE PENNY SKATEBOARDS 3D EXTRAVAGANZA

Dynamic
The customiser WebGL app is fully
dynamic, it lets you change board size
and select wheels, trucks and bolts.
Each part can be configured individually
for unique results. It also uses real-time
Name of site Penny Skateboard Customiser inventory data from a Magento
URL bit.ly/1JzLRBj eCommerce backend to present the
Designer HelloEnjoy user with options currently available.
Loading time is optimised by preloading
URL helloenjoy.com
3D models and textures in diferent
Time to complete Six months batches using CreateJS (createjs.com)
Share
Once the board is complete, the user is
given the option to ride it, similar to a
skateboard game. Using the share
functionality users can invite their
friends to ride their creations. The
related image used on social networks
is also created dynamically, rendering
and uploading to the server a snapshot
of each board.

The limitless potential of three.js


Carlos Ulloa USE THREE.JS TO MAKE ANYTHING, FROM GAMES TO ROTATED PRODUCTS
Interactive designer Three.js takes away a lot of the headaches for you and or should use for everything. While WebGL is supported
Building a product customiser gets you started faster on making some seriously cool on all modern browsers and has recently picked up a lot
using interactive 3D gives us content. While a simple cube in raw WebGL would turn of mobile support being enabled on iOS devices it wont
complete control of how the out hundreds of lines of JavaScript and shader code, a work everywhere. Depending on what youre executing
product appears. It allows the user three.js equivalent is only a fraction of that and much or where youre trying to display your cutting-edge 3D,
to virtually grab an object and look easier to code and create environments with. Its an content may also be pretty processor-intensive and
at it from any angle, like we do in amazing tool that lets you either bring in existing 3D afect mobile usage. But It has its place in our toolbox
real life. It also makes possible to assets or create your own using primitive 3D shapes. The and should be used anytime you need to create, animate
change colours, materials and potential opportunities are limitless with the right or load 3D scenes in the browser.
entire parts in real-time. projects, assets or more importantly ideas. Although you We would also warn about the expectation or desire
should beware, that its definitely not something you can to create photorealistic environments with these new

146
// Expert guide to web 3D

More from
Mobile
The experience is optimised for mobile,
Hello Monday
using the entire browser window. When 4 MORE IMPRESSIVE 3D PROJECTS
running on desktop, higher resolution
3D models and textures are used. Both
mouse and touch input methods are Hello Run
fully supported, and special care was bit.ly/18SB7bS
put into making the interaction tactile
and intuitive. The UI is fully responsive
and supports Retina resolutions using
SVG graphics.

Infiniti Q50 Eau Rouge


bit.ly/1hqIpMe

Graphics
Developed using the three.js engine, we
are rendering a very detailed 3D model.
We use custom shaders to dynamically
change colours as specified by the
client in the backend. The product
thumbnails are also created this way.
Lightmaps created in Maya with
ambient occlusion enhance the object
details and depth.

Samsung Racer S
bit.ly/1U7XVjX

Web 3D
and realism
The key is creatively
executing the content in a way
that is stylised so that it doesnt
have to be real looking it just
tools and browser feature, or trying to needs to be immersive Fortunately the web has its own
match the lighting or render style that emotional, memorable as version of cinematic which is
can be found in popular 3D applications. well as interactive. completely diferent from what you Lights by Ellie Goulding
Its an expectation that should never be experience in real life or in a movie. We are bit.ly/1kv8Xga
set, especially to clients. Its important to allowed to bend the rules and create stylised
remember that were working with 3D in a web browser. fictional worlds and experiences that dont have to be
Nothing will ever compare to the realism of real photo/ 100 per cent realistic.
video content or 3D quality that comes from hours of The web is a magical playground of opportunity
rendering passes in a 3D app. which enables us to combine all sorts of diferent styles,
Movie studios spend years of development time and creative assets and tools to create unique interactive
millions of dollars creating custom special efects and 3D experiences. They can look however we want it to as
scenes for non-interactive blockbuster feature films that long as it is authentic and compelling. Thats what
we are supposed to believe are real. Only the best diferentiates the web from a movie or a photo. And that
movies with the craziest budgets and the best teams is where having a tool like three.js, to make the process
actually make the CG content feel natural. simpler, is vital.

147
:HE'HVLJ
The:HE'HVLJAnnual

insidious-movie.net/entertheroom batmanarkhamknight.com/en_US/batmobile

shanemielke.com/archives/usopen-sessions madmen.withgoogle.com

What can be achieved with WebGL and HTML5 Canvas


WANT TO MAKE 360-DEGREE VIDEO SEQUENCES FOR THE WEB? WELL NOW YOU CAN
use, one must consider the usual things we consider on fair game in Canvas and can really give the feeling of 3D
What can be done with WebGL and all projects. This includes the end creative goal, time to space. Youll see a lot of these types of elements in the
HTML5 Canvas? develop, what assets we have to use or create and the backgrounds or footers of websites to add that extra
So where do we start with the two? Pretty much eternal nemesis of all web developers browser support. immersive punch. Its also great for making things like
anything you can dream of can now be done in the charts or graphs.
browser without a plugin. In fact there has been a revival CANVAS Canvas is also an amazing asset for boosting
of old concepts, ideas and executions that were The Canvas API has been around longer and has deeper performance when handling prerendered 3D content like
previously done with Flash that have risen from the support on all browsers including Internet Explorer (IE9 360-degree image sequences or videos. Performance
ashes. This has prompted the old-school Flash and up. It also has full support on older Android and iOS when interacting with a Canvas-based 360 created from
developers to often say We did that in Flash a long time browsers, but it is definitely a simpler drawing API. JPGs is exponentially faster across all browsers and with
ago. This is nothing new or cool. In this new era of Theres no true 3D support, so you cannot load models less bugs than manipulating the same assets in HTML.
web-based interactive 3D development, individuals with with textures or do complex 3D scenes with crazy
experience in those old ideas, skills and motion lighting, rendering or shaders. Though you can use the WEBGL
sensibilities are highly sought after commodities by drawing tools and good old maths to create basic 3D On the other hand, WebGL has the more advanced 2D
studios around the world looking to create cutting-edge shapes or you can fake it by creating and manipulating and 3D drawing API. Its actually been around for years
content that works on both desktop and mobile. assets in ways that give the illusion of 3D. but does not have the depth of browser support like
So whether it is 3D or 2D content, both the WebGL API Just like the early days of Flash, things like plexus Canvas. It works on all modern browsers but
and Canvas API give us a set of drawing tools to create animations, particle systems, emitters, mouse trails are all unfortunately only works on the most recent versions of
and manipulate assets with better performance, control

Both the WebGL API and Canvas API give


and efects than we can currently achieve with pure
HTML elements.
Keep in mind that both have diferent strengths,
weaknesses, limitations and JavaScript libraries which
us a set of drawing tools to create and
can help you develop content. When choosing which to

148
manipulate assets with better performance

// Expert guide to web 3D

thehobbit.com

Internet Explorer (IE11 and up). It is supported but not Another challenge was compressing a 3D model that can explore and interact with all of the points in the
enabled on all Android devices and was recently enabled held 500MB of detail down to a smaller, more scene as well as view the featured patents and
on browsers for devices that are iOS 8 and up. So the manageable 3MB final file size. The overall experience is inventors which exist on the main abstract 3D shape.
WebGL handcufs have been removed on mobile (sort an immersive click and drag with the ability to pan, and
of) and we can start having fun creating some singular zoom around the vehicle as well as the ability to toggle WEBGL/CANVAS hybrid
solutions that work on all systems and devices. between the Battle and Pursuit modes of the Somewhere in the middle of three.js and pure Canvas
Using a library like three.js to help we can Batmobile to explore all of the key features in development exists tools like Pixi.js. Pixi.js is primarily
easily draw or load true 3D assets in the Canvas each mode. geared towards creating interactive 2D content. It is,
browser to create some really cool Drawing Three.js also great for those fun however, worth noting that it will soon support 3D
interactive 3D content in a short time. For a great example of the immersive conceptual projects we all manipulation of 2D elements. It is a devoted rendering
With three.js youre limited only by Canvas Drawing API in action, dream of being a part of that might engine and drawing API that is blazingly fast with
your ideas. check out The Hunger Games: involve particle clouds, plexus lines, amazing cross-platform support for all devices. It has full
It can be used on any project that Catching Fire site (district13.co.in), data visualisation, globes or assets WebGL support with seamless Canvas fallback so that
has existing 3D assets available. A which uses the API to create the that can be made with primitive you can author once and deploy everywhere in browser.
great example of this is the Batman: appearance of 3D particles shapes, lines and colours, without It was patterned after ActionScript which makes it
Arkham Knight Batmobile Experience and interactions. needing 3D applications. An example intuitive and easy to pick up (especially if you have a
(batmanarkhamknight.com/en_US/ of this is the Adobe Patent Innovation history developing with Flash).
batmobile) for Warner Bros. by Five & Done project (shanemielke.com/work/ When utilising WebGL, Pixi can enable you to use a
(fiveanddone.com). On this Batmobile project a fully adobe-patent). The project is an interactive touch huge set of existing, familiar filters such as blurs,
detailed 3D model was provided by the client and then installation which enables users to explore all of Adobes pixelations and tints but also enables users to create their
three.js was used to create, load, animate and interact patents and inventors in 3D space. It is is currently own unique filters. With a little math sand an animation
with the scene. There were some initial concerns about being installed in the lobby of every Adobe ofice package like that of GreenSock to manipulate properties,
WebGL and a browser being able to exactly match the worldwide and will soon exist as a website. The entire some amazingly powerful particle engines have been
lighting and style of the in-game graphics. So a more scene was created using the three.js drawing tools and created. Pixi.js is very popular as a game development
holographic style was explored using a Fresnel shader as lighting to create a central abstract 3D shape and rendering tool, and its also great for creating create
a way to make the experience feel unique without the surrounded by a swarm of points and plexus lines. The crazy plexus animations, particle systems, emitters,
pressure of replicating the game or what a final rendered points and lines represent all of the patents and mouse trails as well as for handling image sequences
artwork would look like. inventors in a connected relationship in 3D space. Users with 3D content.

149
The:HE'HVLJAnnual

Make an interactive
3D game with WebGL
Learn how to make a Simon Says game with sounds and
animation using WebGL and three.js

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-809
// Make an interactive 3D game with WebGL

R
etro games hold nostalgic appeal to browser resizing or the mouse being pressed and call start of the game. The compSelect array is the computer
people who remember playing them. the appropriate functions, which will be created as we selection of sequence colours; userSelect is the same for
Games themselves are often used as a continue writing the code. the player. Other variables are fairly self-explanatory.
way to engage an audience, just think container.addEventListener( 'mousedown', var menu = f.select("#menu"),
about how many games there are that are used in onDocumentMouseDown, false ); function begin(){
marketing to try and sell the user something. These are window.addEventListener( 'resize', clearTimeout(tmr);
not highly original games, but tap into the audience and onWindowResized, false ); compSelect = [];
spin the game with graphics that make it appropriate for camera.lookAt( scene.position ); userSelect = [];
the content. Learning to code games in the modern onWindowResized( null ); turn = 0;
browser is therefore an important discipline to learn. goes = 0;
In this tutorial the game being created is the old Simon 3. Write your own running = false;
Says game, which was a nostalgic Seventies plastic toy. Now all code that will be added will be done just before incr = 0;
The perfect choice for this is the three.js library because it line 184 for the rest of the tutorial. Here the function is gameOver = false;
can load models, has a Tween Engine and a raycasting created and fired when the Play button is pressed. It }
system that enables interaction. The game consists of hides the title screen, starts to play some speech audio
storing the computers choices and then checking what and then calls begin after a delay of almost a second. 6. Resize the screen
the user presses to ensure they are following the same function ready(){ Now the browser screen resizing is handled so that the
pattern as the computer. Along the way well highlight the info.classList.add("hide"); camera perspective is updated if the screen changes.
buttons pressed and play appropriate sounds. The game simon.play(); The pressing of the mouse button is handled, the mouse
could be made better by spinning the model faster the tmr=setTimeout(function () {begin()}, 950); position on the x and y axis is stored and a ray is fired
longer the game goes on or by speeding up the } into the scene to see the models below the mouse.
selections; theres plenty to explore beyond the tutorial. function onWindowResized( event ) {
4. Game end renderer.setSize( window.innerWidth, window.
1. Get into the code The next function clears the timer that has triggered this innerHeight );
From the project files open the Start folder and then open function for the end of the game and all that the next line camera.projectionMatrix.makePerspective(
the game.html in a code editor such as Brackets. The does is remove the CSS class of hide from the div tag fov, window.innerWidth / window.innerHeight,
code contains the basic CSS and HTML layout and loads with the id of info. This essentially shows the title screen 1, 1100 );
the 3D model. Find line 163 in the code and uncomment again and hides the game in the background. }
the line shown here. This calls the animate loop, which function end(){
hasnt been created yet. clearTimeout(tmr);
animate(); info.classList.remove("hide");
} Event listeners
JavaScript is an event-driven language, which
2. Uncomment the event handlers means that it listens for specific events and then
Just below the previous code you will see comments 5. Begin the game fires the appropriate function when this happens,
that are similar to the lines of code shown here. Remove Now the begin function (called from Step 3) is created such as mouse, keyboard or browser events.
those comments. These listen for events such as the and this clears the values of any variables ready for the

Left
The model that has been loaded is in COLLADA DAE
(Digital Asset Exchange) format and has been created in
Cinema 4D before exporting in the XML-based file

Top left
The WebGL scene is rendered in the browser using the
threejs library (threejs.org), which makes creating 3D
scenes relatively straightforward
Top right
The game has been started with a minimal title screen and
the play button only shows up after first loading all the
sounds and then the 3D model

151
:HE'HVLJ
The:HE'HVLJAnnual

function onDocumentMouseDown( event ) { 8. Other colours over.play();


event.preventDefault(); In much the same way as in the previous step, the blue incr=2;
mouse.x = ( event.clientX / window. and green buttons on the Simon Says interface are tmr=setTimeout(function () {end()}, 700);
innerWidth ) * 2 1; detected. The opacity increase is the highlight and when
mouse.y = ( event.clientY / window. the animation is called to start, this fades it back out 11. Finish the mouse event
innerHeight ) * 2 + 1; again using the Tween library. The final brackets close of the mouse event and if the
raycaster.setFromCamera( mouse, camera ); mouse hasnt detected an object under it then the array
var intersects = raycaster.intersectObjects( 9. Final button is set to null. After this the animate function is created.
scene.children, true ); As before, the yellow button is detected to see if the user This calls itself in a continuous loop using the browsers
has pushed this. The code below checks the users built-in request animation frame. The render function is
7. When the user clicks selection against the computers selection and if they called to display the screen.
Once the ray has detected what models in the scene lie dont match up then a mistake has been made. The
below the mouse when its clicked, an array of models is game over variable is set to true if the mistake is made. 12. Each frame of the game
brought back. If the first object happens to be the red if (INTERSECTED.parent.name=="yellow"){ On every frame of the game the render function updates
button then the button is made to glow, the right sound userSelect.push("yellow"); the models on the screen and checks the game logic.
is played and the users selection is stored in their array. y.opacity = 1; The first thing to do is rotate the Simon Says toy model. It
if ( intersects.length > 0 && turn == 1) { yellowSnd.play(); then detects if its the computers first turn and if it is, it
INTERSECTED = intersects[ 0 ].object; yellowAnim.start(); } calls a function to select a new colour in the game.
if (INTERSECTED.parent.name=="red"){ var c = userSelect.length-1; function render() {
userSelect.push("red"); if (userSelect[c]!=compSelect[c]){ model.rotation.y += 0.001;
r.opacity = 1; gameOver = true; } if (turn == 0 && compSelect.length < 1){
redSnd.play(); running = true;
redAnim.start(); 10. End of the users turn selectNum(); }
} The code here detects how many times the user has
if (INTERSECTED.parent.name=="blue"){ clicked a selection. If the user has clicked more times 13. Playback of existing selections
userSelect.push than the current amount of guesses needs, then the The code now works out if there are previous selections
("blue"); users turn is over and it is handed back to the computer. made by the computer and increments through each
If the game is over then appropriate functions and one with the showSelect function. If its run through all of
sounds are called. the selections then it needs to add a new one at the end,
if (userSelect.length > goes && so the selectNum function is called to add a new colour.

Callbacks
RequestAnimationFrame() will request that your
gameOver==false){
goes++;
if (turn == 0 && incr < goes && running ==
false){
animation function is called before the browser incr=0; running = true;
performs the next repaint. The number of tmr=setTimeout(function () {turnOver(0)}, showSelect();
callbacks is usually 60 times per second. 1200); } else if(turn==0 && incr == goes &&
} else if (gameOver==true){ running == false){

Top left
When the user clicks on a button on the interface it
responds by highlighting, then fading out the light while
playing a sound for that button

Top right
On the computers turn a random number is created to
select the new colour in the sequence
Right
The computer replays its previous selections so that the
player can try to remember the sequence before adding a
new selection to this

152
// Make an interactive 3D game with WebGL

What is raycasting?
An important concept
when creating interaction
in 3D spaces is that of
raycasting. When the user
clicks the screen it is a 2D
flat space, but it is
important to find out what
is in the scene below the
mouse. An invisible ray of
light from the camera is
fired into the scene think
of it as a line extending
from the mouse into the
scene. A list or an array is
returned with all the
models underneath the
mouses position. The first
object in an array is always
at position 0. All we need
to do then is check that
the first object in the array
is actually one of the
clickable buttons on the
Simon Says interface. If it
is one of them, then we
just have to find which one
and then we will play the
appropriate sound and
animation that will give
the user the correct
feedback in the end.

running = true; } else if (rnd == 2){ greenSnd.play();


selectNum(); } compSelect.push("green"); greenAnim.start();
g.opacity = 1;
14. Select a new colour greenSnd.play(); 20. Handing over
The final lines of the render function updates the display greenAnim.start(); The yellow colour is played in this code if that selection
of the screen and runs the Tween Engine. In the has been made previously as it is the last colour in the
selectNum function a random number is generated and 17. Yellow selection sequence. The incr, short for increment, variable is
if that number is zero then the red colour is selected. This The final part to this code (available on FileSilo) doesnt increased by one and then a pause is given so that the
is updated on the screen with the animation and sound, need an if/else statement as it must be the final number sound can play then the release function is called.
while this selection is stored in the computers array. with yellow selected. This is always the final step before } else {
TWEEN.update(); handing over to the user the users selection array is y.opacity = 1;
renderer.render( scene, camera );} cleared and the change function is called after a pause. yellowSnd.play();
function selectNum(){ yellowAnim.start();
var rnd = Math.floor(Math.random()*4); 18. Set audio on change }
if (rnd == 0){ Once the change function is called it comes the players incr++;
compSelect.push("red"); turn and they will have to copy the computers tmr=setTimeout(function () {release()},
r.opacity = 1; selections. Here an audio file is set to play informing the 600);
redSnd.play(); player that it is their turn. After a short pause while the }
redAnim.start(); audio plays, the user can make selections.
21. Test the full game
15. Blue selection 19. The computers sequence The final two functions are added which release the
In the same way as in the previous step if the computer It is necessary for the computer to play back its computer from running the section. The turnover
randomly chooses the number of one, then the blue sequence as well as select a new colour to add to the function passes in either a 1 or 0 for the user or
colour is selected. The animation and sound plays and sequence. The code here is part of the loop that detects computer to determine whose go it currently is and
the selection is recorded in the array compSelect. what colour the computer has selected on previous change them. Save this now and test the game.
occasions and plays that back to the player. function release(){
16. Green selection } else if (compSelect[incr] == "blue"){ clearTimeout(tmr);
Again the if statement checks the random number b.opacity = 1; running=false;}
generated, and this time if it is two the computer plays blueSnd.play(); function turnOver(who){
the green sounds and animation. These steps are slightly blueAnim.start(); clearTimeout(tmr);
repetitive but the nature of choosing diferent elements } else if (compSelect[incr] == "green"){ turn = who;
means they have to be told to play. g.opacity = 1; running=false; }

153
The:HE'HVLJAnnual

Make an image-based
pop-up animation menu
As seen on mediadistribution.espn.com Above the slider
Just above our elements
you can find a neat
parallax slider
showcasing some ESPN
facts, by individual sport.

Within a slider
You may also notice that
the hoverable elements
are contained within a
slider, enabling a larger
selection of elements.

On hover
Hovering on the elements
leads to simultaneous
transitions including
opacity, margin-top and
hidden element changes.

Video backgrounds The pop-up efect


The focus efect is not the Scroll down the page until
only treat on this page, or you find the the elements
within the site. Note the which utilise the pop-up
great use of video efect we are re-creating
backgrounds. in this workshop.
// Make an image-based pop-up animation menu

H
over efects they never go out of layouts and, of course, impressive hover efects. In this
fashion. No matter how much web Web Workshop, were going to create our own version of
design progresses away from the the pop-out menu items that appear about halfway
desktop and further into the touch- down the ESPN page. Hover on any of the images in the
screen world, where hover efects become moot, strip, each corresponding to a sport on the ESPN line-up,
designers still love to come up with new and entertaining and that image will pop out of the strip in full colour,
rewards for placing the cursor on a relevant area of the presenting a link to the relevant page. Its a relatively
page. Not only does it deliver the doorway to the next simple efect, and fairly easy to re-create, but theres a
step in the user experience, but it also make it more small thrill that comes from hovering over each item to
entertaining to knock on that door in the first place. see the same efect. Combining Bootstrap CSS with
Take sports channel ESPNs website: a veritable feast some CSS3 animations, we will build our own pictorial
of background video, parallax animations, responsive menu and re-create the hover efects.

Dont be a purist all the time


Its a common criticism that too many effects and animations are superfluous
and do nothing to enhance the flow of information. While a lean path through
<comment> your site is a must, its also important to remember how many of your users are
What our not web designers and appreciate a bit of animated magic for its own sake.
experts think
of the site
Richard Lamb, freelance web designer at Inspired Lamb Design

Technique </div>
</div>
1. Initial HTML
Our starting point is a container and three menu-item 5. Style boxes
divs within. These divs will contain all the elements, visible As mentioned, set an initial display of none on the
or hidden in static and hover states. Inclusion of linkboxes. Style as you see fit, but a generous padding
Bootstraps CSS will style the container and responsive around both the box and the link, plus a subtle border,
classes. Also add a header and title. looks good and corresponds with the look of the ESPN
site that we are trying to emulate.
2. Initial CSS .linkbox {
When styling the h1 tag, make sure you are giving display:none;
generous margins above and below, to accommodate adding: 25px;
raising elements. Add transition to the menu-item class, background: #03A678;
covering all possible animations. Dont forget the vendor txt-align: center;
prefixes. To align our elements snugly, counter the }
Bootstrap padding either side. .linkbox a {
border: 2px solid #4DAF7C;
3. Insert images color: #ffffff;
Insert your images into each of the three menu-items. text-decoration:none;
You may want to include a max-width of 100 per cent in padding: 25px;
the CSS. Then give each image an opacity of 0.3. }
Combined with the dark background of the div, this gives
each image a darkened appearance. 6. Hover effects
<div class="menu-item col-sm-4"><img Three distinct hover animations bring the efect to life.
src="images/bread.jpg" alt=""/></div> First, what you have to do is just set a minus value to the
.menu-item img{ margin of the menu item. Then set the opacity of the
opacity:0.3; image to 1. Finally, change the display value of the linkbox,
} bringing it into view.
.menu-item:hover {
EXPERT ADVICE 4. Link box HTML margin-top:-50px;
Watch the browsers Underneath the image, but still within the menu-item, transition: all 0.2s;
Browser capabilities is still a constant
headache for many web designers insert a linkbox div which contains an a href link. Repeat }
and developers. Including vendor this for all three menu items. This will be hidden initially, .menu-item:hover img {
prefixes for CSS3 transitions and so move on to the CSS for these elements. opacity:1;
animations is as vital as it is easy to <div class="menu-item col-sm-4"> }
overlook. While Chrome remains top
of the pile, our job is easier, but IE9
<img src="images/bread.jpg" alt=""/> .menu-item:hover .linkbox {
and Opera Mini will still be the ones <div class="linkbox"> display:block;
that will miss out. <a href="#">SERVE ME</a> }

155
The:HE'HVLJAnnual

Make on-click
pop-up tooltips
As seen on dynamite.ch
Of-screen tooltips
The container element is
also responsible for
enabling additional
horizontal elements to
appear of screen until
they are scrolled to.

Background image
The background is
created as a responsive
image of double the
container width to ensure
that the efect works
across all resolutions.

Container to scroll
The container element
has been used here to
enable the map and all of
the markers to scroll
horizontally when the
mouse hovers.

Interactive
markers Moving
Markers can be clicked or background
tapped to reveal new The background image
content, and this enables moves as the mouse
the main design to remain pointer move an illusion
clear when the content is created with container
not required. overflow scrolling.
// Make on-click pop-up tooltips

EXPERT ADVICE

T
he use of hotspots and tooltips enables There are diferent ways that these tooltips can be
you to design your content, avoid your used. Anyone who remembers the game Myst will see Under the influence (of games):
Taking a look at the design of games like Myst, which
visuals for a clean appearance. These how this games concept is similar to the tooltip map use tooltips and hotspots, can help to identify ways
two features involve the ability to allow created in this tutorial where the game uses the tooltip that this concept can be used to increase engagement.
additional content to scroll into view as the user moves concept to enable exploration and interaction with the
their mouse pointer and the ability to present information game scenery instead of focusing specifically on using it Exploration
when the user clicks on designated hotspots. as a method for accessing additional information. People like to explore. Use this as a feature that
enables visitors to access new parts of the website in a
The ability to present information in this way provides This tutorial creates tooltips and hotspots used to
way that is highly targeted to what they have shown an
benefit to design, especially where space is limited and/or present information about buildings in a city. A panorama interest in being presented with.
where the presentation of information detracts from the image is used for the background, with clickable link
websites usability something that can be easy to forget elements placed over image locations that can trigger a Challenge
when focusing on making a design look appealing. pop-up box for access to a new page or website. Is there a way that your design can provide some type
of entertaining challenge? Challenges can be a useful
asset of social media marketing that gives your visitors
Handy for preserving space a reason to share your content with others.

Tooltips and hotspots are useful for allowing content to be presented in a way
Tracking
that is interactive and avoids clutter. This is good for usability experience as well Designing the experience in a way that lets you reveal
<comment> as for presenting an appealing design its not often that a design feature ticks interests through interactions can be useful to help you
understand more about your customers. It makes your
What our the boxes for both categories.
experts think marketing more targeted or can help to close sales.
of the site
Leon Brown, freelance web developer

Technique width: 200%; 8. Speech bubble


height: 100%; For this speech bubble shape, insert a rotated square
1. Establish the HTML background: url('img/background.jpg') #000 before the [data-content] element.
Create a text file called page.html and enter our HTML no-repeat 0 0; [data-marker] [data-content]::before{
from FileSilo this will load the required CSS and background-size: 100%; position: absolute;
JavaScript code as well as build the main page elements. } background-color: #ccc;
The map is made from a block referenced data-map, with content: "\00a0";
link elements inside for the tappable hotspots. 6. Marker elements display: block;
Marker elements placed inside the [data-map] use height: 16px;
2. JavaScript Listeners absolute positioning that is relative to the [data-map]. z-index: 0;
Create another file called map.js. Then we will wait until Markers transition their colour when highlighted and top: -8px;
the page has loaded and listen for mouse or touch have a default + sign as their visible content. Styling is transform: rotate( 29deg ) skew( -35deg );
movements on the <main> tag. JavaScript will set the placed ::before the DOM element. -moz-transform: rotate( 29deg ) skew( -35deg
horizontal scrolling position to that of the mouse/touch );
pointer when events are detected. 7. Marker content -ms-transform: rotate( 29deg ) skew( -35deg
Visible content that appears when a marker is selected is );
3. Define page body placed inside a child element of the marker that has a -o-transform:rotate( 29deg ) skew( -35deg );
The default style rules should be defined, preparing the [data-content] attribute. This element is set as invisible by -webkit-transform: rotate( 29deg ) skew(
<html> and <body> tags to cover the fullscreen width and default, but becomes visible when the parent marker has -35deg );
height. This enables child page elements to be sized in been selected using the :target selector for the parent width: 20px;
relation to the page, they dont work for height by default. [data-marker] [data-content]{ }
position: absolute;
4. Establish main styling display: block; 9. Style individual markers
Create a file called styles.css for your style rules to be z-index: 1; Individual markers need their positions to be defined and
placed in. The first styles to be created will set the size of padding: 1em; set with percentages so that they retain their intended
the HTML, body and main elements the latter being background: #ccc; position on the [data-map] background image.
used as the container for our tooltip map. The <main> color: #000; #itemA{
element has its overflow set to hidden to give the margin: 1em 0 0 -0.5em; top: 46%;
scrolling illusion. border-radius: 0.4em; left: 24%;
width: 15em; }
5. Relative positioning box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.75); #itemB{
The element inside <main> has a [data-map] attribute that opacity: 0; top: 60%;
has the background image, relative positioning and a transition: opacity 1s; left: 37%;
width of 200% of the <main> container width, ensuring } }
that the content scrolls regardless of the size of <main>. [data-marker]:target [data-content]{ #itemC{
[data-map]{ display: block !important; top: 36%;
position: relative; opacity: 1; left: 68%;
display: block; } }