Graphics Tutorials https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/ Tutorials for various Graphics Group Classes Sat, 30 Jan 2021 02:10:38 +0000 en-US hourly 1 https://wordpress.org/?v=5.7.11 Getting Started with TWGL m4 (matrix library) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/getting-started-with-twgl-m4-matrix-library/ Wed, 16 Sep 2015 22:58:36 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=82

For the programming assignments, you will need some basic matrix support to do transformations. You could program this yourself, but you are also welcome to use a matrix library that does it for you. Doing it yourself is good because you have to understand it – but it’s a lot of busywork. Learning to use a matrix library is a better idea, since its what you need in the “real world”.

For doing graphics, we need 4×4 matrices and the associated vectors. There are a few JavaScript libraries out there for this. glmatrix is the best known. I will recommend that you use the “m4” part of “twgl” since twgl will be useful later in the class. This isn’t a judgment on whether twgl.m4 is better than glmatrix – it’s good enough, and easy.

The twgl webpage is here. The link to the documentation is hidden at the bottom (documentation). Even then, you need to look in the upper right corner of the window to find the real things you need. The documentation for the matrix library (m4) is here – but that’s just for the matrix class. The vector class is documented separately. Even then, there are class documentation, but no general guidance on how to get started.

Hence, a tutorial.

Getting Started With TWGL

To use twgl, you need to load it in your html page (load it before your script). If you want to have it load fast, use the minified version. If you want to be able to read the code, use the other version. Either way, you need the “full” version so it has matrices.

I have put a copy of twgl on the graphics group web server so you can access it from JSBin programs. Or you can put the file in your local directory so it loads fast. For things you turn in, its best to refer to the online version – or you can turn in a copy of the library with your handin.

Loading twgl adds one global “variable” – twgl. This is using javascript objects as namespaces and modules (something to get used to as a JavaScript programmer). Within twgl, there is a field called “m4” that is another object that contains the matrix library. I find it’s easiest to create a variable called just “m4” so I don’t need to keep referring to twgl.m4.

4×4 matrices in twgl are actually 1D arrays of length 16 – not really 2D arrays. In fact, they aren’t even normal JavaScript arrays – they are special “Float32Array” which stores things so its easy to pass to WebGL (when you get to that). The m4 functions will take any array of length 16 when they expect a matrix. And the Float32Array generally work just like regular arrays (where each element is a number). Matrices are stored in column major order – which is a little weird. See my other tutorial for an explanation. GlMatrix has the same issue, and explains it on its webpage.

Similarly, points and vectors in twgl.m4 are arrays of length 3. It will always make Float32Array, but you can use any array of length 3 as input to its functions.

To help me experiment with twgl.m4, I wrote something simple that prints out points and matrices so I can try things out. You can look at it here. (link to jsbin, I am not embedding it).

One of the things you’ll notice is that twgl doesn’t have 4 vectors – just 3 vectors. It treats 3 vectors as 4 vectors as 4 vectors with the last component being 1. Most of the time it’s OK. If you have a transformation that does something to the W component (like a projection), when you use the m4.transformPoint function, it will do the divide by w for you. Beware.

Using TWGL.M4 with HTML5 Canvas

Most of the time, the HTML5 Canvas matrix stack is just fine. But, if you want to use twgl with it (for example, to practice using twgl before we get to WebGL, or a class assignment). The only trick is that you need to apply the transforms you have to each point yourself.

Here is a simple example – a triangle (what’s simpler? I guess I could have just made a line) spinning. Done with both regular canvas and with twgl. Rather than discussing it, I just put lots of comments in the code to help you understand. Again, the link is to JSBin – no embedding.

You probably want to understand this program.

]]>
Matrices and GL https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/matrices-and-gl/ Mon, 07 Sep 2015 01:44:49 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=74

There is some weirdness and confusion in notation for transformations, which becomes real confusion when you actually need to implement it using someone else’s libraries and code.

Short verson:

  • In class, we will use right-handed coordinate systems and the post-multiply convention.
  • In GL (whether its old-fashioned GL, OpenGL, WebGL, …) matrices are stored in column-major form. You can think of this as still being post-multiply, just that all the matrices are transposed (so when you do the multiplications, you actually multiply on the left).
  • In GL, the coordinate system can be either right handed or left handed. The only place where the Z axis direction (into or out of the screen) matters is for the Z-test – and you can pick which function you want for the z-test.

You can see a discussion at the glmatrix web page as well.

Long version:

When we compose transforms, it’s nice to think of it functionally:
non-local coords = transform(local coords)

So we get
final coords = transform( transform( … (transform (local coords))))

