Intro to Abstract Art with HTML5 Canvas & Javascript

I was showing my cousin how to do some fun things with canvas and realized that what we went over needs to be publically accessible. I’m going to try to keep this as non-programmer friendly as I can so follow along as far as you can go. Feel free to comment with questions.

 

What is an HTML5 Canvas?

HTML5 is a markup language, it’s nothing special on it’s own but can be very useful. A Canvas can be related to a real life canvas in the sense that you can use it for art projects, but that’s just the beginning.

Tools

For this example I’m going to use JSFiddle which is a tool I use often for quick prototypes in javascript. It’s a great tool for small, one-off projects like this. In the steps below I’ll leave JSFiddle links to document the steps I’ve made. I strongly recommend you rewrite ALL of the code, you’ll retain a lot more that way; it’s worth it I promise.

Getting Started

We will use HTML to tell the web browser that we want the user to see a canvas. At first the canvas will be blank so you’ll see nothing:

HTML

{syntaxhighlighter brush: xml;fontsize: 100; first-line: 1; }<canvas></canvas>{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/cjw6tn8h/

 

Introduce HTML and Javascript

Javascript needs to know how to find the <canvas> and while there are a number of ways to do this, let’s use an id. Keep in mind that id’s are element specific i.e. no two html elements should have the same id.

In javascript we are making two variables (buckets of memory to hold objects by a name you choose). One to hold a reference to the canvas element and another to hold a canvas context. The context (ctx) is what we care about, it’s what allows us to present drawings to the user. If this is confusing, good, that means you’re about to learn something new.

HTML

{syntaxhighlighter brush: xml;fontsize: 100; first-line: 1; }<canvas id=”my-canvas”></canvas>{/syntaxhighlighter}

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }var canvas = document.getElementById(“my-canvas”);
var ctx = canvas.getContext(“2d”); {/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/ayfwyy97/

Draw a Circle

The HTML isn’t going to change anymore so let’s focus on Javascript. First we’ll make our canvas the entire size of the window using some “special” javascript. Then let’s use the canvas’ context to start a new path and draw a circle using the arc method. The link I provided shows you how you can use the arc method and even gives you an example. Sites like Mozilla.org are great for examples as well as accurate information (w3cschools.com is nice for beginners but there are some misleading articles on there too).

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;

ctx.beginPath();
ctx.arc(50, 50, 20, 0, Math.PI*2);
ctx.closePath();
ctx.fill();{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/1gy0zerb/

Change the Color of the Circle

The color corresponds to the fillStyle of the context at the time of drawing.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }ctx.fillStyle = “red”;{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/22wsexva/

Make the Circle Move

For this we add a very specific loop, this gets tricky. We ask the browser if we can draw and if we can then it will call our specified “draw” function.

JSFiddle
https://jsfiddle.net/edcjdLqc/

My Circle is Stretching??

I left the code like this so you can see what happens when your context is not cleared before you draw again. I did this because you can use this to your advantage at many times. For this example, let’s clear the canvas’ context on every frame i.e. every time draw is called.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/r7drrnmh/

My Circle Abandonded me 🙁

Yep, because it’s never told to come back. This is a good place to use programming logic to create a simple boundary for our circle animation. We are going to use a simple if/else.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }var radius = 20;

var direction = 1;

x = x + direction;

if(x > ctx.canvas.width – radius) { // circle reached the end
direction = direction * -1; // flip the direction
}
if(x < radius) { // circle reached the beginning
direction = direction * -1;
} {/syntaxhighlighter}

 

JSFiddle
https://jsfiddle.net/aprkaoqf/

Make it faster!

I know, it was fun the first time but now it feels like it’s so slow. Let’s add a speed control.

Javacript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }var speed = 10;

x = x + direction * speed;{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/7xx25z5z/

Make it funky

Let’s get weird. Let’s make it oscillate. To do this we’re going to add a frame count which goes up by 1 every time we draw and we’ll use that with the Math.sin function to make the y property go wild.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }var frame = 0;

frame = frame + 1;

y = 50 + Math.sin(frame) * 20;{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/nn8fk7d0/

Slow Down the Oscillation

This is an easy one. We only have have to soft the value going into Math.sin. Let’s cut it in half with division.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }y = 50 + Math.sin(frame / 2) * 20; // base + oscilation * oscilation radius{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/gzhz0y3q/

Math.sin is Cool

Let’s add an oscillation to the x value too and see what happens.

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }x = x + direction * speed + Math.sin(frame / 2) * 20;{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/asdn6qda/

Now the radius

Let’s fluctuate the size of the sphere too!

Javascript

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }radius = 20 + Math.sin(frame / 2) * 10;{/syntaxhighlighter}

JSFiddle
https://jsfiddle.net/hpcuoejg/

 

Let’s Make it Weird Again

We’re dividing all the sin inputs by 2. Change it up! Use different values in different places and see what happens. In fact, change any number and see if it still works. If it breaks, just undo. Worst case you can start over using the JSFiddle links I’ve provided.

JSFiddle
https://jsfiddle.net/q6m3u57j/

It’s Not Over Yet

Just as things are getting good, let’s shake up the math method. Instead of Math.sin, try Math.cos in some spots. even more bizarre is Math.tan. Try it everywhere! Note: it will definitely stop working at some point.

JSFiddle
https://jsfiddle.net/tkut8g3u/

Notes

Using beginPath and closePath help a LOT on performance. If your animation is running slow, make sure you’re closing all your paths.

If you’re getting unexplainable shapes of “weird” resisdue, make sure your paths are closing correctly, make sure you’re using clearRect (if it’s desired) and you may be needing to use ctx.moveTo which I haven’t convered here.

I cruised through this article so it’s not “perfect” but it will give you a good idea of what’s going on. I’ve been working with this style coding for years and can tell you, in depth, everything that is going on. I learned it by playing with all the variables of every tutorial I came across. It’s a great way to learn (for free). I strongly recommend looking at the Canvas API Reference and testing out every possibile method / example.

Extra

If you’re interested in this style of programming, I’m going to leave you with this to chew on: Using the drawing concept I’ve covered, here is an example using Object Oriented Programming. I’ve also refractored the code and added a number of other features.

JSFiddle
https://jsfiddle.net/jp835n3g/

Leave a comment

Your email address will not be published. Required fields are marked *