Page 1

.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tas y:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past erro ue_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen me.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] sta d(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(uslee urses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1 n->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refres 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbe h $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { he ntent } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration ad y_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_i ast errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygam creen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange ars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiR leep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + e (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.” n->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install ra on=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti ormat.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec ra ate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_th ef due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA S = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 63 nge(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/p stars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[ (24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $scree h($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem inst er $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.htm ct_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_ent ndle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server valida t_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random imp nge MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star ange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(8 y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80 n->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” nstall bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:tas .html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, statu cessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bund ails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python imp me from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.ty game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstar $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i] _x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :te m “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @tas e_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { rend @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle ex b:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/u python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Cloc = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.eve f event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” gro opment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_ mat| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit .json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec ra grate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_ e.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clo ame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) n pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noech et(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstar $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “ ” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-u nd_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render actio } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle ex b:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’ t < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 48 = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(3 ent in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs o; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $ stars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; ge

the ultimate

javascript manual 2018 20+ practical tutorials! master the world’s most important programming language

Second edition

Digital Edition

• Explore JS frameworks • Dive into VR • Create cutting-edge layouts

180 pages of expert advice enhance your knowledge with in-depth projects and guides


contents

JavaScript Guru Guide 6


Contents

Animation

Features 20 JavaScript tips to blow your mind 8

Site animations with scrollmagic

106

Essential Javascript

16

Build a split-screen landing page

112

Big question

24

Create Micro-animations

118

Introduction to frontend testing

26

Wireframe Rendering in WebGL

124

Gallery

32

integrate photos into video

130

explore creative code with p5.js

134

Frameworks

Performance

The 5 react mind shifts

40

Build a music player with react

44

Stop JS files slowing your sites

140

Material Design with Angular

48

Explore lazy loading

144

Head to head: Vue vs React

53

improve your grunt setup

150

Data Visualisation with Angular

54

Live mockups with Angular

58

Mix Web and native with Astro

62

3D scenes with A-frame and vue.js

156

Real time apps with firebase

68

Virtual reality web apps

160

add push notifications

72

Apps that collect sensor data

166

Immersive Iot experiences

170

UI & RWD layouts with postCss-flexbox

78

Web apps with container queries 

82

Create a custom user interface

88

D3.js charts with SVG gradients

92

Make your site work on touch

98

VR & Iot

Exchange Advice from industry experts

JavaScript Guru Guide 7

174


Essential JavaScript

SuperheroJS A curated collection of articles, books, talks and tutorials all about JavaScript

Handlebars The templating language that comes baked in with Ember

There’s so much out there that no article could hope to cover even half of what’s available, so below I’ve shared some further links and resources to help.

you is a lower-level set of components that you can build your application on top of. It gives you models, collections and views, but lets you choose anything else to fill the gaps. This does mean you have to write a lot more code yourself, but it gives you complete control.

SuperheroJS superherojs.com

Vue

A great suite of curated articles, tutorials, videos, books and conference talks to help you improve your JavaScript and learn what the future holds for the language, too.

vuejs.org

Further reading

EchoJS echojs.com EchoJS is a site where people submit JavaScript content which is then upvoted by the community. It’s a great place to find tutorials and new libraries that people release.

JavaScript Weekly javascriptweekly.com A weekly, curated list of content in your inbox, JavaScript Weekly and its corresponding Twitter account (@JavaScriptDaily) offers a great way to get a dose of JavaScript.

As a relative newcomer to the scene, Vue has been gaining traction recently as a viable alternative to the larger frameworks. Given its comparatively small file size, Vue has a similar feature set to React. It is primarily a tool for building user interfaces but can also communicate with other parts of the application to keep everything up to date. This is all achieved through minimal boilerplate code and uses semantic HTML and CSS where possible to make sure components stay readable and familiar.

Templating With the growth in the use of JavaScript for rendering content on the frontend, templating languages have sprung up to support this.

JavaScript Guru Guide 22

Handlebars handlebarsjs.com Handlebars just uses curly brackets for syntax, which allows you to create templates that are easy to read. It supports basic logical structures such as conditionals and loops to help you output your data. Helpers can also be used to extend this behaviour as needed.

Lo-Dash templates lodash.com/docs#template Lo-Dash, the utility library mentioned earlier, comes with a small templating engine built in. If you find yourself needing some small templates, – perhaps without some of the more advanced features that other solutions offer – Lo-Dash may well be the library for you.

Modules and dependency management As JavaScript apps continue to get larger and the number of files grows, you need to make sure you use some form of system for managing the files, the dependencies between them, and how they are loaded into a page. Having


Essential JavaScript

Browserify This lets you use NodeJS’s modules and npm to manage frontend dependencies

thousands of <script> tags in a page is not a valid approach here!

Webpack webpack.js.org Webpack is able to take every file within a project, work out which parts rely on other modules and compile them together into one bundle. This bundle can then be served from your site, saving the user from downloading lots of files. The behaviour of Webpack can be extended by providing loaders and plugins. These define which types of files should be picked up and bundled and what to do with them once that happens. For example, it’s possible to import CSS styles for specific files and have Webpack extract them into their own stylesheet. The end result is a project with explicit dependencies that can easily be extended in the future.

Browserify browserify.org Similar to Webpack, Browserify takes npm – the module system in Node – and lets us use it on the front end. You write

Webpack Bundle all your assets together to help keep downloads small

all of your code using CommonJS - the dependency system in Node - and use npm to manage those dependencies. Before viewing it in a browser however you must run it through Browserify, which converts it into code that the browser can understand. The downside is that you will need to rerun Browserify every single time you change a file, but this is easily automated and can be done with tools such as Grunt or Gulp.

jspm.io jspm.io Created by Guy Bedford, jspm is a package manager for JavaScript that lets you get modules from a number of sources, including npm, GitHub and others.

ES 2015 Modules netm.ag/polyfill-261 JavaScript took a giant step forward when ES2015 introduced lots of new concepts to the language. One of which was an implementation of modules, which allowed code to be imported and exported. While native support is slowly making its way into browsers,

JavaScript Guru Guide 23

it’s likely you will still need an ES2015 module loader polyfill until all major browsers meet the new standard. Another alternative is to use bundlers that can understand this new syntax and convert it to a level of JavaScript that is compatible with more browsers – Webpack with Babel is a good example.

Conclusion The JavaScript world is vast, and full of great libraries and tools to make your workflow and development easier and more efficient. However, there’s so much out there that it can often be difficult to filter down to the tools you need for your daily work. The approach I recommend is to try a variety of the tools listed that sound like they might suit you, and slowly whittle the list down to just the final few that you can learn in detail and come to rely on for most of your projects. There are new libraries released all the time, but don’t be tempted to chop and change your toolset all the time. Find the ones you like and stick with them. Occasionally, maybe try a new one and see if it can do a better job than your existing tool, but there’s nothing wrong with having your favourites.


React View source files here! All the files you need for this tutorial can be found at netm.ag/reactgit-286

A b o u t t he a u t h o r

Ray Vil l a l obos w: www.raybo.org

t: @planetoftheweb job: Senior staff instructor, LinkedIn areas of expertise: Frontend and fullstack web design and development

react

The 5 React mind shifts Ray Villalobos reveals the five most important things to get

your head around in order to master and fall in love with React Learning React, the JavaScript library for creating user interfaces from Facebook and Instagram, is just crazy. Rather, it seems nuts until you give it a chance. Things get much easier when you understand five key concepts. I call these the five mind shifts. They are: Components, JSX, state, lifecycle methods and one-way data flow. In this article I’ll take a closer look at each of them.

1 Components

Video Ray Villalobos has created an exclusive screencast to go with this tutorial. Watch along at netm.ag/ reactvid-286

Components are chunks of code that can be combined to provide more complex functionality. When you divide your application into components it makes it easier to update and maintain. In React, components are even more important: you don’t just program them, you design your app by thinking of how these components fit together. Let’s use the interface opposite as an example. You can see how it can be divided into three pieces: a box for booking a new appointment, a list view that lets you view the existing appointments, and a search box for looking through them.

JavaScript Guru Guide 40

In HTML, you might think of this application as a series of elements, like this: <div id="petAppointments"> <div class="addAppointments"></div> <div class="searchAppointments"></div> <div class="listAppointments"></div> </div> And that’s also what you’d do in React. You create a single tag ( <div id="petAppointments"> ) that calls a petAppointments component, which then calls the other sub-components as needed. To pass along a configuration object like this, you use the createClass method of the React object. var MainInterface = React.createClass({ render: function() { return ( <div className="interface"> <AddAppointment /> <SearchAppointments />


React

<ListAppointments /> </div> ) } //render }); //MainInterface ReactDOM.render( <MainInterface />, document.getElementById('petAppointments') ); //render There are two render methods. In the MainInterface class we declare the items that will be sent to the browser, and the ReactDOM.render method replaces the <div id="petAppointments"></div> element in your HTML with React’s code. We would then write the code that handles each of our three sub-components. Components make code easy to write and maintain. Once you learn to think of and organise your apps as a series of composable components, building complex applications becomes simpler.

JSX is an extension to JavaScript that allows you to combine XML code with JavaScript 2 JSX JSX (facebook.github.io/jsx) is probably one of the biggest mind shifts and one of the reasons why the library seems so weird. JSX is an extension to JavaScript that allows you to combine XML code with JavaScript. This is sort of what happens with templating languages like Mustache, which let you include JavaScript within HTML. But JSX gets translated (transpiled) into JavaScript. So you are not just building a template, but a structure that gets converted into a series of JavaScript statements. Unlike templating languages, it doesn’t have to be interpreted at runtime. Let’s look at an example. <li className="pet-item media" key={index}> <div className="pet-info media-body"> <div className="pet-head"> <span className="pet-name">{this.state.data[index]. petName}</span> <span className="apt-date pull-right">{this.state. data[index].aptDate}</span> </div> <div className="owner-name"><span className="labelitem">Owner:</span>

In-depth

What is a Virtual DOM? If there’s one thing about React that will win you over it’s the way it manages the DOM using something called the Virtual DOM. Managing the DOM means worrying about inconsistencies between the way browsers handle events and nodes, which is one of the reasons jQuery became so popular. But ask yourself: Why are you mucking with the DOM in the first place? It’s because the state of your application has changed and you need to update your views to match the changes. This is the type of task that would be better managed by a machine, and that’s exactly what React does. React automates the process, so a change in state will render views for you. React’s Virtual DOM is an independent copy of the regular DOM. Why is this faster? When you manage the DOM manually, you trigger a re-rendering process for each modification of the DOM, so if you make 10 changes to the DOM, your browser has to potentially recalculate the DOM 10 times. Borrowing a technique from video games, where the changes to state are cached ‘off-world’ and then pushed to the screen all at once, the Virtual DOM makes rendering happen less often. Another advantage is that you don’t have to worry about browser inconsistencies. The Virtual DOM’s representation is independent of the actual DOM and React will tackle each browser’s rendering independently, so you don’t have to worry about dealing with different methods for different browsers. The best thing about the Virtual DOM is that in most applications, you don’t have to worry about it at all. You worry about your interface, manage the state of your app, and let React do the rest. It’s a refreshing way to work within a modern application.

Example app You can easily see how to structure this app into reusable components

JavaScript Guru Guide 41


Container queries

A b o u t t he a u t h o r

Jonat h an Snook w: www.snook.ca t: @snookca job: Developer, designer, speaker, writer areas of expertise: HTML, CSS, design

Container Queries

Responsive web apps with container queries Jonathan Snook shows you how to transform a complex web app

– with components, states and interactions – using container queries

Res ource Brad Frost has compiled responsive patterns and an exhaustive list of resources on various facets of responsive design and development: netm.ag/bradfrost-285

Responsive web design has been around for over five years now, and in that time we’ve seen a drastic shift in how we approach website development. Media queries let us write CSS based on a variety of conditions, such as resolution, media type and – most popularly – browser viewport dimensions. Design patterns have emerged to help us manage the complexity of building websites that respond to a range of different screens. Brad Frost conveniently maintains a compilation of patterns that you can use for your sites: netm.ag/ frost-285. Generally speaking, these patterns target content based on the full width of the browser’s viewport. In other words, they target elements at

JavaScript Guru Guide 82

a macro level, not at a micro level. On Shopify.com, for example, each band of content is dealt with separately and collapses well on smaller devices. From a design perspective, it’s easier to manage the design for these bands. From a coding perspective, it’s easier, too.

Breakpoints You can either create breakpoints at a global level or at band level. At a global level, it’s not uncommon to see mobile, tablet and desktop breakpoints defined and for the developer to choose how each element will respond within those specific breakpoints. At a band level, you have a bit more control over when


Container queries

each content piece should break. Maybe that twocolumn piece should collapse into a single column at 400px, but that three-column piece should collapse into a single column at 500px. While we have a bit more control when dealing with breakpoints at a band level, we’ve also made things more complex from a design perspective. Most designers working in Sketch or Photoshop will create artboards for a few common viewports: likely portrait mobile, portrait tablet and desktop.

Compared to websites, web apps use smaller patterns across a wider array of contexts When dealing with breakpoints at a band level, the designer needs to move away from this limited number of views and start breaking things down into smaller chunks. Yet all of these bands still need to be presented as cohesive designs, in traditional mockups.

Complex web apps With many art-directed, content-based sites, the patterns are presented in a limited number of scenarios. Web apps, on the other hand, use smaller patterns across a wider array of contexts. A button group might be displayed in a header, the main body, a sidebar or a modal. Now consider all of these contexts multiplied by the variety of viewports on which these pages might be displayed. We’ve gone from three possible

Focus on

Where to declare Since container queries don’t exist as a standards spec, we’re left to figure out where to declare our queries. We have three possibilities: HTML, CSS or JavaScript. Whether you use a pre-built script or build your own solution, you’ll need to know why to choose one approach over another. Defining in CSS Since we declare media queries in CSS, it’d be great to declare container queries there, too. When we do this, we’ll need to use JavaScript to read the CSS file and parse it to find our container query definitions. If you’re serving up files from a separate server (such as a CDN) to your site then you’ll need to have CORS (crossorigin resource sharing) enabled on your servers so the JavaScript is able to read the CSS. Defining in HTML Defining in HTML allows us to get around the CORS issue; the JavaScript will be able to read the HTML to find our container query declarations. Depending on how your project is built, you might have to copy and paste the declarations across every occurrence of a component. Templates help reduce any human errors. Defining in JavaScript Alternatively, you can define your container queries in JavaScript. If you have JavaScript that accompanies your components then these definitions can be embedded with each component (React developers might feel right at home having all of their component concerns defined in one place).

Shopify.com

Each band – the header, intro and content – can be responsively designed independently of each other and without worrying about context

JavaScript Guru Guide 83


Micro-animations

A b o u t t he a u t h o r

Donova n Hu t chins on w: www.hop.ie t: @donovanh job: Frontend designer and developer areas of expertise: CSS animation, web design and development, startups

Animation

Create a set of micro-animations

Donovan Hutchinson discusses how we can create a bank of small, simple animations that can be applied in multiple situations

Video Ever wonder how you can bring animation into the workflow of a larger project and keep it consistent? Donovan Hutchinson explains how in this video from Defuse Dublin: netm.ag/defuse-279

Animations can help our user understand our designs. They can also add polish and even make your site feel faster. We can have animations that introduce the page content, or animations that activate when we interact with the UI or when we scroll. Big, splashy animations are great for attracting attention and making our sites more fun, but it’s the small ones that really boost the quality of our work. We can call these ‘micro-animations’: the small animations that achieve one single purpose, as opposed to larger ones that tell stories through multiple sequences of movements. These subtle movements draw visitors to what we want them to see or understand. A micro-animation

JavaScript Guru Guide 118

might be a list of links fading in, or a Submit button changing from ‘Submitting’ to ‘Done’. These simple animations may not be the main reason people visit your site, but they can make the difference between an average and an exceptional experience. Each one plays a part in communicating your brand.

ANIMATION LIBRARies As we develop our projects and they get bigger and more complex, it’s easy for all these microanimations to become inconsistent. Different timings, easing and styles can add up to problems when conveying a unified brand. We can solve this problem with a little forward-planning.


Micro-animations

Focus on

Transitions vs Animations Aha! A simple, reusable fade animation causes this light bulb to light up on page load (netm.ag/animatepen-279)

In this article, I’ll look at how we can create a library of small, generic micro-animations that can be applied to our projects as needed and reused many times. This common set of source animations can be used across multiple scenarios, and adjusted as necessary by overriding and changing specific properties.

Micro-animations are the subtle movements that add up to an exceptional experience It’s almost like an object-oriented approach, where we create generic animations and associated classes, and modify them as required. This saves the creator from having to reinvent an animation each time one is needed, and also ensures they remain consistent across a project. Once we’ve decided what sort of movements we want to put across, how do we deliver these micro-animations? Putting animations in your style guide (24ways.org/2015/animating-your-brand) is a great way to start. We can define a range of animations, and set out rules for how they are used in our projects.

Transitions and animations are both ways to introduce movement to your web pages, but each works in a different way and comes with its own set of considerations. Essentially, a transition is a rule that tells the browser how to go from one state to another (and back again), whereas an animation is a series of key frames that describe more complex movements. The syntax for the transition property is simpler. You only need to add one rule to your element’s CSS: transition: all 0.5s linear; This tells the browser to animate all aspects of the CSS (height, width, colour, transforms and so on) over a period of 0.5 seconds, and to do so in a linear easing style. If added to a link, then the browser will try to animate the hover state. However, transitions aren’t so great when you want an animation to happen without any interaction – that’s when you’ll need animation. Animations are a series of movements that the browser applies to an element, which usually occur straight away and are not reliant on user input. If you want to fade in some content on page load, this is the option to go for. You can use timing functions to dramatically change the feel of both animations and transitions. Rather than sticking to the basic ease-in or ease-out , try some custom Béziers (I recommend using www.cubic-bezier.com to generate them). With the right Bézier curve, your animations can bounce and zoom around with all sorts of character.

Simple animations Creating your own library may seem a large task, but we can start with basic examples and build them up. Let’s begin by creating some simple animations, and looking at ways we can apply them. Note: In this article I’ve omitted prefixes such as -webkit- from the examples. I’d recommend including these on production code. You can use a service such as Prefix-Free or AutoPrefixer to help streamline this process.

Custom curves Sites such as www.cubic-bezier.com can help you create your own unique Bézier curves

JavaScript Guru Guide 119


Vue.js View source files here! All the files you need for this tutorial can be found at netm.ag/aframe-291

A b o u t t he a u t h o r

David S t ore y

w: www.realise.com t: @david_panik job: Web development manager, Realise areas of expertise: JavaScript development, building rich experiences, driving innovation

Vue.js

Create a 3D scene with A-Frame and Vue.js David Storey shows you how to combine A-Frame and Vue.js to quickly put together a creepy, three-dimensional ghost train experience

res ource Inspired to learn more about using A-Frame? Here’s a great list of guides, components and demos: netm.ag/ resource-291

VR is making big strides in the browser right now, thanks to WebGL and three.js. But for those used to working with a DOM and manipulating nodes, building 3D scenes requires a bit of a shift in mindset. A-Frame from Mozilla, a web framework for building virtual reality experiences, makes things easier for us, allowing the rapid creation of 3D content with familiar HTML-like markup. One cool thing to be aware of is that any changes you make to your A-Frame markup are automatically reflected in the scene. This means we can leverage all the benefits of pairing it with a view framework like AngularJS, React or (as we’re going to do here) Vue.js. Vue is intentionally a lot closer to vanilla JavaScript to work with than Angular or React, but still brings the benefits of things like data-binding and custom components.

Basic scene build In this tutorial, we’re going to use A-Frame and Vue to create a creepy 3D scene. To get started, get hold of the source files we’ve provided and take a look at step 1 (netm.ag/aframe-291). All we’re doing

JavaScript Guru Guide 156

here is including the A-Frame library and creating a simple scene. You’ll notice several elements like this: <a-plane color="#6a41a8" height="2" width="4" position="0 1 -2" rotation="0 0 0"></a-plane> These are plane elements. They’re the simplest feature of a 3D scene: a single-sided, flat surface. We are using these for the walls, floor and ceiling. Since we are working in three dimensions, the position and rotation attributes have three values. The material attribute is where we specify the texture for our plane (the image or colour we’re going to paint on it). You’ll also notice: <a-entity camera="userHeight: 2" look-controls wasdcontrols position="0 2 2" rotation="-45 0 0"></a-entity> This is the camera – the viewpoint from which the user will look into our scene. We’ve configured it so the user can look and wander around at will. Load the example in a browser and try it out.


Vue.js

Adding a monster The scene is a little lacklustre, so let’s add a monster (step 2 of the repo):

Case Study

Ghost Train Builder

<a-obj-model position="0 0 -5" rotation="0 0 0" scale="1 1 1" src="monster-ghost.obj" mtl="monster-ghost.mtl"></a-objmodel> The obj-model attribute is pointing at a .obj file we’ve included in the project. This is a 3D model that’s been created using Blender. While A-Frame is great for quickly building simple stuff with primitives (planes, cuboids, spheres), there’ll be times when you want to create something more advanced. This technique can be used to load highly complex models, but here all we’re doing is adding the rough outline of our popup monster. We now have a static monster in place; let’s give it some life by animating it. This is as simple as adding an a-animation node inside our a-entity : <a-animation attribute="rotation" from="-90 0 0" to="0 0 0" delay="500" dur="2000" fill="both" repeat="-1" easing="ease-out-bounce"></a-animation> We’ve set the animation to repeat indefinitely so the viewer doesn’t miss it (this can be changed to any numeric value). The animation also feels a little linear, so let’s introduce some easing by adding the easing attribute with a value ease-out-bounce . Now the animation has a satisfying bounce at the end. You can see this pulled together in step 3.

This tutorial is based on a recent project at Realise called the Ghost Train Builder (www.ghosttrainbuilder.com). When we first came up with the idea, the aim was to offer a highly customisable experience without having to hard-code every potential combination of user choices. It was for this reason we identified Vue.js a perfect fit – only requiring knowledge of HTML, CSS and JavaScript, it offers templating and is purpose-built for creating user interfaces. The Ghost Train Builder uses Vue’s templating capability to pull in appropriate A-Frame mixins to add skins, music and other options to the A-Frame markup from data files containing user choices. Mixins are predefined A-Frame properties that can be added to entities and reused a limitless number of times. The combination of mixins and the user data file is responsible for the vast majority of the customisation you’ll see on the Ghost Train ride. Room themes, monster skins and their animations, and lighting effects were created in this way. A-Frame entities in set positions have mixin names added from the user data. This allows the Ghost Train to use predefined settings such as lighting styles, monster skin images and animations, and place them on entities in a way that the user decides. Each user’s configurations are then stored in a database, in exchange for a unique sharing URL.

Creating a component What if we want to have multiple monsters, or to configure different types of animation? This is where Vue comes in, allowing us to make our own monster component. First off, we need to instantiate Vue. This involves including the Vue library, ensuring

Speedy scene With the help of A-Frame, we are able to quickly put together a simple (if slightly plain) 3D scene

JavaScript Guru Guide 157


SPECIALS & GUIDES

myfavouritemagazines has over 100 one-off guides and specials which celebrate your favourite subjects. There’s something for everyone treat yourself or give gift.

DELIVERY INCLUDED

https://www.myfavouritemagazines.co.uk/guides

Or call now – UK: 0344 848 2852 Overseas: +44 344 848 2852 MyFavouriteMagazines is the official magazine subscription store of Future. You can save up to 74% on a huge range of popular magazine titles. Every magazine subscription will be delivered direct to your door, and includes free UK delivery; guaranteeing you don’t miss a copy of your favourite magazine.

Technology Bookazine 1713 (Sampler)  

You can subscribe to this magazine @ www.myfavouritemagazines.co.uk

Technology Bookazine 1713 (Sampler)  

You can subscribe to this magazine @ www.myfavouritemagazines.co.uk