If our transforms are linear operators (matrices), this ends up looking like:

    \[ \mathbf{x'} = \mathbf{D\ C\ B\ A\ x} \]

where x is a point in local coordinates,A,B,C and D are transforms (matrices, and x’ is the point in global coords

This is called the post-multiply convention.

If you think about it, this is writing backwards. First apply transform A to the object. Then apply transform B to that. Then apply C. So, some people like to write it:

    \[ \mathbf{y\ P\ Q\ R\ S\ = y'} \]

In this case, y is transpose(x), P is transpose(A), etc.

This is called the premultiply convention.

Aside: be careful that this is re-ordering, not inversion. It is one thing to say:

    \[ \mathbf{x' = M\ x}   \Longleftrightarrow  \mathbf{x^T\ M^T = x'^T} \]

it’s quite another to say

    \[ \mathbf{x' = M\ x}   \Longleftrightarrow  \mathbf{x = M^{-1}\ x'} \]

transpose is not inversion.

Notice that this is just notation that you might not need. If your program doesn’t look inside the matrices, you can happily speak in terms of transformations (assuming that each transformation operator applies to the local coordinates of the objects inside)

translate(...)
rotate(...)
translate(...)
rotate(...)
scale(...)
draw object

Except that sometimes your program actually has to look inside of those matrices. Especially since with WebGL it doesn’t compute them for you.

So now you might ask… is WebGL pre-multiply or post-multiply? And the sad news is you won’t find a consistent straight answer.

Here’s a way to think about it: WebGL does follow the post-multiply convention. However, it stores all matrices transposed. Therefore, you either need to transpose the matrices before sending them to GL (in old-fashioned GL you used the “loadMatrixTranspose” and “multMatrixTranspose” functions rather than “loadMatrix” and “multMatrix.” Usually, you’d use the commands that created the transformations (translate, rotate), so this wasn’t a big issue.

Now, with “modern” GL, you have to implement matrix stuff yourself. Even if you get a library that implements matrix multiply, you still have to make your own stack.

This doesn’t seem to bad. I want to do

    \[ \mathbf{D\ C\ B\ A\ x} \]

I define “multmatrix(M)” to be stackTop = stackTop * M
multMatrix(D)
multMatrix(C)
multMatrix(B)
multMatrix(A)
use matrix for drawing the points

And I just need to remember to transpose the matrix before i sent it to GL (in that last line).

Except… if I am using a library, that library might be designed to keep all of the matrices transposed. So if I say “give me a translation matrix” it will actually give me the TRANSPOSE of the rotation matrix – since it knows that eventually you will want to send it to GL.

We could transpose these matrices into the form we like, multiply the way we think about stuff, and transpose them back.
multMatrix(transpose(get D from library))
multMatrix(transpose(get C from library))
multMatrix(transpose(get B from library))
multMatrix(transpose(get A from library))
use transpose of matrix stack top to draw the points

But that’s a lot of transposing. Instead, we remember that:

    \[ \mathbf{B\ A} = \mathbf{(A^T\ B^T)^T} \]

So we can just keep all the matrices transposed all the time, but just switch left-multiply to right multiply.

So, hopefully, you are wondering “why does OpenGL store the transpose of the matrices?” Which is a good question. This isn’t a mean trick from the developers, it’s a historical artifact.

In modern programming languages (C, JavaScript, Python, …), the convention is to store matrices in row major order. That is is you turn your 2D array (matrix) into a 1D array (list):

1 2 3
4 5 6     1 2 3 4 5 6 7 8 9
7 8 9

In some other programming languages, popular at the time GL was invented, matrices were stored in column major order:

1 2 3
4 5 6     1 4 7 2 5 8 3 6 9
7 8 9

So, in the minds of the designers of GL, they are storing the matrices the right way: non-transposed, but in column-major order. They also thought about things using the pre-multiply convention.

For me, using modern languages, I think of GL as using the matrices transposed, and working with my post-multiply convention. I just need to remember that I need to left multiply rather than right multiply.

I’ve been working with GL variants (beginning with the original IrisGL, and now up to WebGL) since 1989. This has bugged me since day 1. And I still forget it and have to check from time to time.

]]>
Changes in CS559 for 2015 https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/changes-in-cs559/ Wed, 02 Sep 2015 16:50:19 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=70

Warning: this is from 2015. It is kept for historical reasons.

This message was sent to students who were enrolled in CS559 before class began, but the set of people in the class has changed, so not everyone has seen it. This is why we prefer to use this webpage as the primary source for class announcements.


Changes in CS559

You are receiving this email because you are enrolled in CS559 – Computer Graphics – this coming semester, and we want to warn you of some changes to the class. All of these changes are experimental.

The web page for CS559, Fall 2015 is: https://pages.graphics.cs.wisc.edu/559-f15/

First Big Change: The class will be co-taught by Professor Michael Gleicher and Professor Eftychios Sifakis.

This means that if you want to send email to “the professor” you need to send it tocs559.staff@gmail.com – so it gets to both of us. One (or both) of us will see it there and respond. If you send course related email to one of us directly, there will be a delay in response.

Second Big Change: The programming assignments in the class will be done using web-based technologies. Yes, that means no C++ – you’ll be programming in JavaScript. For more information, see: https://pages.graphics.cs.wisc.edu/559-f15/2015/08/16/cs559-in-javascript/

There is a tradition in 559 of making students pick up a new programming language in order to do the assignments for the class. Historically, we have provided a little help (pointers to books, help sessions). This semester we will try to provide another option.

We are going to offer a 1 credit class (a section of CS638) that will “teach” Javascript and Web programming. Another way to phrase it is: if you’re going to spend the time learning Javascript, you might want to get credit for it. For this semester, it will be offered with a 638 number and be offered Pass/Fail only. https://pages.graphics.cs.wisc.edu/638-f15/

We appreciate that many students won’t be able to sign up for 638 because of the timing. We’re only telling you about this now (late August), so you might not be able to fit a 2:30 Tuesday class onto your schedule. You are welcome (encouraged) to look at the readings and assignments for the class, even if you aren’t taking it.

We will take care such that 559 students who are not signed up for 638 will not be at a disadvantage (other than, missing out on some Javascript experience that they could get elsewhere).

If you do sign up for 559 and 638, we will try to make it overlap well. For many of the 638 assignments, you will be able to use your 559 assignments.

Third Big Change: Books All required readings will be made available via the web. There will be a textbook, but Wendt Library has arranged for online access for students. If you want to buy hardbound copies, information is available on the class website.

https://pages.graphics.cs.wisc.edu/559-f15/2015/08/18/books/

If you have any questions, please send us a note at cs559.staff@gmail.com (NOT to Gleicher or Sifakis’ regular email).

We look forward to seeing you on September 3rd (the first day of class) at 11am in room 1120 Biochem.

Mike and Eftychios

]]>
Learning JavaScript https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/learning-javascript/ Sun, 30 Aug 2015 18:37:44 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=54

Warning: This page is out of date

For a more modern take on JavaScript for CS559 see 2021 CS 559 JavaScript page. It’s less philosophical than this page. JavaScript (and JavaScript usage) is evolving so it is a more “normal” language. A lot of what is below is obsolete.

This post gives you some advice on how to learn JavaScript. It spends most of its time giving you a general strategy, and a sense of why this general strategy is the right thing. I recommend getting that philosophical dose, since it will make the reasons for the actual choices in books and stuff make more sense when they do come later down.

Warning: This is from 2015, and Javascript has evolved. New language features make a lot of the weirdness go away. Better constructs mean you don’t need to use the general functional programming mechanisms for everything.

Learning JavaScript

This is assuming you already know how to program in some other language. If you don’t already know how to program, I don’t think JavaScript is the right first language. I also don’t think it’s a terrible choice. However, the way to go about learning your first language will be different since your main focus should be on the concepts that are common across programming languages.

One interesting thing about JavaScript is that it builds on a lot of “foundational” computer science concepts. One of the cool things about JavaScript is that it provides the very basic abstractions that you can assemble into the things you need. This creates two kinds of problems: first, you must understand these foundations of how programming languages work (first class functions, scopes, environments, closures, …); second you must think about programming language feature needs in a general way so you can have an open mind about their being other ways to meet your needs (e.g. think about code re-use, data hiding, polymorphism and information organization rather than rigid classes and hierarchies). I fear that the way many intro CS classes work, they don’t do either of those things: they teach Java features, not necessarily the concepts from which they are built.

The effect of this is that the key to learning JavaScript is to see how it is a manifestation of the foundational programming language concepts, and understand how these concepts can be used to get stuff done in nice ways. The fact that the actual language isn’t an ideal representation of these concepts will get in the way – but try not to focus on that aspect. Try to focus (at first) on understanding why functional programming can be cool, why lexical scope (closures) can give you nice building blocks for making object and module systems, why a uniform and flexible type system lets you do object-oriented programming in the way that you want (for lots of different definitions of the way that you want), etc. If you appreciate that good stuff, you will not only be prepared to learn to work around the bad stuff, but even motivated to do so.

The bad parts of JavaScript will still be there. Being aware of them is important.

There are several kinds of problems with JavaScript:

  1. Issues with it being different (and in some ways better) than what people are using, but people wanting to use it in the old ways.
  2. Issues in it providing basic abstractions that can be used to build language features we’re used to. And often these more basic abstractions are not taught. And we’re (usually) not taught to think about programming languages in general ways, but rather just shown the specific features (not what the general issue they address are).
  3. Issues where its flexibility let you shoot yourself in the foot.
  4. Issues where poor design decisions make things ambiguous or misleading.
  5. Issues from the fact that it’s embedded in the web browser, and the web-browser wasn’t necessarily designed to make it easy for people to write code inside of it. (but this isn’t really JavaScript’s fault)
  6. Issues from non-standardization (different browsers/compilers being incompatible) – these are largely a thing of the past
  7. Other historical issues. It has a name that creates association with something very different, the early implementations of the language weren’t so great, etc. Fortunately, you can view these as historical footnotes.

If you think about this, most of these issues either: don’t effect what you actually program since you will use a modern compiler in a modern browser (and for class we will let you pick 1, so compatibility isn’t a problem) or can be gotten around by taking the time while learning JavaScript to learn to think about things in the right way. Number 3 and 4 will still be there – and you’ll need to learn to protect yourself.

How can you learn JavaScript this way?

Here are three paths:

You could try to learn about the programming language foundations first. Learn to program in a functional language that is a pure instantiation of these concepts. Then JavaScript will just be “Scheme (or Lisp) with ugly syntax.” Even Python has most of these concepts (although people don’t often learn Python this way). I don’t think this is the most practical way to learn JavaScript quickly. Full disclosure #1: this was my path, except that the programming language for me to get at the foundations was one that I was making myself in grad school (called whisper). Full disclosure #2: I am a Python fan, and for me, my biggest complaints with JavaScript are often “but Python does this so much better.”

You could look for resources that emphasize those foundational concepts and functional programming in teaching JavaScript. This is the path that I recommend, providing you can find the appropriate resources. But I’ve done some of the work for you: I’ve found some resources like this, and it’s how I’ll structure my class and the resources I create.

There is one last choice that I advise against: You could pretend JavaScript is like your statically scoped, rigidly typed, simple classical object-oriented language that you are used to. You will complain loudly every time things don’t behave as expected. You will think JavaScript is silly and want to stop using it. You will miss out on the great things that JavaScript’s flexibility gives you. You will be able to survive to do small things (like programming assignments in class), but it will be more painful than it should be.

If it’s not obvious, I am recommending the middle path. The first path might be better if you had enough time (take a programming language theory class before learning JavaScript). But not only is this impractical (I am guessing you want to learn JavaScript NOW), I’m not sure its the best thing. You don’t need to know that much programming language theory to appreciate this stuff, and it tends to over-emphasize certain stuff by trying to be pure.

One downside to the way that functional programming is taught is that it often emphasizes recursion rather than iteration. Being able to use recursion where it is appropriate is important, however learning to use it for everything is not (unless you are using a language that forces you to do things this way). In practice, recursion is harder to learn, often harder to debug, and requires specialized compiler support to be efficient at large scales. To my knowledge, JavaScript is not properly tail-recursive (if you don’t know what that means – don’t worry, it’s one for the programming language geeks, but it is a beautiful concept), so there is little incentive to prefer recursion to iteration except where it is is more convenient for what you are trying to do.

Part of the reason I like JavaScipt so much is it allows me to use the cool parts of functional programming, without having to make everything tail-recursive.

So how do I take this middle path?

Well, you can take my class. Or, someday these notes might turn into a book. But for now…

Books

One aspect of web programming is that the web really is the best resource for it (usually). Books and traditional media don’t evolve as quickly, don’t provide the diversity of viewpoints, and often aren’t the preferred venues of the “real experts.” (If you’re an expert programmer, you might be too busy to write a book, but willing to share your expertise). There are downsides to getting information from the web (how do you know you can trust it?), but to be honest books have this issue too. Except that if its a blog and its wrong, a lot of commenters will point out the problems and the author can update it.

As a JavaScript textbook, Eloquent JavaScript fits the bill. At first, I liked it because it had a free online option (it is free to look at online, but you can buy a printed copy if you want). But I’ve grown to appreciate how it does follow the philosophy I discuss above. It kindof starts out in a weird way – seeming to be telling you the CS101 stuff all over again, but not in a way that would work as a CS101 book. But if you bear with that in chapter 1, it gets better quickly. I am also not fond of his silly examples. And Chapter 4, which is trying to get some deep concepts across by telling it as part of a silly story is weird: the ideas are there, but the silly story kindof got in the way. But if you bear with that, it actually presents the concepts nicely.

Product Details Eloquent JavaScript, by Marijin Haverbeke. (hardcopy at Amazon). I like this book because it is “free” (it is free online, but you can buy a hard copy from a traditional publisher). I also like the spirit of the book (because it focuses on teaching JavaScript as a functional programming language, not as a traditional language). That said, I haven’t compared it to a lot of other books, and I didn’t use it to learn myself, and I haven’t read the whole thing. After reading the whole thing, I like it even more, for reasons discussed here.

Tutorials

There are zillions of JavaScript tutorials out there. If you find one that you think is particularly good, let me know.

Some that I think are notable:

  • A re-introduction to JavaScript (JS tutorial) – An official Mozilla thing. Supposedly an “intermediate level”. A nice concise description of the important stuff.
  • There are actually a lot of great things on the Mozilla tutorials page. I haven’t read them all – but I probably should.
  • JavaScript in Ten Minutes – A misnomer (even he admits it takes more than 10 minutes to read). But it’s useful – a programming language geek rants about what is good and bad about JavaScript, making sense of stuff by using the real CS terminology and concepts.

Tools

Web Browsers: All modern web browsers implement JavaScript well. This hasn’t always been the case. But nowadays, just about any web browser will be good enough. The differences between them are good for debates. Both Firefox and Chrome now have good compilers, debuggers, and profiling tools – I assume that Internet Explorer and Safari do as well (but I haven’t tried them). Make sure you can find the “web developer console” – this is slightly different in each browser, but gives you access to your programs error messages, console logging, as well as the debugger and other tools.

Debuggers: I recommend getting familiar with the debugger before you need it. Being able to step through your program and look at its data is really handy when things go wrong. Looking at the data can be enlightening even when things work (because something JavaScript will represent things internally in a different way than you might expect. Debuggers are built into current web browsers. Some IDEs (see below) offer connections to them.

Editors / IDEs: You can use any text editor you like to edit JavaScript code (and the HTML that loads it). Since you’re just loading these text files into a web browser, you don’t need anything more than a simple text editor. You can use notepad, notepad++, TextWrangler, emacs, vi, or whatever you like. However, you probably want to use something that is a little more specialized for web development.

A good code editor will give you syntax highlighting with integrated checking (see style checking below). They’ll give you autofill, hints about things like function parameters, and other handy things.  It will help you organize your code in various ways. Some even connect to the debugger and browser to give you an integrated development experience.

Personally, I use the tools from JetBrains. Their python IDE (PyCharm) has their web tools (HTML and JavaScript) built in. For Python its the best I’ve seen, especially for mixed language development (mixing python and web stuff). For web stuff, I’m already used to PyCharm and have it installed on my machines. I believe their web development tool (WebStorm) is just PyCharm with some features removed, but I’ve never checked. One cool think about JetBrains: they will give you a free license to the Pro version if you are an education user. There are web development environments based on Eclipse (see Aptana), there are tools from Adobe, and some people I know swear by Visual Studio (especially since it has good TypeScript support).

In the opposite direction: there are some surprisingly good development tools that run right inside the web browser. These have a ton of advantages – no installation, you can work anywhere (since your code is stored in the cloud), there is the potential for easy sharing, … From what I’ve seen (and I’ve only really looked as JSBin, and a quick glance at some others) they are mainly good for small programs (plunker might be better for multi-file development). But since you’ll be writing small programs when you’re learning …

For Example… I started using https://jsbin.com because it allows me to easily embed live code examples right onto web pages (look at the other tutorials). It has an editor with syntax highlighting (which I find helpful) and a code-analysis engine (see hinting below). One catch: to get all the cool coding features, you need to put your JavaScript code into the JavaScript pane, not the HTML pane.

Style checkers: I recommend regularly running your program through a style checker. It will point out potential problems. Things that will either cause bugs, or might cause bugs in the future (if you try to add to or modify your code). It will remind you of good habits you should get into so you will write code that is clean the first time.

Many JavaScript editors have style checkers built in (PyCharm does, even JSBin has some code checking features). Or you can go to http://jshint.com/ and paste your code in.

Source Control: You should keep your program in some kind of source control so you back up old versions. I recommend putting your repositories someone that isn’t your own local computer – either the CS file servers (AFS) or a source control service (BitBucket, GitHub). Or don’t believe me until you learn the importance of source control the hard way when you lose your work.

If you are working by yourself, there are easy ways to get the versioning/backups without a full-blown source control system. If you use a file box service (box.com, dropbox), they can do versioning. Some of the online IDEs (JSBin, for example) will keep multiple snapshots of your work. You can decide how safe, secure and reliable this all is.

]]>
When do I draw? (some comments on code organization) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/when-do-i-draw-some-comments-on-code-organization/ Sat, 29 Aug 2015 03:15:43 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=47

Warning: this is from 2015. Some of it is obsolete – there are newer (and better) ways to do things as JavaScript has evolved.

One thing which is weird about JavaScript (in the web browser at least) is that your program doesn’t have a beginning. It is embedded on a web page, and attached to things. This brings up questions of when your code actually gets run. It is particularly important for drawing – since you want to draw at the right time.

This is a bit of web programming detail – it is more about how web browsers work than graphics or JavaScript. You need to worry about this so your web programs work.

Draw on Start

There’s a problem that when you write some JavaScript code on a web page, there’s an issue of when it actually runs. Consider the most trivial example.

JS Bin on jsbin.com

You would think that the script should run after the canvas gets created. And most of the time it does. But since web browsers are smart, they might not finish step 1 before step 2. So the canvas might not be set up before the script gets run. Or worse, you might not want to put the script in the middle of the body – you might want to load it at the top of the program (especially if you are loading it from another file).

Here’s something that plain does not work: just sticking the code into the top part of your html page (the <HEAD></HEAD> block – which I call the header, although that might technically be a misnomer). It’s not unreasonable to want to put it there – especially if you are loading the script from a file, you might want to have the browser start fetching that file before it needs it. However, if the code runs at the beginning of the web page, it almost certainly will run before the canvas gets created, and will fail.

As with most things web, there are lots of different ways to deal with this “when do I run my script” issue. The one that I use is to have the code execute when the window is finished loading. To do this, I set the window’s “onload” function to be the code I want to execute.

JS Bin on jsbin.com

As you can see, this isn’t too much different than the first example. The big difference is that I’ve put my drawing code in the header of the HTML file. However, rather than running it, I instead define a function with the code inside and assign this to the window’s “onload” attribute. This way, they code gets run when the window is done loading, so that I know that all the HTML objects (like the canvas) have been created.

If you’re a web pro, you probably would have reasons to prefer an even fancier method. But this usually involves learning about some other library (jQuery’s “ready” function seems to be the preferred approach). For this class, onload functions are probably good enough.

I had the code execute with the window’s onload. Some people put it on the body’s onload. I am not sure if it makes a difference. It might make a difference if you put stuff after the body (but still on the web page).

Draw on Update

Here I’m going to do something simple: I want to make a slider (on the web page) and have the X position of the square be determined by the value of the slider. Making a simple slider is easy: there is a “range” object that we can put on the web page. Then, in our script, we can find the slider (just like we found the canvas), and ask it for what it’s value is.

JS Bin on jsbin.com

One trick: we can’t draw the rectangle until after the slider has been made (since we need to ask the slider where we’re supposed to draw). Our “onload” trick from above can help with this.

There’s another trick: when the slider changes, we need to redraw the picture. Remember, we’re using an immediate mode API. When we draw the square, we are actually drawing the picture. If we want the square in a different place, we need to redraw the picture (for now, the whole picture – there are ways around that, but it’s a longer story).

JS Bin on jsbin.com

So what I’ll do is to make the thing that draws my picture into a function (I’ve called it “draw”). I’ll call it during the onload function. But I’ll also want to call the very same draw function each time the slider is moved. Notice the line where I “attach” the draw function to the slider, so it gets called when the slider gets moved.

http://www.impressivewebs.com/onchange-vs-oninput-for-range-sliders/

Some comments on JavaScript Style and Efficiency

Let’s think about this code for a minute – and see how some of JavaScript’s features are leading us into potential problems as this program grows more complicated…

First, notice that draw is a global variable. We can only define one draw function. If we load another module, and it wants to use the name draw, it will over-write this one. For the draw function, this might not be such a big deal – but we probably want to avoid having too many global variables.

Second, notice that on every update, we have to search the whole document for the canvas and the slider. If the document was big, this could be time consuming: and we want draw to be fast, since we want the screen to update as we move the mouse. An obvious thing to do would be to find the canvas and slider once, store them in a global variable. Of course, this makes a yucky global variable. There is also the problem that this has to happen within the onload function (because we can find them until we’re sure the page is ready).

There is a nice way to address both of these problems, using the basic features of JavaScript (the fact that it is a lexically scoped language that supports closures). This is a common paradigm of JavaScript programming that you will see a lot: use scope and closures to build other useful abstractions and achieve things (like modularity) we like.

The idea is that we put everything into the function that gets called onload. Note that in this example, I am also giving that function a name – but we could have created it anonymously as in the previous example. The more important thing to note is how all the things we might have declared as global, are instead placed inside this function – so they can only be seen inside this function.

JS Bin on jsbin.com

Notice how this solves both of the issues above. The draw function is now not global – nothing outside of the setup function can see it. Similarly, I can create other variables (canvas, slider) that are similarly hidden. Since they are inside the setup function (which only gets run at “onload”) they happen at the right time and place. And that I only search for them once when the page loads – not each time the slider moves.

Take time to understand this example – it gives you a sense of a real JavaScript programming idiom. It shows why programming in JavaScript might be different than some other language you’re used to.

Draw All the Time

Suppose I want to just keep redrawing. This doesn’t make sense if the picture isn’t changing, but if the picture is animating (changing on each frame) then I want to keep redrawing. As soon as I finish drawing, I want to draw again (or maybe wait a little while). The trick is that we want to give the web browser a chance to do other stuff too.

JS Bin on jsbin.com

Again, there are probably many ways to do this. The one I learned uses a feature called “requestAnimationFrame.” The idea is that this schedules a redraw at some time in the future. It’s a method of window.

Notice that I commented out the extra call to “draw” when the slider changes. Because the things are being redrawn all the time, we don’t need to force a redraw when the slider changes. In fact, if we ask for an extra draw when the slider changes, this will add another request for a redraw, and before we know it, we’ll have way to many requests, and things will go crazy.

http://creativejs.com/resources/requestanimationframe/
https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

One problem with requestAnimationFrame is that it tries to go fast (60 frames per second). So a different possibility is to schedule the redraw a certain time in the future (some number of milliseconds) use “setTimeout”. You can look up how to do that. You can also look up debates as to why one is better than the other.

What you should have learned

This isn’t really graphics, but its stuff that is useful for writing graphics programs. Hopefully, you got a sense of when you can make drawing happen in your web-based graphics program: this will also be useful when we start using other APIs than Canvas. You saw simple ways to:

  1. Make sure your pictures get drawn onto a web page
  2. Add a slider to your program so you can change things about your picture
  3. Make animation
  4. Use common JavaScript programming idioms to organize your code.

Now you can use this to make something less boring!

]]>
What is a Pixel? (and what is a point sample) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/what-is-a-pixel-and-what-is-a-point-sample/ Fri, 28 Aug 2015 19:14:23 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=37

