Rotate towards mouse
For this sketch, we applied what we've learned in the previous exercises such as transformations and colour to create a pattern. The pattern consists of circles that rotate towards the current mouse position.Setting Up the Canvas
The following are global variables needed to define the initial properties of the canvas and the circles that will be drawn later.
let shapes = [];
let canvasSize = 500;
let numOfShapes = 20;
let shapeSize = canvasSize/numOfShapes;
let col, d;
The empty shapes
array is where the circles created from the Shape
class will be added.
canvasSize
refers to the width and height of the canvas and numOfShapes
is the number
of circles drawn in each row and column on the canvas. shapeSize
is the width and height of the circle.
col
is the colour of each circle and d
stands for distance. These variables will be used in
the Shape
class.
function setup() {
createCanvas(canvasSize, canvasSize);
ellipseMode(CENTER);
colorMode(RGB, numOfShapes, numOfShapes, numOfShapes);
}
As shown in the code above, the color mode is set to RGB and the range for the red, green, and blue are all set to the number of shapes on the canvas. This is for generating an interesting colour palette.
The Shape class
The circle objects that are drawn on the canvas are created from a class called Shape
. A circle object has the following
properties.
class Shape {
constructor(_i, _j) {
this.i = _i;
this.j = _j;
this.s = shapeSize;
this.x = this.i * this.s + this.s/2;
this.y = this.j * this.s + this.s/2;
this.angle = 0;
}
}
this.i
and this.j
are index numbers. this.s
is initialised to
the value assigned to the global variable shapeSize
. this.x
and this.y
are offset properties that make sure the circles will be drawn within the canvas. this.angle
is initialised to 0 but this value changes when the circles rotate towards the mouse.
Before drawing the circles on the canvas, I first populated the shapes
array
in setup()
.
for (let i = 0; i < numOfShapes; i++) {
for (let j = 0; j < numOfShapes; j++) {
shapes.push(new Shape(i, j));
}
}
Drawing the Circles
I have a method called render()
in the Shape
class which draws a circle object on the canvas when called.
Each circle has its own origin point which are the values assigned to the properties this.x
and this.y
.
The colour of the outline of each circle depends on its position on the canvas.
render() {
push();
translate(this.x, this.y);
col = color(this.i, 0, numOfShapes - this.j);
noFill();
stroke(col);
ellipse(0, 0, this.s, this.s);
pop();
}
Next, the render()
method is called on each circle object in the draw()
function. The result
is 400 circles drawn on the canvas, each has no fill colour and has a different outline or stroke colour.
function draw() {
background(0);
shapes.forEach(shape => {
shape.render();
});
}
Rotating Each Circle Towards Mouse Position
The method updateAngle()
changes the inital angle of a circle object. It has the parameters
_mx
and _my
. These parameters refer to the mouseX
and mouseY
variables that return
the current mouse position on the screen. atan2()
calculates the angle in radians from each circle to the mouse position.
The updateAngle()
method is added just before the render()
method in the Shape
class.
updateAngle(_mx, _my) {
let dx = _mx - this.x;
let dy = _my - this.y;
this.angle = atan2(dy, dx);
}
The code below rotates a circle by the current angle value. It is included in the render()
method after
the translation.
rotate(this.angle);
Then the updateAngle()
method is called on each circle object in the draw()
function.
shapes.forEach(shape => {
shape.updateAngle(mouseX, mouseY);
shape.render();
});
Smaller circles are drawn on the canvas to make the rotation more obvious. The following lines of code are added
in the render()
method before pop()
.
fill(255);
noStroke();
ellipse(this.s/4, 0, this.s/2, this.s/2);
Changing the Size of Each Circle
To better the interactivity of the sketch, the size of each circle also changes according to the current mouse position.
d = dist(mouseX, mouseY, this.x, this.y);
this.s = map(d, 0, width, 10, shapeSize);
The dist()
function calculates the distance between the mouse position and the circle position. The result
is scaled from a range between 0 and the width
to a range between 10 and the value assigned to the shapeSize
variable.