IntroductionWelcome| 00:00 |
(music playing).
| | 00:04 |
Hello, thanks for checking out HTML5
| | 00:06 |
Projects, Interactive Charts.
I'm Joe Lowery and I'll be your guide to
| | 00:10 |
building an online interactive bar chart.
This project is great for web apps where
| | 00:15 |
you want to enable the user to easily
chart their own progress in a task.
| | 00:19 |
And then save it for a future reference,
sharing, or just bragging rights.
| | 00:23 |
We'll put the powerhouse HTML5 Feature
Canvas to work and I'll show you how to
| | 00:27 |
import background images, add text, draw
primitive shapes, integrate anchor points
| | 00:33 |
for single direction dragging, display
continuously updated numeric feedback and
| | 00:38 |
much more.
You'll see how to incorporate an HTML5
| | 00:42 |
Web Storage Solution to effortlessly keep
track of the chart progress from day to
| | 00:46 |
day, as well as how to save the entire
chart to admire or share.
| | 00:50 |
Sound good, then let's get going with
HTML5 Projects, Interactive Charts.
| | 00:55 |
| | Collapse this transcript |
| About the exercise files| 00:00 |
I'm very happy to announce that any
member of lynda.com now has access to the
| | 00:05 |
exercise files used throughout this
title.
| | 00:08 |
Naturally the information in this course
is ultimately intended to be applied to
| | 00:12 |
your own webpages.
However, you may find it helpful to work
| | 00:16 |
with these supplied exercise files to
practice the steps safely and without
| | 00:21 |
creating your own examples.
To begin using the files from the site,
| | 00:25 |
download them, extract them, and then
store those files in a convenient
| | 00:29 |
location, such as your desktop.
Or, if you're using a local web server
| | 00:34 |
like I am, your web server root.
(SOUND) I've got Map running, so my files
| | 00:41 |
are located in the htdocs folder found in
the Map Application folder.
| | 00:46 |
The exercise files folder is organized by
chapter and the chapters are broken down
| | 00:52 |
into its various lessons.
Within the lessons chapters there are a
| | 00:57 |
series of items.
Typically HTML, CSS, images, and so forth.
| | 01:02 |
All of which make up the practice file.
For most lessons, you'll also find a
| | 01:07 |
folder named final, which contains the
completed lesson file.
| | 01:12 |
You're free to explore this at your
leisure, of course.
| | 01:15 |
Now you can either follow the whole
course, chapter by chapter, or jump in at
| | 01:20 |
any point.
If you'd rather not use the exercise
| | 01:23 |
files, you can definitely follow along
with your own assets.
| | 01:27 |
| | Collapse this transcript |
| Course and browser requirements| 00:00 |
To follow along with this course, the
requirements are pretty straightforward.
| | 00:04 |
From a tools perspective, you'll just
need a code editor, and a number of
| | 00:08 |
browsers for testing.
You can use whichever code editor you prefer.
| | 00:13 |
I'm going to be working with Aptana on
the Mac.
| | 00:16 |
A free editor for both Mac and Windows.
Most of our browser demonstrations and
| | 00:21 |
testing will be done using pretty current
versions of standard base browsers like
| | 00:25 |
Google Chrome or Firefox.
As the focus in this course is on some of
| | 00:30 |
the most recently released technologies
you probably shouldn't depend on the
| | 00:34 |
techniques demonstrated if your client
needs to support legacy browsers like
| | 00:39 |
Internet Explorer 6.
That's it for tools.
| | 00:41 |
From a knowledge perspective you should
be pretty familiar with both HTML and CSS
| | 00:47 |
with a general understanding of Java
Script.
| | 00:50 |
I'll walk through any advanced Java
Script we use, block by block so you can
| | 00:54 |
understand what's going on under the
hood.
| | 00:57 |
Oh, and one last item.
The absolute best thing you can bring to
| | 01:00 |
this course is your imagination.
Although, I'm going to be going through
| | 01:04 |
all the details of applying HTML5
technologies to a specific project,
| | 01:09 |
you'll get the most benefit if you keep
your mind open for other ways you can
| | 01:13 |
apply the same lessons to your own work.
| | 01:15 |
| | Collapse this transcript |
|
|
1. Understanding the ProjectWhat we're going to build| 00:00 |
In this lesson, I'm going to run through
the completed interactive charts project,
| | 00:04 |
so you can see what we'll be building.
If you're the type who likes to dive
| | 00:09 |
right into the code, and you've already
downloaded the exercise files, you'll
| | 00:13 |
find the completed project in the Chapter
1 01_01 folder.
| | 00:19 |
So, welcome to the fictional Trans Planet
Airlines website, where folks planning
| | 00:23 |
their trip to the moon can record their
Lunar Leaping Training progress.
| | 00:28 |
As the instructions say, the idea is to
drag the bar up to show how high you
| | 00:32 |
jumped in your training that day.
So, if I move my mouse over the corner of
| | 00:38 |
day 1, a handle appears, and I can drag
that bar up.
| | 00:44 |
When I do, a number value appears showing
the relative progress.
| | 00:49 |
Let's say I just made it to 4 today,
whether it's inches, feet, yards or
| | 00:54 |
meters, that can be specified later.
The relative number and its relationship
| | 00:58 |
to the height of the bar, is what's
important.
| | 01:00 |
So, here's where a little bit of behind
the scenes techno magic takes place.
| | 01:06 |
Let's say, I've close my browser, and
then come back the next day after a
| | 01:11 |
rigorous session in the lunar leaping
simulator.
| | 01:13 |
I want to mark my progress for day two.
I'll simulate that experience by copying
| | 01:21 |
my URL, and then opening up a new tab,
and pasting it in.
| | 01:27 |
When I scroll down to see the chart, low
and behold, the day one value is
| | 01:34 |
displayed correctly.
We'll use the HTML5 technology Local
| | 01:39 |
Storage to achieve that effect.
Okay, let's bring up the bar for Day 2.
| | 01:49 |
Doing better, made it to 9 this time.
Again, the value is automatically stored
| | 01:53 |
for later.
Alright, let's go for Day 3.
| | 01:58 |
Woah, got up to 17, excellent work, I
think I'm ready to go lunar leaping.
| | 02:06 |
Now, if I want to show everyone how great
I did, I can click the Training Complete
| | 02:11 |
button, and the entire chart, bars,
values, and background, is merged into a
| | 02:15 |
single image, which I can save locally
and then share to my hearts desire.
| | 02:21 |
So, that's the project, and now you're
ready to peek under the hood, so you can
| | 02:25 |
get a better understanding of the various
technologies that are driving this app.
| | 02:29 |
| | Collapse this transcript |
| Highlighted HTML5, CSS3, and JavaScript technologies| 00:00 |
Before we start the actual creation of
the project, let's talk about each of the
| | 00:04 |
key technologies being used.
There are two main technologies brought
| | 00:08 |
into play in this project, Canvas and
Local Storage.
| | 00:11 |
Let's take a quick look at Canvas first.
Canvas brings run-time graphics to the
| | 00:16 |
web, with a terrific degree of control.
Stroke and fill are independently controlled.
| | 00:21 |
It can handle all primitive shapes, like
line, circle, and rectangles.
| | 00:26 |
As well as text and images, perhaps
Canvas' best feature,to my mind anyway,
| | 00:30 |
is that it enables interactive graphics.
You can, as we will in this project,
| | 00:35 |
combine layers of graphic elements, apply
graphic filters, and animate any graphic
| | 00:40 |
element, including moving, resizing, and
rotating.
| | 00:44 |
Happily, Canvas has great browser
support.
| | 00:47 |
As you can see, on it's page on
caniuse.com.
| | 00:49 |
To make the most of Canvas, we're going
to be using a dedicated library called KineticJS.
| | 00:55 |
KineticJS was developed by Eric Rowell
and really brings a lot of advanced
| | 01:00 |
functionality within easy reach.
You can learn more about KineticJS by
| | 01:04 |
going to it's site.
Next, let's take a look at local storage.
| | 01:08 |
You'll find local storage very easy to
use.
| | 01:10 |
One of the primary benefits of Local
Storage is that it provides a much needed
| | 01:14 |
state to websites.
So you can carry variables from one web
| | 01:18 |
page to the next, all without server-side
coding.
| | 01:21 |
Local Storage is browser specific and
provides a much larger storage space, 5MB
| | 01:27 |
vs 40kb for cookies.
Local Storage is set up as a name/value
| | 01:32 |
pair structure, so you'll need to convert
any non-string formats you use.
| | 01:36 |
The two most common commands are setItem
and getItem.
| | 01:40 |
Set item takes two arguments, the item
name and its value, while get item only
| | 01:45 |
needs the name of the item to retrieve
it.
| | 01:47 |
As caniuse.com shows us, browser support
for local storage is really rocking.
| | 01:53 |
As you'll see in the remaining lessons,
the technologies involved in this project
| | 01:57 |
are full featured and pretty well
supported in the browser.
| | 02:00 |
| | Collapse this transcript |
|
|
2. Setting the StageCrafting the HTML| 00:00 |
Before we launch into the canvas oriented
JavaScript, where we'll spend the vast
| | 00:05 |
majority of the course.
Let's bring in the essential HTML, and
| | 00:09 |
include the neccessary JavaScript files.
So I have open, index.htm from the
| | 00:16 |
chapter 2 > 02_01 folder of the excersise
files.
| | 00:21 |
Let's look down at the body section where
we can insert a couple of key HTML elements.
| | 00:28 |
First, we're going to need to add a DIV
with an I.D of container.
| | 00:32 |
This DIV will eventually hold the canvas
tag that will be inserted at runtime by
| | 00:39 |
our JavaScript.
I'm going to put this DIV tag right below
| | 00:43 |
the steps DIV that has some instructions
for the site visitor.
| | 00:52 |
We'll give it an I.D of container, and
antenna automatically provides the
| | 01:01 |
closing DIV tag.
Now, right below that, I'm going to add
| | 01:05 |
another DIV to hold the complete training
button.
| | 01:09 |
So, I'll move my cursor to the end, hit
Enter and then put in my DIV tag.
| | 01:15 |
We don't need to give this one an I.D.
Next, I'll enter button, give that an I.D
| | 01:22 |
of save image.
And then the text within the button will
| | 01:27 |
say, Training Complete, exclamation mark.
Now let's go back up to the Head section
| | 01:36 |
so we can link in our JavaScript files.
I've already downloaded the file and
| | 01:41 |
stored it in my script folder, so we'll
put in a script tag.
| | 01:46 |
Give it a type equal to text JavaScript.
And then set the source equal to
| | 01:55 |
scripts/kinetic-v4.40.js, and then, close
the script tag.
| | 02:09 |
Now I've also created a shell file for
our custom canvas code named canvas_chart.js.
| | 02:14 |
Let's add the script tag for that code
next.
| | 02:18 |
Script type, text slash javascript and
the source for this one, also in the
| | 02:34 |
script folder, and it's canvas_chart.js.
Okay we close that tag, and that's really
| | 02:44 |
all the HTML we'll need.
In the next lesson we'll start working
| | 02:48 |
with our custom JavaScript file.
| | 02:49 |
| | Collapse this transcript |
| Initializing the stage| 00:00 |
Our first task in the custom JavaScript
is to get an overview of the modules needed.
| | 00:07 |
The second is to initialize the stage.
Relatively speaking, this is a very
| | 00:11 |
simple process, but I wanted to start out
slow, so we can ease into the coding.
| | 00:16 |
I have opened canvas_chart.js from the
chapter 2 02_02 folder in my code editor.
| | 00:24 |
As you can see, all that's in it are a
series of Javascript comments.
| | 00:28 |
Each comment denotes a major section,
typically a function.
| | 00:32 |
There are six sections in all, but don't
let that low number lull you a sense of security.
| | 00:38 |
Some of the functions are quite lengthy.
On the other hand don't let the length
| | 00:42 |
scare you.
Because we're ultimately going to build
| | 00:45 |
three different bars in our bar chart
much of the work is copy, paste alter.
| | 00:51 |
The first function I want to set up is in
it stage.
| | 00:54 |
We'll take advantage of the kinetic js
syntax to create our stage and point it
| | 01:00 |
toward our container DIV.
So, let's begin by naming it function initStage.
| | 01:07 |
Put in an open and curly closing brace,
and we'll declare our first variable,
| | 01:17 |
named stage, and set that equal to new
Kinetic.stage.
| | 01:22 |
So, this is a kinetic stage object.
And within the parentheses we'll put a
| | 01:26 |
set of curly braces, and then I'll hit
Enter to make a little room.
| | 01:34 |
And this is the first of our array
elements, container, colon and then
| | 01:41 |
single quotes, container, which is the ID
of the DIV that's going to hold the
| | 01:47 |
canvas tag.
Next, we're going to give it a width and height.
| | 01:52 |
So, enter a comma with 600 height, 400.
Now let's put a semicolon here to close
| | 02:03 |
off that line.
I'm going to leave an empty line before I
| | 02:05 |
close off the function, as a reminder of
code to come.
| | 02:08 |
And because this function is quite
lengthy, I'm also going to add a comment
| | 02:17 |
Indicating where it ends.
Just good coding practice.
| | 02:23 |
Now that's all the coding we're going to
do in this lesson, but I do want to point
| | 02:27 |
out one thing.
Note that the parentheses following the
| | 02:31 |
initStage function on line 4 are empty.
That's typical for a function that
| | 02:37 |
doesn't accept any arguments.
But watch that space, because in the next
| | 02:43 |
lesson we'll insert code to load the
needed images.
| | 02:48 |
Which will call the initStage function
when it's done.
| | 02:51 |
And we'll need to insert a parenthetical
argument at that time.
| | 02:55 |
| | Collapse this transcript |
| Loading the background image| 00:00 |
Our project uses a nice background image
of Apollo 16 on the moon, courtesy of NASA.
| | 00:05 |
In this lesson, I'll show you a routine
that will load that image, so that it can
| | 00:10 |
be used by canvas.
And the routine is so robust, you can use
| | 00:15 |
it to load any number of images.
After we set that up, we'll add the code
| | 00:20 |
to display the background image on the
canvas.
| | 00:24 |
I have the canvas_chart.js file from the
Chapter 2 02_03 folder open, and we'll go
| | 00:30 |
down towards the bottom of the page where
it says Set Image Sources.
| | 00:36 |
First I need to define a variable for our
image sources.
| | 00:41 |
And I'll call it Sources.
And I'll set the equal to an array.
| | 00:48 |
We'll use the array for the variable, so
that you can load multiple images if you
| | 00:51 |
need to.
We're going to use just one image, and
| | 00:55 |
I'll give that a name of moonSurface,
follow that with a colon, and then our
| | 01:03 |
path needs to be set because it's a
string, in quotes.
| | 01:08 |
So, images/plum_apollo16_big.jpg.
Put a semicolon after var sources.
| | 01:24 |
Next, let's call the function to load the
images, cleverly called, Load Images.
| | 01:35 |
We'll pass two arguments in the
parentheses.
| | 01:38 |
The first is called Sources, and that
passes in the image name and path, or source.
| | 01:46 |
The second argument, after the comma,
defines the callback function, or what
| | 01:53 |
happens next after all the images are
loaded.
| | 01:57 |
The code is set up this way to make sure
that the images are loaded completely
| | 02:00 |
before the stage is initialized and tries
to use those images.
| | 02:04 |
So, the function we're going to call is,
of course, initStage.
| | 02:11 |
Okay, now it's time to build the load
images function, and that's at the top of
| | 02:17 |
the page.
Essentially, we're going to create a new
| | 02:20 |
canvas image object for each element in
the sources array, using the name and the
| | 02:26 |
SRC attribute.
Then, after all the images have been
| | 02:30 |
looped through, we'll call the
initStage's function, and pass in our
| | 02:35 |
image array.
So, we enter the keyword function,
| | 02:39 |
followed by the name of our function,
loadImages, open and close parentheses,
| | 02:45 |
and the two arguments, sources, comma,
callback.
| | 02:50 |
After the closing parentheses, put in an
open and closing curly brace.
| | 02:56 |
And we'll declare our first variable,
which is var images, and set that equal
| | 03:04 |
to an empty array, or an open and closed
curly brace.
| | 03:10 |
The next variable is called Loaded
Images.
| | 03:12 |
And because we're just starting out, that
will be set to 0.
| | 03:23 |
Now we need a counter, and we'll call
that numImages, and also set that to 0.
| | 03:34 |
Next comes a for loop.
For, open and close parenthesis, var src
| | 03:42 |
in sources, for every src that's in the
sources array.
| | 03:48 |
And then, after your parenthesis, put in
another open and close curly brace.
| | 03:55 |
Then what we're going to do is we're
going to create a new image object for
| | 03:59 |
each one of those, so as part of the
array's images square brackets src equal
| | 04:05 |
to new Image.
Next we'll use an on load function for
| | 04:15 |
each of those images.
So, after the square bracket, dot onload
| | 04:24 |
and set that equal to a function, open
and close parenthesis, curly brace.
| | 04:32 |
Now we want to check and see if we're
done, basically.
| | 04:36 |
So, we'll put in an if statement with an
open and close parenthesis, and then the
| | 04:42 |
incremented indicator, dot dot
loadedImages is greater than or equal to
| | 04:53 |
the number of images, numImages, open and
close curly brace.
| | 05:00 |
And if that's the case, we're done, so
call the call back, and pass in the
| | 05:07 |
images argument.
Okay, I need to put a closing semicolon
| | 05:13 |
after that second curly brace there, and
one more line of code and this is where
| | 05:18 |
we actually set the source of the file.
So images, square bracket src, dot src,
| | 05:25 |
and set that equal to sources, square
bracket src, close it all off with a
| | 05:27 |
semicolon and we're done.
Now, I want to make the modification to
| | 05:29 |
initStage's, I mentioned in the previous
lesson.
| | 05:43 |
I'll add the argument Images to my
initStage's function call.
| | 05:50 |
Next, we're ready to begin populating the
stage.
| | 05:54 |
So, I'm going to scroll down a little
bit, bring this up to the center.
| | 06:00 |
Now we're ready to start populating the
stage.
| | 06:02 |
The first thing we'll need to do is to
create a background layer.
| | 06:05 |
So, I'm going to put this on it's own
line here, and we do that by declaring a
| | 06:10 |
var bgLayer, and set that equal to new
kinetic.Layer, open and close parenthesis
| | 06:20 |
and a semi colon.
Now we can create our background image object.
| | 06:25 |
Just put in a little comment here,
background image, and a new var bgImg,
| | 06:33 |
background image.
And this will be a new Kinetic.Image,
| | 06:44 |
parenthesis, curly brace.
We want our image to be placed in our
| | 06:49 |
upper left corner of the canvas.
So, my coordinates are going to be 0,0.
| | 06:53 |
So x, colon, 0, followed by a comma.
y, colon, zero, followed by a comma.
| | 07:02 |
Now, we get to say what the image is.
Image colon, and this is where we're
| | 07:08 |
going to reference our images array.
Images dot, you'll recall the name of the
| | 07:15 |
image of my source file was Moon Surface,
follow that with a comma.
| | 07:21 |
Let's give the width, something equal to
600, and the height, which is 476.
| | 07:34 |
One last parameter and that's the name,
colon and we'll set that to image.
| | 07:39 |
All right, a semicolon to close off that
var declaration.
| | 07:44 |
And now, things are really getting
exciting.
| | 07:48 |
So, let's add the background image to the
background layer.
| | 07:52 |
And you do that by declaring bgLayer.add.
And then in parentheses, the name of
| | 08:02 |
whatever it is you're adding to the
layer.
| | 08:03 |
In this case, it's bg image.
And now I'll add that layer to the stage,
| | 08:12 |
Stage.add bgLayer.
Finally we're all set to draw the stage.
| | 08:24 |
Now that's a simple function stage.draw.
So, let's save the page and check our
| | 08:32 |
progress in the browser.
I have the page loaded here.
| | 08:36 |
All I have to do is hit refresh to see
the latest code.
| | 08:42 |
And our background loads.
I'll refrain from making it a one small
| | 08:46 |
step for coders comments, but just
barely.
| | 08:51 |
So, now the stage is set, to start adding
the chart elements in the next chapter.
| | 08:55 |
| | Collapse this transcript |
|
|
3. Drawing the ChartAdding the legend area and labels| 00:00 |
This lesson is dedicated to the legend
area.
| | 00:03 |
That part below the bars with the labels
day one, day two, and day three.
| | 00:09 |
I'm going to start by creating a new
legend area out of a white rectangle.
| | 00:13 |
We're going to put this code below the
initial stage declatation here.
| | 00:19 |
Create a new line, hit Tab so everything
lines up, enter var legendArea, and we'll
| | 00:30 |
set that equal to a new Kinetic.Rect,
short for rectangle, parenthesis and
| | 00:38 |
within those curly braces.
Now i want this to appear at the bottom
| | 00:43 |
of the page stretched all the way across.
So, our x coordinate is going to be 0, so
| | 00:49 |
it'll be flush left, follow that with a
comma, and the y coordinate we're going
| | 00:55 |
to calculate.
So I want to get the height of the stage,
| | 00:59 |
and then make it minus 20.
Because I'm moving it down to 20 pixels
| | 01:05 |
above the bottom.
Now I could have just put in 380, but
| | 01:09 |
this is more generic, and I wanted to
show you a way to calculate it, so that
| | 01:15 |
you could use this routine over and over.
So, get height, parenthesis, minus 20, comma.
| | 01:24 |
And then we'll set the height to 20, and
the width, again we'll use a function
| | 01:29 |
stage.getWidth comma, and we'll fill it
with the color white.
| | 01:37 |
Let's close that all with a semi-colon.
Next we're going to create the labels.
| | 01:44 |
Each label will be it's own text object
with very similar properties.
| | 01:48 |
So, once we code one, we can copy, paste,
alter the other two.
| | 01:53 |
So, this will be my dayOneLabel, and I'll
set up a variable with that name, dayOneLabel.
| | 01:59 |
new Kinetic.text, parenthesis and curly
braces.
| | 02:06 |
So, our first parameter is text, colon,
and this is a sting, so I'll put that in
| | 02:11 |
quotes Day 1, comma.
Next let's set the font size to 12, comma.
| | 02:22 |
Next we need to give the coordinates, so
I'm going to move this in a little bit on
| | 02:25 |
the left, x colon 40 comma.
And then y, I'm going to use a calculation.
| | 02:32 |
I'll take the stage, get height minus 18.
So, it moves it down a little bit from
| | 02:40 |
the 20, that's the top of the rectangle.
fontFamily, I'll set to sans-serif, and
| | 02:50 |
let's fill it with a greyish color.
If you're specifying a hexadecimal value,
| | 02:56 |
you need to put in the hash sign.
So, 333333, okay let's scroll it down a
| | 03:02 |
little bit.
Now before I leave this, let me put in my
| | 03:06 |
closing semicolon.
And now I'm just going to, as I said,
| | 03:10 |
copy this code block, and then, paste it
in once.
| | 03:15 |
Now let's change the variable name from
dayOneLabel to dayTwoLabel, and change
| | 03:20 |
the text from Day 1 to Day 2.
So, we also want to move it over.
| | 03:27 |
So, I'll change the x value to 170 a 130
pixels over.
| | 03:34 |
Let me copy that one, and then paste it
in for my day Three, which I'll change
| | 03:39 |
the variable name from dayTwoLabel to
dayThreeLabel.
| | 03:45 |
Change the text to day 3, of course, and
the x value gets bumped up to 300.
| | 03:51 |
So, where on the stage do the legend area
and the labels go?
| | 03:55 |
Certainly not the background layer.
Let's create a new layer to hold them,
| | 03:59 |
and I'm going to put it just above the
background layer declaration here.
| | 04:06 |
var Layer equals new Kinetic Layer.
All that's left is specifying what goes
| | 04:15 |
where, and where you put your code is
critical, because the order of the code
| | 04:20 |
determines the stacking order or z index.
So, I'm going to move down to where I
| | 04:27 |
have bg layer add bg image, and
in-between these two, I'm going to put in
| | 04:33 |
my four objects.
The first one will be the legend area.
| | 04:37 |
And I'm going to add it to not the bg
layer, but layer.
| | 04:40 |
So, Layer.add legendArea semicolon,
Layer.add, dayOneLabel.
| | 04:51 |
Layer.add dayTwoLabel, and layer add
dayThreeLabel.
| | 05:06 |
Finally, I want to add the layer itself,
and I don't want to put it before
| | 05:10 |
bgLayer, because otherwise it would be
behind the background layer.
| | 05:15 |
I want to have it appear after that.
So, I'll make a new line after stage add
| | 05:19 |
bgLayer and enter stage add Layer.
Okay, let's save this page and see what's what.
| | 05:30 |
Let me refresh the page, and we have
labels in the house.
| | 05:34 |
Now, I know that sometimes it seems like
it's a lot of work for a small result,
| | 05:39 |
but that's pretty much the nature of the
canvas beasts at this point in time.
| | 05:42 |
And structuring your canvas bit by bit is
the best way to get it done.
| | 05:47 |
| | Collapse this transcript |
| Drawing the bars| 00:00 |
It's time to bring the bars onto the
stage.
| | 00:02 |
Again we'll define three new objects,
each similar to each other.
| | 00:08 |
So, it should go pretty quickly and
smoothly.
| | 00:10 |
I'm going to define the bars right after
the initial stage declaration, and once
| | 00:15 |
we define one, it'll be a snap to copy
past alter the other two.
| | 00:19 |
So, first variable dayOneBar.
And we're creating these out of
| | 00:27 |
rectangles, so this will be a new
Kinetic.Rect object.
| | 00:36 |
Now the bars are going to be part of a
larger group.
| | 00:40 |
So, our x and y coordinates can be 0, for
both.
| | 00:47 |
The width for all bars will be 100.
And the height, when they first start
| | 00:53 |
out, will be 10.
We'll name them all bar, and this first
| | 01:01 |
one, I'll give a fill of hashtag b20000.
And that's a hexadecimal color code for
| | 01:10 |
the red that's in our logo.
And with a semicolon at the end, this
| | 01:14 |
one's done.
So, I'll copy it, as well as the line
| | 01:19 |
after it.
Paste it in again, change the variable
| | 01:23 |
name to dayTwoBar.
And we'll change the color, which is the
| | 01:29 |
only parameter we need to change, to
green.
| | 01:32 |
Okay, I'll copy dayTwoBar and paste in a
copy of that.
| | 01:37 |
And then we'll change the variable name
to dayThreeBar and give it a different color.
| | 01:45 |
Let's make this one blue, that's it for
this section, but there's nothing to
| | 01:51 |
preview yet.
You'll have to wait until we add the bar
| | 01:54 |
groups, which comes up in the next
lesson.
| | 01:57 |
| | Collapse this transcript |
| Creating bar groups| 00:00 |
You may be asking yourself, didn't we
just create the bars?
| | 00:03 |
What's all this about bar groups?
Well, we need to create the bar groups,
| | 00:10 |
so we can attach anchors to each bar,
that will allow the bar to be dragged and
| | 00:15 |
rescaled by the user.
So what we'll do in this lesson, is
| | 00:19 |
define each of the bar groups, one for
each bar.
| | 00:22 |
And then attach the bars to the bar
groups and the bar groups to the canvas layer.
| | 00:29 |
Sounds like fun?
Let's do it.
| | 00:32 |
We're going to put our bar groups right
below the bars so let me scroll down,
| | 00:37 |
past those, day one bar, day two bar, day
three 3 bar.
| | 00:45 |
(SOUND).
And I'll add a couple extra lines there.
| | 00:47 |
Now, before we can define the first
group, we're going to have to set up some variables.
| | 00:52 |
These variables are really only
temporary.
| | 00:54 |
But we need to use them in the bar group.
And they'll figure in our coding later.
| | 00:59 |
So the variables are bar oneY, as in y
coordinate, bar twoY, and bar threeY.
| | 01:07 |
They're all set to 370.
Var, barOneY equals 370, semicolon, var,
| | 01:21 |
barTwoY, equals 370 and var, barThreeY.
You guessed it, equals a 370.
| | 01:34 |
Now we're all set to create the bar
groups.
| | 01:36 |
KineticJS includes a group object that we
can take advantage of.
| | 01:41 |
So my first variable name is barOneGroup.
I think you see a method for my madness
| | 01:47 |
here and, we'll create a new Kinetic dot
Group, parenthesis and curly braces.
| | 01:57 |
We'll set the x coordinate to 10, the y
coordinate to the variable we just set up
| | 02:08 |
barOneY, comma and draggable false.
Now we want to make sure that the bar
| | 02:15 |
groups are not draggable because all the
dragging will be done by the anchors.
| | 02:22 |
Alright I'll put a closing semicolon
after my curly braces and parentheses.
| | 02:28 |
And this code block is ready to be Copied
and Pasted and altered, so, barTwoGroup.
| | 02:38 |
We'll need to change the x coordinate,
add 130 pixels to it, so that becomes 140.
| | 02:47 |
We also need to change the y-coordinate
to barTwoY.
| | 02:54 |
Now we're setting these up as variables
rather than as static values, because
| | 02:59 |
once the user drags the bar to a new
location, the y value will change.
| | 03:06 |
Okay, let's do our final bar group and
we'll make this one barThreeGroup.
| | 03:16 |
It's 270 pixels away and it uses the y of
barThreeY.
| | 03:25 |
Cool, now with our bar groups ready to
rock, let's go ahead and add them to the
| | 03:30 |
stages layer.
So let me scroll down to that section.
| | 03:34 |
I'm going to put them between the
background layer and the legend area, so
| | 03:40 |
that they're on top of the background but
behind the legend.
| | 03:45 |
Because we're actually using the legend
area to mask the bottom two anchors that
| | 03:50 |
we'll be adding.
So I'll put my cursor at the end of the
| | 03:53 |
bgLayer.add bgimage line, hit Return, and
enter layer.add(barOneGroup), semicolon
| | 04:03 |
at the end, and two more times.
This time, barTwoGroup.
| | 04:13 |
And finally, layer.add, barThreeGroup.
Our last task in this lesson is to add
| | 04:26 |
each bar to its respective bar group.
For this to render properly, we need to
| | 04:31 |
place this code below the stage set up.
So we'll specify barOneGroup.add(dayOneBar).
| | 04:45 |
(SOUND).
Now I'm going to leave an extra line
| | 04:49 |
between each of these declarations.
Because there's some additional code,
| | 04:54 |
adding the anchors in, to be specific,
that's coming up a little bit later.
| | 04:57 |
BarTwoGroup.add(dayTwoBar).
Finally, barThreeGroup,add(dayThreeBar).
| | 05:21 |
Time to save the page and see if our bars
are where they should be.
| | 05:27 |
Let me refresh the page, and there they
are, at their initial height.
| | 05:32 |
They're not terribly exciting but their
perfectly positioned to integrate the
| | 05:37 |
anchors, which is coming up in the next
lesson.
| | 05:40 |
| | Collapse this transcript |
| Adding anchors for interactivity| 00:00 |
Anchors are a concept in KineticJS that
allow canvas objects to be resized in any
| | 00:06 |
direction and even rotated.
In this lesson, we'll add four anchors to
| | 00:11 |
each bar, one for each corner.
With a free floating object, this
| | 00:15 |
placement would allow a rectangle to be
stretched every which way.
| | 00:18 |
We're going to hide two of the anchors
behind the legend area, so users will
| | 00:23 |
only be able to grab the top two to
resize the bar.
| | 00:27 |
The code for manipulating the anchors,
attaching them and then updating them
| | 00:30 |
when moved, is pretty complex.
So we are going to take a break from hand coding.
| | 00:34 |
I've already included the code in the
canvas chart.js file found in the chapter
| | 00:41 |
3>03_04>scripts folder.
I will however walk through both
| | 00:45 |
functions to explain how everything
works.
| | 00:48 |
But before we get to that, let's put in
the code to call the at anchor functions.
| | 00:53 |
Again, it's fairly repetitive code, which
will allow us to copy, paste and modify.
| | 00:59 |
The code we're going to insert into the
section that we entered in the last lesson.
| | 01:04 |
And that's located towards the bottom of
the init stage group.
| | 01:10 |
So here's my bar one group, add, so after
that I'm going to add anchor, parenthesis.
| | 01:20 |
The add anchor function takes four
arguments the first is the name of the
| | 01:25 |
group that you're adding to.
Bar one group.
| | 01:29 |
Next are the x and y coordinates, and
well start with the top left, 0, 0.
| | 01:34 |
And then, the name of that anchor, which
we're just going to call top left.
| | 01:44 |
Now we need to add an anchor to the top
right.
| | 01:46 |
The x coordinates here will be 100 and
the y still 0, and the name, top right.
| | 02:01 |
Now let's move to the bottom right, and
add another anchor there for the bar one group.
| | 02:09 |
The x coordinate here will be 100.
And the y coordinate 20.
| | 02:15 |
The name of course will be bottom right.
Finally, for this group, add anchor bar
| | 02:24 |
one group 0, 20.
And that would be the bottom left.
| | 02:35 |
Okay, now that we have those four done,
let's just copy them, and then I'll paste
| | 02:41 |
them right below the bar two group.
And all we really need to do is to just
| | 02:46 |
change the name for those.
So I'm just going to select and copy bar
| | 02:50 |
two group there and then for each anchor,
I'll select and paste in contents of my clipboard.
| | 02:59 |
Let's get rid of that extra line I
mistakenly put in.
| | 03:06 |
Now let's add the add anchors for the bar
3 group.
| | 03:10 |
Again, I'll copy my add anchor routines,
paste those in, copy the bar 3 group
| | 03:21 |
name, and then paste it over bar 2 group
4 times.
| | 03:28 |
Okay, our coding is done.
Now, we're going to take a tour of the
| | 03:32 |
add anchor function that we just
referenced.
| | 03:35 |
It's located after init stage.
There's the two functions.
| | 03:39 |
There's function update, and then below
that, is function add anchor.
| | 03:44 |
You'll find it on line 190.
The first two variables you see var stage
| | 03:49 |
and var layer, get the respective objects
as it relates to the specific bar group.
| | 03:55 |
Then, online 194 an anchor is created
from a circle object.
| | 04:02 |
Initially, the stroke width is set to 0
so it's hidden.
| | 04:07 |
We also want it to be draggable.
As you can see by draggable equals true
| | 04:11 |
on line 200.
But not just anywhere.
| | 04:14 |
The drag bound function that starts on
line 202 constraints the movement to the
| | 04:21 |
y axis.
The next set of routines all starting
| | 04:26 |
with anchor on, tell the anchors what to
do when a particular event happens.
| | 04:31 |
It's kind of like the Java script add
event listener function.
| | 04:35 |
The first one is key.
It calls the update function we'll
| | 04:38 |
discuss shortly, whenever the anchor is
moved.
| | 04:42 |
This allows for smooth interaction.
The first argument for each of the anchor
| | 04:47 |
on routines is the event that's fired.
So you can easily see what's happening.
| | 04:53 |
The code block that starts on line 214,
actually incorporates two events, so that
| | 04:58 |
computers that use a mouse or a touch pad
would benefit from the mouse down event.
| | 05:04 |
Whereas devices that use touchscreens
could use touch start.
| | 05:09 |
The last two anchor on functions,
starting on line 227, are used to show
| | 05:14 |
and hide the anchor circles on mouse over
and mouse out.
| | 05:18 |
This happens by changing the stroke
width.
| | 05:22 |
And if we scroll down just a little bit
more, the last line in this routine
| | 05:25 |
completes the functionality by actually
adding the anchor to the group.
| | 05:29 |
Okay, let's take a quick look at the
update function and we'll scroll up above
| | 05:34 |
add anchor.
And there you see update function
| | 05:40 |
starting on line 156.
As I said, this comes into play whenever
| | 05:44 |
an anchor is moved.
The function opens by defining a series
| | 05:48 |
of variables that basically establish
which anchor goes on which corner, and is
| | 05:54 |
attached to which bar?
It also gets the current anchor x and y.
| | 05:59 |
Then, around line 169, the x and y
coordinates are updated according to
| | 06:06 |
whether the top left or top right anchor
are involved.
| | 06:09 |
There's no need to specify bottom left
and bottom right, because we won't be
| | 06:14 |
using those.
Then on line 180, the entire bar is
| | 06:18 |
placed at it's new position.
And finally, starting around 182, the
| | 06:25 |
width and height are adjusted.
Well, that's certainly a lot of info, so,
| | 06:30 |
why don't we see it in action?
I'm going to save the page, and then go
| | 06:34 |
to the browser.
Let me refresh the page.
| | 06:37 |
And no apparent change, but I move my
mouse over the corner of one of the bars,
| | 06:44 |
you'll see the circle appear.
This is the anchor.
| | 06:48 |
My pointer change to a hand, so and if I
drag it up, the bar in the bar chart rises.
| | 06:58 |
Let's try it on another end.
Here's my Day 1, and just to be complete,
| | 07:04 |
let's try Day 3.
All right, that's working quite well.
| | 07:08 |
I know it's not quite magic, but pretty
close.
| | 07:11 |
The next step is to display some number
values that relate to the dragged bar height.
| | 07:17 |
So I'll see you in the next lesson.
| | 07:19 |
| | Collapse this transcript |
| Connecting the feedback| 00:00 |
In the previous lesson, we got the
interactive bars working, where the user
| | 00:04 |
can drag them to any height.
But the project needs corresponding
| | 00:08 |
numbers to convey exact values.
We'll put those much needed numbers on
| | 00:13 |
screen in this lesson.
And even hook them up to the bar height
| | 00:16 |
for real time updating.
Let's start by creating three text
| | 00:20 |
objects for the numbers.
We're going to put this code after the
| | 00:24 |
bar groups are defined and before legend
area.
| | 00:28 |
That's around line 74, so let's scroll
down there.
| | 00:32 |
And we want to put it right in front of
legendArea here.
| | 00:37 |
So again, we can create one object, and
then Copy, Paste, Alter.
| | 00:45 |
Only the x and y coordinate values will
vary for these different objects.
| | 00:49 |
So it's var, dayOneText, and this is a
new Kinetic.Text.object.
| | 01:01 |
The content for it, I'm actually going to
put in as an empty string.
| | 01:05 |
Because I don't want to have any values
there until people actually move the bars
| | 01:10 |
so we'll follow that with a comma.
Let's make the font pretty big its a font
| | 01:15 |
size of 48 and again the x and y values
will be specific for each bar.
| | 01:22 |
So for the day one bar its going to be x
35 y 338.
| | 01:28 |
I should have said earlier that only
actually the x value changes, the y is consistent.
| | 01:36 |
Font family is sans-serif.
And, one of the nice things about Canvas
| | 01:47 |
is that you can independently control the
stroke and the fill of text.
| | 01:52 |
So you can get outlined letters, if you
want, or either with or without a fill.
| | 01:56 |
In order to make the numbers stand out a
little bit more, let's add a black stroke.
| | 02:01 |
So, stroke, colon black, and we'll make
the letters white, with fill, white.
| | 02:10 |
Let me add a semicolon at the end here,
and now we're ready to Copy that code,
| | 02:16 |
Paste it in.
Change dayOneText to dayTwoText and then
| | 02:24 |
change the x value from 35 to 165.
Let's scroll down and make a little more
| | 02:33 |
room and we'll still have that on the
clipboard, so we'll just paste it in again.
| | 02:43 |
DayThreeText, will be 295 as the x value.
So let's go down to that section.
| | 02:52 |
And there it is, and we're going to put
these right after the label.
| | 02:56 |
They could go before, but it doesn't
really matter, as long as they're on top
| | 03:02 |
or after the bar groups.
That's really the only thing that does matter.
| | 03:06 |
And we'll add these to, so layer add
dayOneText, layer add dayTwoText, layer
| | 03:20 |
add dayThreeText.
One last chore to take care of in this
| | 03:26 |
lesson, and that's to make these text
objects, interactive.
| | 03:29 |
We'll insert three functions after the
addAnchor function calls.
| | 03:35 |
So, scroll down, and go, right in front
of, stage draw, and we'll target the
| | 03:42 |
dayOneBar first.
This is a event-driven function so we use
| | 03:48 |
the on syntax.
And it takes two arguments.
| | 03:53 |
First is the name of the event, and the
event that we're going to use is heightChange.
| | 03:59 |
Which is an event specific to kineticJS,
follow that with a comma and then we are
| | 04:05 |
going to tell it what to do and for that
we we will set up a function.
| | 04:10 |
After the opening and closing parenthesis
put a curly brace.
| | 04:14 |
We're going to create a variable called
the Height, and we'll get that using the
| | 04:23 |
get height function.
But I want to make sure it doesn't come
| | 04:26 |
in as a floating number, so I'm going to
use parseInt, a JavaScript function, to
| | 04:31 |
change it to an integer.
And we want to get the height of the
| | 04:36 |
dayOneBar, open and close parenthesis,
divided by 12.
| | 04:44 |
Now I have to admit this is a rather
arbitrary number.
| | 04:47 |
I wanted to have a value returned from
the pixel measurements, as the bar is
| | 04:52 |
changing height, that seem to have some
sort of general sense to it.
| | 04:57 |
So, I tried a bunch of different division
numbers, 12 was one that I liked, and
| | 05:02 |
that's the back story behind that
particular value.
| | 05:05 |
So now that we have the height, let's set
the text to that height.
| | 05:10 |
(SOUND).
This will display whatever the number
| | 05:17 |
value is in our text object.
Okay, time to Copy that function.
| | 05:25 |
So we'll change this to dayTwoBar and
parseInt dayTwoBar also and dayTwoText,
| | 05:38 |
setText to height, okay?
Just to be consistent, I'll go ahead and
| | 05:44 |
Copy that, Paste it in.
And now, we'll change the Two's to
| | 05:52 |
Three's, dayThreebar on, dayThreeBar
getHeight, and dayThreeText.
| | 06:03 |
Okay I'm ready to see some action how
about you?
| | 06:05 |
Let's save that page and power up that
browser.
| | 06:10 |
Okay I've loaded the page in my browser
and now let me hover over the anchor on
| | 06:15 |
day one.
I'll pull it up and there's my text value.
| | 06:19 |
If I continue it all the way it goes all
the way up to the top which is 32.
| | 06:25 |
Not bad, lets check the other two to make
sure that they're working.
| | 06:28 |
There's that value for day two and day
three is good to go as well.
| | 06:34 |
Alright our bar chart is no officially
interactive, nice.
| | 06:39 |
The next chapter will finish up the
project with ways to save the chart selections.
| | 06:43 |
| | Collapse this transcript |
|
|
4. Keeping Track of the DataStoring the user's progress| 00:00 |
In the last chapter, the bar chart went
interactive.
| | 00:04 |
Users can now drag the daily bars to
indicate their progress, and see the
| | 00:08 |
related numeric value.
But since the app is intended to be used
| | 00:12 |
over a period of days, the only way to
retain their progress would be to keep
| | 00:17 |
the browser window open and avoid moving
the bars.
| | 00:21 |
In this lesson, we're going to use a very
handy HTML5 technology called local
| | 00:26 |
storage to automatically record the
height of the bar every time it moves.
| | 00:31 |
And then, display that same height
whenever the user revisits the page in
| | 00:36 |
the same browser.
Cool, eh?
| | 00:38 |
Let's go do it.
First, let's set it up so our app
| | 00:43 |
automatically stores the height values.
Because we want this value stored every
| | 00:48 |
time the height of the bar is changed,
we'll add our code to the height change
| | 00:53 |
routines we previously inserted.
These routines are the second to last
| | 00:58 |
code chunks in the init stage function
right above Stage Draw.
| | 01:03 |
So let's head on down to around line 184.
There's the first of our three routines,
| | 01:10 |
right at line 184.
And we're going to insert a single line
| | 01:13 |
of code in each function that creates a
local storage item with the current
| | 01:18 |
height value.
If the item already exists, it overwrites
| | 01:22 |
the old value with the new one.
So I'm going to put this first one in the
| | 01:28 |
DayOneBar on code block, right after
dayOneText set Text.
| | 01:34 |
And we'll use the local storage set item
functionality.
| | 01:38 |
So it's local Storage, capital S.
Dot setItem, capital I, parentheses, and
| | 01:49 |
you'll recall from our introduction to
local storage in chapter 1 that it takes
| | 01:53 |
two arguments.
The first is the name that you want to
| | 01:58 |
set for your local storage item, and I'm
going to call this DayOneScore.
| | 02:03 |
So DayOneScore.
And then a comma after the single quotes.
| | 02:09 |
And a value you want to store in
DayOneScore and that's going to be the
| | 02:14 |
variable we declared in this function the
height.
| | 02:19 |
Close out everything with a semi-colon.
And now it's basically the same line for
| | 02:24 |
the other two co chunks that we have
here.
| | 02:26 |
So let me just copy that and I'll paste
it in the same relative location but I'll
| | 02:34 |
change the name of the local storage
item, from DayOneScore to day Two score.
| | 02:41 |
and let's do that one more time for the
third item.
| | 02:43 |
Put my cursor in the correct place, paste
it in, and change DayOneScore to day
| | 02:50 |
Three score.
Now that we've put something in local
| | 02:53 |
storage, we can take it out again and use
it.
| | 02:56 |
So right below these three functions,
we're going to add another series of code blocks.
| | 03:02 |
These we'll check to see if the local
storage has been created and if it has,
| | 03:06 |
set the height of the bar to that value.
If it hasn't, it will use the default
| | 03:11 |
height, 10.
So I'll put my cursor after the last of
| | 03:16 |
the 3 and hit return a couple times while
we're at why don't we scroll down so
| | 03:23 |
bring that cursor.
First I'll set up my variable var the DayOneHeight.
| | 03:29 |
And I'm going to set that equal to 10
that's my default value.
| | 03:36 |
Now I'll write out an if statement that
will check to see if the DayOneScore
| | 03:42 |
local storage item exists.
And if it does, we'll add our code.
| | 03:46 |
So, if parentheses localstorage.getitem
parentheses, single quotes, the name of
| | 03:58 |
the item we're getting, DayOneScore.
Then after those ends of parentheses, a
| | 04:07 |
curly brace pair.
And now we're ready to set the
| | 04:11 |
DayOneHeight variable.
So, the DayOneHeight.
| | 04:17 |
And we're going to set that equal to the
value we retrieve from the DayOne Score.
| | 04:23 |
Now you may recall, from my introduction
to the local storage, that it only
| | 04:28 |
handles strings.
So because we want to multiply whatever
| | 04:33 |
the value is by 12 to restore it to its
pixel height, we're going to use a
| | 04:37 |
standard Javascript function, parseInt to
convert the string that's in the DayOne
| | 04:44 |
score local storage to a number.
So parseInt parenthesis theDayOneScore
| | 04:48 |
times 12, and now that we have our
variable declared, let's put it to use.
| | 05:01 |
So I'll enter DayOneBar.setheight
parenthesis and then the value that we
| | 05:09 |
want to set the height to which is, of
course the variable we just calculated
| | 05:14 |
the Day OneHeight, okay.
Let's go ahead and copy that function and
| | 05:22 |
then paste it in and change the initial
variable from the day one height to the DayTwoHeight.
| | 05:32 |
Basically we're changing wherever we see
a one to a two.
| | 05:40 |
So, the day two height equals parse in
the DayTwoScore times 12.
| | 05:47 |
And now, DayTwoBar.setHeight,
TheDayTwoHeight.
| | 05:54 |
And lets do that one more time.
I'll paste in my copied code form the
| | 05:59 |
clipboard and change the ones to threes
so the variable becomes the DayThreeHeight.
| | 06:07 |
We're getting the local storage item,
DayThreeScore.
| | 06:11 |
The DayOneHeight, again we change to
DayThreeHeight.
| | 06:19 |
And again change the DayOneScore to the
DayThreeScore.
| | 06:22 |
Now let's change day one bar or
DayThreeBar.
| | 06:26 |
And finally, one last time we'll modify
the DayOneHeight and make it the DayThreeHeight.
| | 06:35 |
One more task to go and that is to remove
the temporary variables we inserted up on
| | 06:41 |
line 52.
Let's go up there and check em out.
| | 06:46 |
This is the bar 1y, bar 2y, and bar 3y.
And we're going to replace them with code
| | 06:53 |
that retrieves the local stored values.
So I'll delete these and put in my new
| | 07:01 |
variables, which is var the DayOneScore
equals local storage dot get item.
| | 07:13 |
And in single quotes, DayOneScore.
Close that off with a semicolon, and
| | 07:23 |
let's do our copy paste routine again.
So I'm just going to paste it in quickly
| | 07:27 |
two more times and then change the Day
OneScore on the first item I pasted into
| | 07:33 |
day two.
And dayOneScore of the local storage item
| | 07:38 |
name to dayTwoScore.
On the third line of course we're
| | 07:43 |
going to change the ones to threes.
Finally, we need to handle the initial
| | 07:50 |
refreshing of the browser, and establish
some related variables, depending on
| | 07:55 |
whether local storage exists or not.
So I'm going to make a little space and
| | 08:01 |
then put in an if else statement that
checks to see if there is a DayOneScore
| | 08:08 |
local storage item.
So if parenthesis localStorage dot
| | 08:14 |
getItem parenthesis single quote
dayOneScore.
| | 08:20 |
At the end of the line after the closing
parenthesis put in a curly brace pair.
| | 08:25 |
So if the local storage exists we're
going to set up three variables.
| | 08:30 |
The first one is the dayOneScore.
Where we'll get that local storage value,
| | 08:35 |
var the DayOneScore equals local storage
dot get item, parenthesis dayOneScore.
| | 08:51 |
Next we want to calculate the day one
number.
| | 08:57 |
And this is using the parseInt function
again.
| | 09:07 |
Finally, we'll use the day one number as
we set the bar one y variable.
| | 09:13 |
Which you recall is one of the variables
that we had just deleted but that we used
| | 09:18 |
as place holders for awhile.
So var bar one y equals 370 minus and
| | 09:28 |
then in parentheses, you all remember
your math order of operation don't you?
| | 09:34 |
The day one number times 12.
Again, bringing the value that's stored
| | 09:41 |
back to its pixel measurement.
Plus 20, which is the offset value.
| | 09:47 |
After the closing curly brace, put in
else.
| | 09:51 |
And then another curly braced pair.
If we don't have local storage, let's go
| | 09:55 |
ahead and set up some default variables.
So far, the day one score is going to be
| | 10:02 |
equal to zero.
Var, bar 1y is equal to 370.
| | 10:10 |
And var dayOneBarHeight is equal to 10.
So that's the initial values that they
| | 10:19 |
would see.
Okay, we've got our basic code chunk done.
| | 10:23 |
I'll select, copy it, and paste it in the
first time.
| | 10:28 |
You've seen this dance before where we
change our ones to twos.
| | 10:35 |
So day one score becomes day two score.
The variable the day one score now is the
| | 10:40 |
day two score.
We'll be getting the local storage item
| | 10:44 |
day two score now.
The day one number is converted to the
| | 10:50 |
day two number, we'll parse in the day
two score, and bar 1y becomes bar 2y.
| | 11:00 |
And then the day one number, again we'll
change.
| | 11:04 |
Okay so I'm just going to do these last
default values the day two score bar 2y.
| | 11:11 |
dayTwoBarHeight.
Alright one last time aren't you glad we
| | 11:21 |
don't have ten different bars?
Okay, our twos becomes threes.
| | 11:29 |
Day three score, v day three score, the
day three number for day three score
| | 11:49 |
parse int, bar 3y and the day three
number.
| | 11:59 |
And now for our default values, the day
three score.
| | 12:03 |
The bar three y, day three bar height.
Okay, it's that one wonderful and
| | 12:08 |
somewhat terrifying time to save and
test.
| | 12:11 |
My page is saved.
Let's go to the browser, and now I'll
| | 12:24 |
refresh the browser.
Alright, let's try out our new bars.
| | 12:29 |
There's our values changing.
Let's say the first day, we go up to six.
| | 12:34 |
Day two and not much progress, let's go
up to a seven.
| | 12:38 |
And then oh my goodness, can you believe
it?
| | 12:41 |
He's going all the way.
No, he stops at 23.
| | 12:43 |
Still, very good progress.
Okay.
| | 12:47 |
So, let's test it by clicking Refresh
again.
| | 12:51 |
And sometimes, you'll see a slight height
change in the bars when you refresh the
| | 12:56 |
page, as we just did.
That's just a rounding adjustment,
| | 12:59 |
nothing to worry about.
Okay, the hard part of the project is done.
| | 13:03 |
Can I hear a woot?
All that's left is a simple function to
| | 13:07 |
save the complete chart as an image, and
we'll tackle that in the next lesson.
| | 13:12 |
| | Collapse this transcript |
| Saving the chart| 00:00 |
The final element to add is a routine to
create an image from the merged layers
| | 00:05 |
and objects of the canvas.
Once that image is created, it can be
| | 00:08 |
saved, emailed, printed out, shared,
however the user chooses.
| | 00:12 |
This function which uses the JavaScript
function Add Event Listener, is placed
| | 00:17 |
within the init stage routine at the very
end after stage draw.
| | 00:21 |
So let's go down there.
Stage draw is located on line 250, so
| | 00:28 |
I'll just put in a comment here, save
canvas to image.
| | 00:36 |
And the first thing we want to do is get
the training complete button object.
| | 00:41 |
So, the code for that is document
getElementById.
| | 00:48 |
And the ID of the button is saveImage.
After that dot, addEventListener, parentheses.
| | 00:58 |
addEventListener takes 3 arguments.
The first is the event.
| | 01:04 |
We're listening for the click event.
Next is the function that you want to
| | 01:08 |
have happen.
So, let me enter some function code here.
| | 01:15 |
And now we're going to use a canvas API
function called to data URL.
| | 01:20 |
So we want to take the entire stage to
data URL.
| | 01:24 |
So stage.toDataURL all cap parenthesis
and curly brace then we enter the
| | 01:34 |
callback parameter followed by a colon.
And that is a function passing the data
| | 01:45 |
URL Notice the difference in the
capitalization between to data URL, where
| | 01:51 |
URL is all capital letters and data url,
in the function argument, is just an
| | 01:57 |
uppercase U.
Outside the parentheses, we put a pair of
| | 02:02 |
curly braces.
And what we want to have happen is
| | 02:05 |
window.open data URL.
Close that out with a semicolon and then
| | 02:12 |
a semicolon to close out the stage to
data URL line.
| | 02:19 |
And we actually want to go in between the
last curly brace and the closing
| | 02:25 |
parentheses there.
Put a comma because we have a third
| | 02:29 |
argument for add Event Listener.
The third argument is a boolean, true or
| | 02:35 |
false, which determines whether to use
capture or not.
| | 02:40 |
The default and the setting we're
going to use is false.
| | 02:43 |
Basically Use Capture determines the
firing order if we had multiple, add even
| | 02:50 |
to listener functions.
Okay, that's all the code we need, I'll
| | 02:53 |
save and go on over to the browser.
Let me click Refresh.
| | 02:59 |
And because we already have our local
storage routines in place, our numbers
| | 03:03 |
stay the same as that additional code is
added.
| | 03:07 |
Now, let's go down to Training Complete.
I'll click Training Complete, and there's
| | 03:12 |
our PNG or PNG file.
I can right-click on the image and copy
| | 03:17 |
it, save it, email it, what-have-you.
I want to note that the routine that
| | 03:22 |
we're using generates a new window which
some browsers interpret as a popup.
| | 03:29 |
To see the image in those browsers, the
user would need to allow popups for your
| | 03:33 |
application site as I've done here.
| | 03:36 |
| | Collapse this transcript |
|
|
ConclusionNext steps| 00:00 |
Thanks for joining me for HTML5 Projects,
Interactive Charts.
| | 00:04 |
Canvas is such a rich technology that I
had to create a number of other HTML5
| | 00:10 |
project courses to explore it.
You can check out all of the available
| | 00:13 |
titles by visiting my authors page on
lynda.com.
| | 00:17 |
| | Collapse this transcript |
|
|