An updated version of this tutorial is available on the 2021 Course Web

When we talk about image-based graphics, we talk about it being a regular collection (usually a grid) of samples (or pixels). It’s time to be a little more precise about this.

The term pixel is (I’m told) short for the term “picture element.” (Wikipedia, of course talks about this)

Unfortunately, there is an ambiguity when we talk about a grid. And for reasons that we become clearer later, it is better to think about pixels one way rather than the other. Consider a grid:

There are two different things we could refer to as “the elements:” the squares bounded by the lines, or the points at the corner of the square. Note that both of these objects (the squares and the corners) are regular rectangular grids.

It turns out that it is best not to thing about the region inside the square. It is better to think about things as point-samples.  That is a measurement taken at a specific position (where “position” is a mathematical idealization of having no area). It will be much better to think about a pixel as a point-sample.

You might notice that when we take the grid (as in the picture above), there are more corners than there are squares (there is one more row/column). We usually prefer to consider the point sample as being the center of the square. Or, since we use the sample positions much more than we consider squares that are centered on (and surround) the point-samples.

In an image, we make a measurement (usually color or brightness) at each point-sample location. When we say a point sample has a particular color, we are only talking about that specific point in space. Two questions probably come to mind:

  1. What about the spaces in between the samples?
  2. Wouldn’t we have avoided that problem if we instead assigned the color to the area inside the little square?

