Making Objects
Stick Building Objects An object is just a chunk of memory storing stuff. In JavaScripts, objects can store state and methods. One approach to making object is to "stick build" them.
Here is an empty object. It knows nothing, and it does nothing.
> mt = {}
Object { }
We can attach state (this is what an object KNOWS) like so.
> mt.x = 3
3
> mt.y = 4;
4
> mt
Object { x: 3, y: 4 }
Let us now attach a method. Methods can depend upon the state
of the object they are attached to. Here we attached a method
that tells us x + y
.
> mt.foo = function(){return this.x + this.y};
function foo()
> mt
Object { x: 3, y: 4, foo: foo() }
> mt.foo()
7
Here we attach another method.
> mt.goo = function(){this.x*this.y}
function goo()
> mt.goo()
undefined
> mt.goo = function(){return this.x*this.y}
function goo()
> mt.goo()
12
A Ball Object
When we click in a canvas, we can record each ball we create in an object. We can then put these objects into an array. This way, if the background repaints, we can repaint all of the balls on top of it.
We can even make the ball smart and teach it how to paint itself!
Classes
What if I make an object a lot? Do I have to stick-build every time? No. You can create a blueprint for making object called a class. You can then use the class to stamp out objects.
Our Ball class needs to know
- x: the x-coördinate of the center of the ball
- y: the y-coördinate of the center of the ball
- radius: the radius of the ball
- color: the color of the ball.
These are the four pieces of stated we need. Here is the class we created.
class Ball
{
constructor(x, y, radius, color)
{
//in this class I am a ball and my name is "this."
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
}
Inside of the class, we have a special method called a constructor. One of its principal duties is to initialize all state. As with any function, you can treat the items in the argument list as being defined quantities.
When you program inside of a class you are the object,
and your name is this
. Latin scholars, the construct
of this.
is the genetive case. The genetive case of the
first person is "my".
To this.x = x
translates to, "my x is the x argument."
Now inspect it in the console. Here we use it to stamp out some Balls.
Logically enough, we make new Balls by calling new Ball(....)
.
Where the Rubber Meets the Road
Let us now make this class even smarter. We will teach a ball how to draw itself. Let's go back to the our three basic files.
<!doctype html>
<!--Author: Morrison-->
<html lang="en">
<head>
<title>ballWorld</title>
<meta charset="utf-8"/>
<link rel="stylesheet" href="ballWorld.css"/>
<script src="ballWorld.js">
</script>
</head>
<body>
<h2>Canvas Template</h2>
<canvas width="800" height="500" id="surface">
<p>Get a modern browser, chumley!</p>
</canvas>
<p class="display"><button id="makePink">Pink!</button></p>
</body>
</html>
/*Author: Morrison*/
h1, h2, .display
{
text-align:center;
}
canvas
{
border:solid 1px black;
display:block;
margin-left:auto;
margin-right:auto;
}
/*Author: Morrison*/
window.addEventListener("load", main);
function main()
{
let surface = document.getElementById("surface");
let makePink = document.getElementById("makePink");
let pen = surface.getContext("2d");
surface.addEventListener("click", function(e)
{
drawBall(e.offsetX, e.offsetY, 50, pen);
});
makePink.addEventListener("click", function()
{
pen.fillStyle = "pink";
pen.fillRect(0, 0, surface.width, surface.height);
repaint();
});
}
function drawBall(x, y, radius, pen)
{
pen.beginPath();
pen.arc(x, y, radius, 0, 2*Math.PI);
pen.fill();
}
As soon as we hit the "pink" button, all of the balls we created were painted over and lost. Somehow, we need to keep track of them so we can paint them again when the pink button gets clicked. Als notice that the only color we have for balls is Henry Ford Black.
We want them to come in a whole array of colors. Let us now modify our code to make this happen. Here is the general idea
- Create an array in which to store the balls. Ours will be
named
balls
. - Each time the canvas is clicked, we save a Ball object representing the ball that is put on the canvas, and we push it onto the array.
- Write a method that repaints all of the balls in the array.
- Call that function whever the backgrouund color is changed.
The first step is easy. While we are here, let's add our class to the file.
class Ball { constructor(x, y, radius, color) { //in this class I am a ball and my name is "this." this.x = x; this.y = y; this.radius = radius; this.color = color; } } function main() { let surface = document.getElementById("surface"); let makePink = document.getElementById("makePink"); let pen = surface.getContext("2d"); let balls = []; //create the new array. surface.addEventListener("click", function(e) { drawBall(e.offsetX, e.offsetY, 50, pen); }); makePink.addEventListener("click", function() { pen.fillStyle = "pink"; pen.fillRect(0, 0, surface.width, surface.height); repaint(); }); } function drawBall(x, y, radius, pen) { pen.beginPath(); pen.arc(x, y, radius, 0, 2*Math.PI); pen.fill(); }
All done in one line of code.
The next thing we do is to modify the event listener for the canvas. We will add a new variable with an eye to the future. Eventually the user will be able to change the ball color. This variable will store the value chose by the user for the color of the next ball he creates.
let currentBallColor = "black";
surface.addEventListener("click", function(e)
{
b = new Ball(e.offsetX, e.offsetY, 50, currentBallColor);
balls.push(b);
drawBall(x, y, 50, pen);
});
Notice that this goes inside of main
so it has
access to the array balls
.
Let us now teach our class how to draw a ball.
- Set the pen to the ball's color
- Call drawBall to do the drawing.
class Ball
{
constructor(x, y, radius, color)
{
//in this class I am a ball and my name is "this."
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
draw(pen)
{
pen.fillStyle = this.color;
drawBall(this.x, this.y, this.radius, pen);
}
}
Now we can again modify our canvas's event listener to use this new capability.
surface.addEventListener("click", function(e)
{
b = new Ball(e.offsetX, e.offsetY, 50, currentBallColor);
balls.push(b);
b.draw(pen);
console.log(balls);
});
Exercise Open the HTML file and open the console.
Click in the canvas and see the ball appear. Then look in the console and
see the ball in the array. Do this several times, and watch the array
expand. Then get rid of the console.log
line.
Repainting