Before you go, check out these stories!

0
Hackernoon logoCreative coding basics - Polygons, translation and rotation by@radarboy3000

Creative coding basics - Polygons, translation and rotation

Author profile picture

@radarboy3000George Gally

Building a retro screensaver effect in Javascript

The end game here is to use our original particle code to create a 90s screensaver effect…

If you new to the series start here: Part1, Part 2, Part 3 and Part 4.

All the code and libraries for these tutorials can be found here: https://github.com/GeorgeGally/creative_coding

Hello creative coders. Firstly, I want to show you how to draw a new type shape — a polygon, and eventually build us a 90s screensaver effect.

We can just draw any polygon shape simple using my creative_coding.js functions: fillPolygon() and strokePolygon():

ctx.fillPolygon(x, y, number_of_sides, size);
ctx.strokePolygon(x, y, number_of_sides, size);

Though you don’t really need to know how the functions works behind the scenes, in case you’re interested, we build a polygon by using sin and cos to calculate its points:

ctx.polygon = function (_x, _y, sides, size){
this.beginPath();
this.moveTo (_x + size * Math.cos(0), _y + size * Math.sin(0));
for (var i = 1; i <= sides; i += 1) {
this.lineTo (_x + size * Math.cos(i * 2 * Math.PI / sides),
_y + size * Math.sin(i * 2 * Math.PI / sides));
}
}

I’ll be covering Math.sin and Math.cos, the creative coders best friends, in a later tutorial.

So using our old particles code, our original drawBall() function will now look like this (I’m using a solid polygon, then a stroked polygon, to get the outlined effect:

function drawBall(){
for (var i = 0; i < balls.length; i++) {
var b = balls[i];
ctx.fillStyle = b.colour;
ctx.fillPolygon(b.x, b.y, 8, b.size);
ctx.strokeStyle = rgba(255, 0.6);
ctx.strokePolygon(b.x, b.y, 8, b.size);
}
}
Polygon particles

Drawing a polygon, then having to draw another one seems like repetition though. And I’ve just realised I’ve been breaking my own rule of 3 (do something three times, must make a function), so here we go:

this.outlinedPolygon = function (_x, _y, _sides, _size, _fill, _stroke){
this.fillStyle = _fill;
this.fillPolygon(_x, _y, _sides, _size);
this.strokeStyle = _stroke;
this.strokePolygon(x, y, _sides, _size);
}

So now our drawBall() function can be simplified:

function drawBall(){
for (var i = 0; i < balls.length; i++) {
var b = balls[i];
ctx.outlinedPolygon(b.x, b.y, 8, b.size, "black", "white");
}
}

(Maybe outlinedPolygon is a lame name, actually probably, but it doesn’t matter, if it doesn’t stick, I’ll change it later, one of the many advantages of building your own library).

Next up, let’s tweak the code with a subtle change which will make everything look way way better, by slightly rotating the polygons as they move.

But to do that I need to introduce you to translation, which might seem more complicated than they actually are…

  • Firstly to rotate an object, we actually rotate the whole canvas/page and then move it back to it’s original state after. We do this by saving the screen’s current state first with: ctx.save(); and then restoring to original state with ctx.restore();
  • After we’ve saved the canvas state, we want to rotate our object. However, things by default rotate from the centre of the screen, and we want to rotate each individual object. So we need to set the centre point to be that of the object, we do this by using ctx.translate(x, y);
  • We can then rotate our object using ctx.rotate(radians); Radians, hmmm, yes. Don’t love ‘em. They’ve always seemed more hassle than they worth, so I use my own function ctx.rotateDegrees(degrees), which for me seems more human friendly.
  • Draw your object at 0, 0 — because we’ve shifted the whole canvas to our object’s x and y points.
  • Once we’ve rotated our object, as mentioned above, we need to restore the screen to it’s original state, with ctx.restore();

Seems a bit complicated. But it’s not, and it always works the same. Save. Translate. Rotate. Restore. Like so:

// save the current state of the canvas
ctx.save();
// move the centrepoint to that of your object you want to rotate
ctx.translate(b.x, b.y);
// rotate your object with ctx.rotate() or ctx.rotateDegrees()
ctx.rotateDegrees(radians);
...draw your shapes
// restore to the original state of the canvas
ctx.restore();

So our whole drawBall() function would now look like this:

function drawBall(){
for (var i = 0; i < balls.length; i++) {
var b = balls[i];
ctx.fillStyle = b.colour;
ctx.save();
ctx.translate(b.x, b.y);
ctx.rotate(b.rotation);
ctx.outlinedPolygon(0, 0, 8, b.size, "black", "white");
ctx.restore();
}
}

(We need to remember that if we’ve moved the canvas with ctx.translate() to the centrepoint of our object, we must now draw our object for 0, 0.)

The only other major things we need to do is add a rotation property to each particle, so we can track each of their own individual rotations. We then increment this rotation varaible in the moveBall() function, so our entire code would look like this:

var ctx = createCanvas("canvas1");
var number_of_balls = 4;
var balls = [];
ctx.lineWidth = 1;
// push a ball and it's values into the array
for (var i = 0; i < number_of_balls; i++) {
addBall();
}
function addBall(){
var ball = {
x: random(w),
y: random(h),
speed_x: random(3,5),
speed_y: random(3,5),
size: 70,
colour: rgb(255),
rotation: random(1)
}
balls.push(ball);
}
function draw(){
//ctx.background(255, 0.2);
moveBall();
drawBall();
}
function moveBall(){
  for (var i = 0; i < balls.length; i++) {
var b = balls[i];
b.x += b.speed_x;
b.y += b.speed_y;
b.rotation += 2;
if (bounce(b.x, 0, w, b.size)) {
b.speed_x *=-1;
}
   if (bounce(b.y, 0 ,h, b.size)) {
b.speed_y *=-1;
}
  }
}

function drawBall(){
for (var i = 0; i < balls.length; i++) {
var b = balls[i];
ctx.save();
ctx.translate(b.x, b.y);
ctx.rotateDegrees(b.rotation);
ctx.outlinedPolygon(0, 0, 8, b.size, "black", "white");
ctx.restore();
}
}

And now we have our polygon screensaver:

Polygons!

Well that’s it. There’s tonnes of stuff you can do will this kind of code. Hppy coding…

Follow me on Instagram here:https://www.instagram.com/radarboy3000/

Follow me on Twitter here: https://twitter.com/radarboy_japan

And like my Facebook Page here:https://www.facebook.com/radarboy3000

Here are my previous creative coding tutorials:

Introduction to Creative Coding Part 1: https://medium.com/@radarboy3000/creative-coding-basics-4d623af1c647#.hn9zzliob

Introduction to Creative Coding Part 2: https://medium.com/@radarboy3000/introduction-to-creative-coding-part-2-d869832d9ffb#.fzxcom541

Introduction to Creative Coding Part 3: https://medium.com/@radarboy3000/how-to-make-particles-1cbeee937593#.wwjhkv7u2

Introduction to Creative Coding Part 4: https://medium.com/@radarboy3000/playing-with-particles-ef87744d7ed2#.5r081j34l

Github repository of all the code: https://github.com/GeorgeGally/creative_coding

Tags

The Noonification banner

Subscribe to get your daily round-up of top tech stories!