The answer to #1 is “we really don’t know what happens in between the samples.” A sampled representation only tells us about what happens at the samples. If we’re trying to guess about other places (e.g. to fill in the gaps to make a continuous image), we’re doing just that: trying to extend beyond what we were told. This process of trying to figure out reasonable values for other locations is called reconstruction.

You might think that the problem is that we’ve assigned the color to a point. But, the alternative (assigning the color to an areal region, such as the little square) not only doesn’t help, but creates new problems.

Suppose we did consider that each color is assigned to a little square. It still leaves the problem of deciding what color occurs are the edges and corners where the squares come together. But it also makes the assumption that our picture is made up of squares of constant colors. In the real world, very little is exactly this. Your computer monitor (LCD / Projector) or printer is more like a bunch of dots that blur together. The objects that you’re making pictures of are unlikely to have been made from little squares (unless it’s a tile floor or something like that).

The real problem is that we’re trying to represent something that is continuous (that has a value at every position) using a finite set of measurements. The thing we want to represent (a picture, an image) might be arbitrarily complex. But in an image, we are only storing a fixed size set of measurements. Some information will be lost. Using the point sample model, we are aware of what we’ve lost, and can talk about the best ways to measure that loss, and to reconstruct as well as possible.

If we view each measurement as a point sample, we can choose how we do reconstruction to “fill in the spaces between.” Making little squares is one kind of reconstruction (sometimes called “nearest neighbor” reconstruction because every position is assigned the value of the sample closest to it). Later in the course, we’ll learn about many different kinds of reconstructions.

