The JavaScript Language Introduction JavaScript is typically used as a client side scripting language. That is how we will be using it in this work however it is becoming more common at the server side. Although it has the name Java in the title it is not related to Java (although there are some similarities as with all C flavoured languages.) In this work will be covering JavaScript as an animation tool in HTML 5. Remember thought that this will give you a useful jumping off point to other languages such as JQuery. Like all C flavoured languages there are a few things to remember. Case Sensitivity Semi Colons Data Types Unlike C# JavaScript does not require you to specify data types. The data type of a variable is controlled by what data is assigned. For example… var colour = "red", cost = 2.55, quantity = 3; The above code declares three variables, colour, cost and quantity. By assigning the values “red”, 2.55 and 3 the language sets the data types to string, decimal and integer. What is interesting is that we my change data type mid execution like so… quantity = "fourteen"; This has the advantage of making writing code a bit less fussy but the disadvantage that there are fewer controls over what data you may assign where. Comments Comments are as in C# using the double slash //this is a comment Block comments may be handled like so /* this is a block comment that may go on and on for many many lines*/ Variables //this declares three variables called colour, cost and quantity var colour = "red", cost = 2.55, quantity = 3; Variables in JavaScript are declared using the var keyword. In the above example we are declaring three variables separated by commas and terminated by a semi colon. Or alternatively we my use three var keywords like so… //this declares three variables called colour, cost and quantity var colour = "red"; var cost = 2.55; var quantity = 3; Don’t forget that the language is case sensitive! Functions As with C# JavaScript supports the creation of functions using the function keyword… /*creates a new function called MyFunction with no parameters and no return value*/ function MyFunction() { //code for function goes here } Parameters and Return Values Notice the function as no parameters or return value. To add parameters we simply add them in the parenthesis like so… /*creates a new function called MyFunction with two parameters and no return value*/ function MyFunction(FirstParameter, SecondParameter) { //code for function goes here } Which is all well and good if we want a void function but what if we want some data returned back from the function? The following code adds a return value to the function… /*creates a new function called MyFunction with two parameters and returns the sum of the two parameters*/ function MyFunction(FirstParameter, SecondParameter) { //code for function goes here //variable to store the result var newvalue = 0; //add the two parameters together newvalue = FirstParameter + SecondParameter; //return the answer return newvalue; } To call the function we might do the following… //call MyFunction and get the sum of 2 + 2 var result = MyFunction(2, 2); This code would assign the variable “result” with the value of 4. Selection JavaScript supports pretty much identical selection structures to C#. //if the result is 4 if (result == 4) { //do this } JavaScript also includes else… //if the result is 4 if (result == 4) { //do this } else { //do this } And else if… //if the result is 4 if (result == 4) { //do this } else if (result = 7) { //do this } else { //do this } Repetition While loops are also pretty much identical to C# Take a look at the following section of code function DrawWindows(context) { //var for the offset of the window to be drawn var XOffset = -20, //var for loop counter to indicate which window we are drawing WindowNo = 1, //var to store the colour to use Colour = ""; //loop through each window while (WindowNo != 6) { //if the red window is being drawn then set the colour to red if (WindowNo == RedWindow) { //set colour to red Colour = "#ff0000"; } else { //set colour to white Colour = "#ffffff"; } //draw the window Window(context, XOffset, -12, Colour); //point at the next window WindowNo++; //work out the position of the next window XOffset = XOffset + 10; } //chage the red window to the next one RedWindow = RedWindow + .25; //if the red window is 6 that’s too many if (RedWindow == 6) { //set it back to 1 RedWindow = 1; } } This code is used to draw the windows on the flying saucer sprite that we will be creating in the labs… The variable RedWindow is gradually increased by .25 each time the function is called. Within the loop each window is numbered 1 – 5. If the integer value of RedWindow is equal to the number of the window being drawn it is drawn in red. If the integer value of RedWindow is not equal to the number of the window being drawn it is drawn in white. The result of this function is that the windows flash in sequence. Object Orientation JavaScript supports full object orientation Encapsulation Inheritance Polymorphism Classes Classes in JavaScript (as with other languages) are text files that contain the code for the class organised into functions that make the methods and properties for objects we create. In this example we have organised the classes into two types. Classes – containing code that does something Sprites – also containing code but they also have some graphical component For example the square sprite looks like this in the animation… The code in the class file that generates it is as follows… //create the constructor for the class square function Square() { //initialisation code will go here //create private variables for the x and y coordinates var x = 0, y = 0 //create a public property called X (note caps!) Object.defineProperty(this, 'X', { //getter get: function () { //return the value of x (lower case) return x; }, //setter set: function (value) { //ste the value of x (lower case) x = value; } } ) //create the draw function to give us the draw method //it accepts one parameter which is the context from the canvas it is drawn on Square.prototype.draw = function (context) { //start the line (path) context.beginPath(); //set the start coordinates context.moveTo(x, y); //draw the top line context.lineTo(x + 29, y); //draw the right side context.lineTo(x + 29, y + 29); //draw the bottom line context.lineTo(x, y + 29); //close the path context.closePath(); //fill the shape context.fill(); //go ahead and draw the line context.stroke(); } //create the public move method by adding it to the classes prototype Square.prototype.move = function () { //change the value of the x axis for the shape x++; } } To create a new instance of an object based on this class we need to do two things. 1. We need to tell the HTML 5 page that the class file exists like so… 2. We then need to create an object based on the class… //create a reference to the canvas var canvas = document.getElementById('canvas'), //access the 2D drawing API context = canvas.getContext('2d'), //new instance of the Square class square = new Square(); The Constructor The constructor is an important function which is used to initialise objects when we create instances based on the class. The constructor is named like so… All public and private functions and data members need to be created in the opening and closing brackets of the constructor… //create the constructor for the class square function Square() { //initialisation code will go here } Notice how when we created the object we matched the name of the Class with the name of the constructor – not the name of the file. The constructor is named like so… We created our object like so… //new instance of the Square class var square = new Square(); The presence of the “new” keyword results in the constructor being called. Omit the “new” keyword out and you will end up with a null instance of an object i.e. not initialised. Private Data Members In the above example we create private data members by declaring variables within the constructor… //create the constructor for the class square function Square() { //initialisation code will go here //create private variables for the x and y coordinates var x = 0, y = 0 When we create objects based on this class these variables will not be available i.e. private. Public Properties Creating public properties requires creation of a getter and setter for the property. The following code creates a public property called X (Note upper case) with both getter and setter… //create a public property called X (note caps!) Object.defineProperty(this, 'X', { //getter get: function () { //return the value of x (lower case) return x; }, //setter set: function (value) { //ste the value of x (lower case) x = value; } } ) Public Functions Any functions created in a class using the function keyword will be private to that class… /*creates a new function called MyFunction with two parameters and returns the sum of the two parameters*/ function MyFunction(FirstParameter, SecondParameter) { //code for function goes here //variable to store the result var newvalue = 0; //add the two parameters together newvalue = FirstParameter + SecondParameter; //return the answer return newvalue; } To create a public function in JavaScript we need to attach it to the class’s prototype. //create the draw function to give us the draw method //it accepts one parameter which is the context from the canvas it is drawn on Square.prototype.draw = function (context) { //start the line (path) context.beginPath(); //set the start coordinates context.moveTo(x, y); //draw the top line context.lineTo(x + 29, y); //draw the right side context.lineTo(x + 29, y + 29); //draw the bottom line context.lineTo(x, y + 29); //close the path context.closePath(); //fill the shape context.fill(); //go ahead and draw the line context.stroke(); } The prototype may be seen as the underlying definition of all objects created in JavaScript. In this example Square.prototype.draw = function (context) We are adding a new function to the prototype of Square called draw which accepts one parameter called “context”. Rules of Scope The rules of scope in JavaScript are different to those in C#. Look at the following code... Here we have declared a number of private variables notably vx. We have also created a public property with both getter and setter. Because these two items have been declared within the constructor they both share the same scope. It is possible in JavaScript to declare variables and functions in a way that C# will not allow. The following code illustrates some of the rules of scope The Canvas and Context Objects All drawing in JavaScript is performed on the HTML 5 canvas. <canvas id="canvas" width="400" height="400"></canvas> The canvas mark-up in the HTML 5 is not automatically available to the code that we write. To access the canvas in our code we need to attach an object called the context. This object allows us to draw on the canvas. To get at the HTML 5 canvas we create an object based on it and then associate a context with the canvas like so... <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> <link rel="stylesheet" href="StyleSheet.css" /> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script> //this function will always be executed when the page loads window.onload = function () { //our code here var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'); } </script> </body> </html> Canvas is linked to the HTML 5 tags via document.getElementById('canvas') getElementByID tells the code to link to a section of HTML 5 we want to do something with i.e…. ('canvas') Which is the ID of the section of HTML 5 specified when we created that mark-up <canvas id="canvas" width="400" height="400"></canvas> This canvas object allows us access to the HTML 5 canvas area. Problem – the canvas has no drawing facilities built into it. Before we may do any drawing we need access to the context. The context may be 2D or 3D. The context gives us access to the full set of drawing tools (API – Applications Programmers Interface) In this case we need access to the 2D drawing context… context = canvas.getContext('2d') Having gained access to the context via the variable “context” we now have access to the 2D drawing API. Auto Executing Functions JavaScript includes a feature called auto executing anonymous functions. We may turn the drawFrame function into an auto executing function by enclosing it in brackets like so… (function drawFrame() { //clear the canvas for the new frame context.clearRect(0, 0, canvas.width, canvas.height); //draw the sprite square.draw(context); //move the square to the right square.move(); //get the next animation frame window.requestAnimationFrame(drawFrame); })(); (Notice the little rash of brackets at the end and get the numbers of brackets right!) Multimedia APIs There is a lot more to the JavaScript language than will ever be covered in this module. There are two APIs available for 2D and 3D animation. It is worth doing some extra reading to see what other facilities are available. Editors and Debugging For this work you will be using Visual Studio and Internet explorer simply because the debugger works so well. You will need to consider how other browsers handle debugging and editing. Researching this question will make up part of your final assignment for this work.