Of course, considering things as point samples extends more gracefully to cases where we aren’t using a rectangular grid. But more importantly, the mathematics will be far simpler and more elegant.

We’ll explore all this in more detail later when we talk about signal and image processing. But for now, please remember:

A pixel is a point sample.

An image (in the sense of image-based graphics) is a regular grid of point samples,

A pixel is not a little square.

For Further Reading

Wikipedia article on Pixel says where the word comes from and also gets at the point-sample issue.

Alvy Ray Smith’s article “A Pixel is Not A Little Square” 

Terms you should know

Pixel

Point-Sample

Reconstruction

]]>
Image-based graphics vs. Object-based graphics https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/image-based-graphics-vs-object-based-graphics/ Fri, 28 Aug 2015 19:11:23 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=35

There’s a very basic distinction in kinds of pictures (and therefore kinds of graphics) we use with computers. The difference is really simple, but very difficult to describe precisely. In fact, we don’t even have great words for the two categories.

In the old days, they referred to the two types as “raster” and “vector”. I prefer “image-based” and “object-based”.

Here’s a first attempt at the definitions:

  • An image-based (or raster) graphic represents the pictures by measuring the color at a pre-determined set of locations (usually a grid). Think of a picture taken with a camera: it tells you a color for each point taken on a fixed grid.
  • An object-based (or vector) graphic represents the picture by describing the objects in the picture in a mathematical way. For example, I might list the 2D things (lines, circles). The number and positions of these objects can vary.

One of the reasons this gets a little tricky is that we don’t actually look at an object-based graphic. Our display devices are pretty much all image-based. LCD screens, laser and ink-jet printers, CRT monitors, computer projectors – all show raster images (regular grids of color measurements). So, if I try to show you an object-based graphic, it would be converted to an image-based graphic so that it could be displayed. The process of converting an object-based representation to an image-based one is called rendering.

The simplest form of image-based graphic is a grid of pixel values, where each pixel is a color or brightness. Each one is a measurement of what we see at a particular place. Those places are fixed. If we have a different picture (of the same size), we change the colors at those positions. For example, every picture that my digital camera takes has the same regular grid of pixels (for my current camera, it’s a 4592×3056 grid if you care). At each position on that grid a picture has a color. Whether I take a picture of a white wall, or some  complex street scene or landscape, it’s always the same grid – it’s just that the patterns of colors are more or less complex.

 
 
 

sign on trail grey ski slope notwhite-vsmall

Three pictures taken with my digital camera (greatly reduced in size). Each has the same 150×100 grid of pixels, even thought the images are quite different. In an image-based graphic, the places where colors are measured are fixed, while the colors at these positions are different.

 

A simple form of object-based graphic is a 2D vector graphics image, where the picture is represented by a list of 2D objects like lines and circles. These simple pieces are called primitives. An object-based picture might be a list of these primitives. Note that each primitive can be varied in position, and more can be added to make a more complex picture.

   

Three “vector-graphics” pictures. The first two have two lines, albeit in different places and with different colors. The last one is just a grey rectangle. It (should) look the same as the right-most picture above (of the image-based examples).

Note that your web browser has rendered the vector graphics to images to show on your screen.

Object-based graphics are even more common in 3D, where we describe “scenes” as collections of 3D objects. We will typically do this by breaking the scene up into small objects (called primitives).

Let’s contrast those rightmost pictures in each of the boxes. They both appear as grey rectangles. (the photograph might have a spiffy black border around because the website puts borders around images, and it doesn’t consider vector graphics images). The difference is in the representation. The image describes the color at every pixel on a regular grid. Since the picture is 150 pixels wide and 100 tall, this means the picture is a list of 15,000 colors (one for each pixel). They just all happen to be gray. The vector picture representation just says “gray rectangle” (with some other information that says where the rectangle goes).

For a simple picture (like a gray rectangle), an object representation is more convenient since its easier to specify and easier to change.  For a complex picture (like a mountain scene), an image representation is more convenient since it would be really hard to make the exact mountain you see out of simple primitives (whereas, you can make the picture easily with a camera).

In a Graphics Class

Traditionally, computer graphics classes have focused on object-based graphics. It’s often what you think about as “graphics”: making pictures out of complicated 3D objects and then rendering them into 2D images. Images typically were discussed in a different class (like “Image Processing” – nowadays we might call it “Computational Photography”).

However, understanding images is really important for a number of reasons.

  • If you make an object-based representation, you will ultimately need to make an image if you want to see it. So, understanding images will come up (unless you let someone else take care of the rendering for you, which actually isn’t such a bad idea). Note that there are plenty of reasons why you might make an object-based representation of a 3D object besides making a picture of it.
  • Images are increasingly common in computer graphics. With the advent of the digital camera, image-based graphics are everywhere. If you look on your cell phone, most web-pages, in the movies, on pages of a book or magazine, etc. you will see examples of image-based graphics (even if you don’t know know it – most pictures these days, in print, television, and movies, etc. are digital).
  • In fact, you don’t see object-based graphics except in specialized cases. Text (like this web-page) is an important special case. But how often do you actually encounter 3D graphics in your regular life? (other than say, in a computer game, or as a special effect in a movie)
  • Even then, images are a critical part of object-based graphics. Often we describe objects by talking about the images that define their appearance (we’ll discuss this as “texture-mapping” later in the class). And of course, we’ll need to consider how those object-based graphics are ultimately going to be rendered to images.

So, (in this class at least) expect to learn about both object and image based graphics.

What’s so hard about this?

For image-based graphics, it’s easy enough to say “an image is a grid of pixels.” Except that it doesn’t have to be a grid, and I haven’t explained what a pixel is (soon I will).  We’ll explain pixels sometime in the future. If you don’t want to be really precise, and only care about the common cases (or the cases you’re likely to encounter), the distinction really is simple.

The thing that really defines “images” in the sense we’re talking about is that the are sampled representations (we’ll explain what this means at some point – for now, you can think of “we make a measurement at a specific point”) where those samples are taken at specific locations.

Usually in 2D, when we make images, we sample in a (rectangular) grid. A square pattern. it doesn’t have to be that way. We are unlikely to encounter another sampling pattern in class.

From the other perspective, we haven’t really defined object-based graphics very well either. A graphic is a collection of primitives (which we haven’t been too specific about). Of course, our definition has to make it such that a sample isn’t a primitive, otherwise an image-based graphic would be an object-based graphic.

2D and 3D

You can have 3D images – it’s just that the sample positions are in 3D space. You can sample in a grid pattern, or some other pattern.

In this class, we will usually only talk about 2D images. Most of the stuff we do in 3D will be object-based, and we’ll talk about the process of rendering those 3D object representations into 2D images.

3D (and higher) images do exist. In fact, image-based 3D is especially important for medical applications (called volumes) and other places where you are trying to understand what happens “inside” of a solid object. We’ll come back to talking about these volumes at the end of the class (if time permits).

Computer graphics is usually concerned with making pictures of things, so we don’t worry about the insides as much. So typically, when we make 3D things, we only model their outside appearance, and then render them to 2D images. Of course, with the growing importance of 3D medical imaging and 3D fabrication (e.g. 3D printers), learning to model the insides become more important.

Words You Need to Know

  • image-based (or raster) graphics
  • object-based (or vector, or primitive-based) graphics
  • render (rendering) – note that sometimes rendering refers to the more general process of converting from one representation to another, and other times it refers to the specific problem of creating a 2D image from a 3D scene description
  • primitives
]]>
Points, Vectors and Coordinate Systems (why are points and vectors different?) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/points-vectors-and-coordinate-systems-why-are-points-and-vectors-different/ Fri, 28 Aug 2015 19:09:10 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=33

See the updated version on the Spring 2021 CS559 Course Page

It always bugged me that math books made a big deal of the difference between points and vectors. They’re both just a list of numbers, right?

In practice, yes, they are both lists of numbers. But getting an idea of what the difference is helps develop the intuition of coordinate system.

To describe this, let me use an analogy/example: describing walking in a room. Assume that you know which way is north.

  • a vector is a movement that you can make. like “2 steps north, 3 steps east”
  • a point is a position. it’s a place in the room. like “the south east corner” or “the center”

Notice that a vector doesn’t say where you start or end. Just how you should move.

Notice that it makes sense to do arithmetic on vectors. For example you can double the vector (if you do the movement described twice), you can add two vectors (do the first movement, then the second movement – combined into one movement). It makes less sense to do this with points (twice the center of the room?)

Some operations mix the two. You can take a point and add a vector (start in the center of the room, go 2 steps north and 3 steps east). You can take two points and talk about the vector between them (how do you need to talk to get between the points).

Vectors as Points (and points as vectors)

We can add a vector to a point to get another point. This gives us a way to describe points. We need to have a starting point (the origin). And then we can describe other points by the vectors that take you from this origin.

So, a point is just a vector with a known origin.

Think about it this way: if we agree that the south east corner of the room is the origin, then 5 steps north, 6 steps east is the “middle of the room” (for the room I’m in now). Or in Madison, the capitol is the center of the coordinate system, so the computer science department is “12 blocks west” (hence the number 1210).

Coordinate Systems

Having an origin is only part of what we need to interpret a point (or vector). Notice in the descriptions we use the terms “steps north” and “steps east”.

To interpret a vector, we basically need other vectors that will tell us how to interpret each of the numbers. “One step north” and “one step east” are the building blocks from which we build more vectors. These are actually vectors themselves. So, yes, we define vectors in terms of other vectors – the story of the world being carried on the back of a turtle, who is on the back of another turtle, and its turtles all the way down comes to mind (if you don’t know this, don’t worry about it – but I just learned from Wikipedia that its not actually a Hindu myth).

So, to describe what a vector means (in 2 dimensions), we need 2 basis vectors that tell us how to interpret  the two numbers.

If you want to define a coordinate system (something that tell us how to interpret a point) in two dimensions, we need two basis vectors and an origin. If you have these things, then you can take pairs of numbers (2-vectors, or coordinates) and interpret them as points/positions or vectors.

So, if we agree that the origin is the south-west corner of the room, and our basis vectors are a step north and a step east, you can interpret (3,5) as a position: it’s the place you get to if you start at the origin and take 3 steps north and 5 steps west.

Or, to give a more practical example…

If we agree that the origin is the top left corner of the page/screen, that the first basis vector is one pixel down, and the second basis vector is one pixel to the right, then pairs of numbers like (40,75) tell us positions on the page/screen.

Getting to know your bases

If that seems like a roundabout way to get to how we define positions on the screen, you’re right. However, understanding these concepts is really important because it will help us generalize to other bases and coordinate systems.

A quick idea of where this is going…

You could imagine that there are lots of possible bases. Above, I gave one for the screen, but I could have equally picked another one (say, the origin is the center, and the first basis vector is from the center to the right edge, and the second basis vector is from the center to the top edge). If we’re going to talk about positions, we’ll need to know what basis we’re in. We’ll want to be able to use whatever basis is useful, and transition between them. And this is the basis (pardon the pun) of linear algebra.

Notice how we took a geometric problem (describing places and movements) and translated it into a math problem (multiplying and adding lists of numbers).

Next we’ll need to think about bases and spaces a bunch more. But I’ll put that on a separate page.

Read About It In A Book

See Chapters 1 and 2 of “Practical Linear Algebra” (available as part of the online reader).

Terms you need to know

  • point
  • vector
  • origin
  • basis vector
  • basis
]]>
Color: Initial Answers to a Practical Question https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/color-initial-answers-to-a-practical-question/ Fri, 28 Aug 2015 03:05:09 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=25

Color

Color is complicated. We will probably spend a week of class on it – and just scratch the surface of its complexity.

But, between now and then you need to make pictures and you will want to specify what colors are in them. So here’s a short version…

Can I really represent Color as 3 Numbers?

In terms of the physics of light: you cannot.

In terms of the perceptual science (psychology): in theory, 3 numbers are sufficient to capture what most people can see.

In terms of computer graphics: 3 numbers are often good enough. But you need to understand the limits and issues in doing so.

In terms of this class: we’ll use 3 numbers to represent colors. Except when we are specifically studying how color works.

Why R, G, and B?

In graphics, we very often will represent a color as three numbers: the amount of red light, the amount of blue light, and the amount of green light. These three colors are the additive primaries: if you add lights of these colors together, you get lots of these colors. This is very different than the subtractive primaries (how different inks mix on paper to block out colors of light), or paint primaries (the colors of paints you mix together to make different colors).

The reasons for RGB actually have to do with the anatomy of the human eye, and the practical issues of building devices that work given the constraints of how the eye works. If we were making computer graphics (and display devices) for ducks or monkeys, we would need to have different primaries.

Most of the time in this class, we’ll use RGB (3 numbers) to represent colors, since it’s good enough most of the time – if only because it’s what our display devices use. When we talk about color, we’ll see why this is (and isn’t) a good choice, see some alternatives, and see some of the ways we deal with the problems of RGB.

Why 0 to 255 for each of RGB?

Really, for each of the color channels (R,G,B) we have a percentage of the maximum brightness. So, in you could use a floating point number (either between 0 and 1 or 0 and 100). In fact, this is probably a better idea than 0-255, and is most likely what is going on inside the graphics card.

Back in the old days, memory was expensive, and floating point computations took a long time. So we really liked to use single byte numbers for storing colors. The 0-255 was a binary fraction (divide by 255). Be careful that it really is divide by 255 (not 256) – otherwise you don’t get 100% brightness.

From the human perception side, it turns out that 8 bits of precision is about the right amount (if you use it correctly). When we study color, we’ll see why between 8-9 bits is all you need in terms of what people see. But we’ll also see why you probably want more precision for doing the computations (which is OK, because now computers can do floating point really fast).

What’s up with the 6 digit hex colors?

For web things (HTML, SVG, …) the common way to write a color is as a 6-digit hex string. 2 hex digits give you 0-255. So 6 hex digits give you a very compact way to write the three binary fractions to make an RGB color. Remember that the denominator is FF (255).

The web formats require that you put a hash mark “#” at the beginning of a hex string to denote that it is a hex string color.

So, “#FF0000” means the RGB triple (255,0,0), which means red.

There is a cheating thing where you give just a 3 digit hex number. In this case, its the same as repeating each digit. “#F00” is the same as “#FF0000” which we just explained.

]]>
Getting Started with HTML5 Canvas https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/getting-started-with-html5-canvas/ Fri, 28 Aug 2015 02:02:21 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=14

Why do I need to write my own Canvas tutorial for CS559?

There are some good tutorials out there (I have a few on a list, but that’s just a start). I recommend that you use them AFTER this one. Before you read this one, you might want to read my post on what Canvas is and why we use it.

The problem with those other tutorials is that they all assume that you know a certain set of stuff from prior tutorials. You should be able to figure this out yourself, but in case you need to be walked through it…

You should start with the explanation of what I mean by Canvas

Then we can start…

To draw, you need to answer three questions:

  1. Where do I draw?
  2. When do I draw?
  3. What do I draw?

But since you can’t do any without the other, we’ll look at them all together.

The simplest possible program

JS Bin on jsbin.com

Notice that this is an HTML file – you can load it into your web browser. I am using a spiffy thing to embed it on this web page so you can see the code and the output side by side. You can edit the code and see what the changes do. You might want to move the divider between the code and the output so the lines don’t wrap.

You should recognize some of the basic HTML stuff. This page is really minimal – it has no “<HEAD>" section (which is where I would set the title and other useful stuff). This is bad, since some of the stuff in the HEAD is important (like declaring the character set). In practice, you might not want to make your pages so minimal. I wanted to keep it simple here (so it fits on the screen). Later, I’ll show you a more realistic example.

In the body, you’ll see there are two tags.

The first is the canvas tag. This creates a blank rectangular space on the web page. The size is set by the width and height. I have given it a name (or "id") of "myCanvas" – this is important, since I will need to refer to it later.

The second thing in the body is a "script" tag – inside this script tag, I put my javascript code. Technically, I probably should have had the script tag say javascript – but the web browser will figure it out.

The script is simple. It finds the canvas (that I made above) by looking up its name. It then gets the drawing context from this canvas. The drawing context is the object that we use to actually do the drawing – it stores all the information about drawing state.

Aside… I could have done this differently. Rather than naming the canvas and searching for it, I could have searched for the first (or last) canvas on the web page – but this is bad practice, since it makes assumptions about the rest of the web page. In fact, I could have just assumed there wasn’t a canvas and added one to the end (or beginning) of the web page right in the JavaScript code. This is less desirable because it makes it hard to mix the canvas with other stuff on the page.

Aside… This code works and is simple, but in practice is way too simple. For example, there is no error checking. When writing a JavaScript program you need to worry about errors. Also sticking the program right in the html becomes unwieldy when the program is more than a few lines long.

Then, finally, I can actually do some drawing. Notice that I need to start a path before I can do anything. Then I add a rectangle to the path. Then I fill inside the path.

Besides the fact that the picture I drew is really boring (a black square), there are some over-simplifications in this example that you should understand before trying to draw more.

Where do I draw?

There are two parts to the where question.

The first part of the question is the space we’ll actually be drawing on. This is a canvas element on a web page. To be able to create this, you’ll need to know enough about web pages to make one that you can put a space on, and then actually put the canvas tag someplace.

Web pages usually give a lot more information about themselves, so that the browser doesn’t have to guess. It’s probably a good idea to do some of that.

You can put other web-page stuff around the canvas element – this is useful for making titles, or putting controls (like sliders), or even documentation.

Once you start drawing, you’ll need to understand the coordinate system of the canvas (so when you position things, you’ll know where things will go). For canvas, this is simple: by default, things are measured in pixels, the origin in the upper left corner, and the positive Y axis goes down.

When do I draw?

Or… where do I put my code?

If you notice, I placed my program code right in the web page within a script tag. This is OK for a tiny program like this, but you can imagine that quite quickly you’ll want to put stuff elsewhere to keep your code organized as it grows bigger.

There is another issue as to when this code actually gets executed. It would be nice to assume that everything works all linearly. The script tag gets processed after the canvas tag is done being processed, so the code inside the script tag only gets run once the canvas has been created and is ready to go. In practice, web browsers are more complicated than that. Especially since something can modify the canvas later on (for example, to relocate it to a different place on the page, or put a border around it). So, in a real program, you want to do something smarter about having your code run only when things are really ready.

I’ve written a separate tutorial about this. I recommend that you read it. Either right now, or after you finish this tutorial.

The real answer can be complicated, because it gets to questions of how to best organize your program.

But here’s a more realistic version of that same minimal program

HTML Test on jsbin.com

Here, I’ve turned off the output pane (you can turn it back on to see that the program draws the same back rectangle).

If you read the “When do I Draw” tutorial, this should make sense to you (since it’s one of the examples). If not, what’s happening is I am putting my code inside of a function that gets called when the window is done loading. But the important thing is that the drawing commands (begin path, …) happen at an appropriate time. This is a more realistic program for you to start with. I suggest that you take this and start tinkering with the stuff that actually does the drawing…

What do I Draw?

Now the fun part… we can draw stuff. Preferably something more fun than a black rectangle.

OK, here’s something that’s just a little bit better.

HTML Test on jsbin.com

Notice that drawing has a few parts (that I do over and over)…

  1. I start a path.
  2. I add shapes to the path, either as a whole shape (the rectangle) or by moving a “pen” around (the MoveTo and LineTo that draws the triangle). If the shape is closed, I make sure to close it.
  3. I decide how I want that shape to appear. You can see I set the fill color, the stroke color, and the width of the stroke. I could set other things (like making the lines dashed, or patterns to fill the shapes).
  4. Then I draw it (using the currently set style parameters). I can either fill it, or stroke it.

You’ll notice that I refer to colors in a funny way – as a string beginning with a # (hash mark) and a hexidecimal number following it. This is explained in another tutorial on color.

There are a bunch of different basic shapes (primitives) you can draw. Look at another tutorial to get a more complete list. There are a bunch of different style things you can do. Again, look at some other tutorial. But at this point, you can probably have enough of the basics so that you can start drawing stuff.

If you haven’t done it already, now might be a good time to go back to the “when do I draw” tutorial, so you can get some ideas on JavaScript code organization idioms.

There is a resource list for more Canvas info as part of the “Canvas: What and Why” tutorial.

]]>