# JavaScript/Exercises/IntroGraphic

We offer a lot of examples. The structure of the source code, in general, follows a particular pattern: global definitions / start function / render function / program logic (playTheGame + event handler). We believe that this separation offers an easy understanding of the code, especially the distinction between logic and rendering. But this architecture is just a suggestion; others may also, or even better, suit your needs.

## Canvas

To develop apps that contain graphical elements, you need to include an area into your HTML where you can 'paint'. HTML elements like button, div, or others contain primarily text, colors, or a (static) image or video.
The HTML element canvas is designed to fulfill this purpose. It is like a board where dots, lines, circles, ... can be drawn.
During this introduction, the HTML part is mainly identical to the above one. Sometimes there are some more buttons or explanations. To beautify the page, you may want to add some more CSS definitions.

## Draw into a canvas

The main work is done in JavaScript. The first example draws two rectangles, a 'path' (a line), and a text.
Exercise: Draw a line like the uppercase character "M" and surround it with a rectangle.

## Work in an object-oriented way

Please work in a structured, object-oriented way and use the classical prototype or the class syntax to define often-used objects. In our examples, we use the prototype syntax for Rect (rectangle) and the class syntax for Circle to give you examples for both. It's a good idea to create separate JS-files for each such object resp. class to separate them from other JS-files, which shall handle other aspects of the games.
We define Rect and Circle with some attributes and functions:

## Introduction to movements

The above example creates a single graphic without any change or movement of its objects. Such graphics must be painted only once. But if any object changes its position, the graphic must be re-painted. This can be done in different ways.
* Single movement: Re-painting initiated by an event
* Continous movement: Call to function windows.requestAnimationFrame
* Continous movement: Call to function windows.setIntervall
Case 1: If - after an event - the new position of an object will not change anymore (its 'speed' is 0), the event can initiate the re-painting directly. Nothing else is necessary.
The situation changes significantly if it is intended that some objects shall move across the screen constantly without further user interaction. That means that they have their own 'speed'. To realize this automatic movement, the re-painting must be done in one way or another by the system. The two functions requestAnimationFrame and setIntervall are designed to handle this part.
Case 2: requestAnimationFrame( => func) initiates a single rendering as far as possible. It accepts one parameter, which is the function that should render the complete graphic. It is necessary that the execution of the called function func leads again to the call of requestAnimationFrame( => func) as long as the animation shall go on.
Case 3: setIntervall(func, 25) calls in a loop a function (its first parameter) repeatedly after certain milliseconds (its second parameter). The called function shall render the graphic by first deleting all old content and then re-painting everything - in the same way as requestAnimationFrame. Nowadays, requestAnimationFrame is preferred over setIntervall because its timing is more accurate, results are better (e.g., no flickering, smoother movements), and it shows better performance.

## Single movements (jumping)
### Step-by-step with fixed width

A figure can be moved across the canvas by clicking on 'left', 'right', 'up', 'down' buttons - or by pressing the arrow keys. Each click creates an event, the event handler is called, he changes the position of the figure by a fixed value, and lastly, the complete scene gets re-drawn. Re-drawing consists of two steps. First, the complete canvas is cleared. Second, all objects of the scene are drawn, regardless of whether they have changed their position or not.

### Jump to a particular position

The following example adds an event handler canvasClicked to the canvas. Among others, the event contains the mouse position.
If you want to move an object to the position to which the mouse is pointing, it's necessary to know where the click-event has occurred. You have access to this information by evaluating the details of the parameter 'event' of the event handler. The event.offsetX/Y properties show those coordinates. They are used in combination with the additional jumpTo method of circle to move the circle.

### Summary

Such applications show a common code structure.
* Classes and prototype functions are declared inclusive of their methods.
* Variables are declared.
* A 'start' or 'init' function creates all necessary objects. As its last step, it calls the function that renders the complete scene.
* The rendering function clears the complete scene and draws all visual objects (again).
* Event handlers that react on buttons or other events change the position of visual objects. They do not render them. As their last step, they call the function that renders the complete scene.
    The event handlers implement some kind of 'business logic'. Therefore they differ significantly from program to program. The other parts have a more standardized and static behavior.

## Continous movements

Working with continuously moving objects is similar to the above-shown stepwise movements. The distinction is that after the user action, the object does not only move to a different position. Instead, the movement goes on. The object now has a 'speed'. The realization of the speed must be done in one way or another by the software. The two functions requestAnimationFrame and setIntervall are designed to handle this part.
Since requestAnimationFrame is widely available in browsers, it is favored over the traditional setIntervall. Its timing is more accurate, results are better (e.g., no flickering, smoother movements), and it shows better performance.

### requestAnimationFrame

In the following program, a smiley is moved across the screen at a constant speed. The program's overall structure is similar to the above-shown solutions. Once initiated, the movement keeps going on without further user interaction.
* Classes and prototype functions are declared inclusive of their methods.
* Variables are declared.
* A 'start' or 'init' function creates all necessary objects. As its last step, it calls the function that renders the complete scene.
* The rendering function - renderAll in our case - clears the complete scene and (re)renders all visual objects.
* At the end of the rendering function, the crucial distinction to the above programs is implemented: it calls requestAnimationFrame( => func). That initiates a single transfer of the rendered objects from RAM to the physical screen as far as possible.
    And it accepts one parameter, which is the function that executes the game's logic (in combination with events), playTheGame in our case. It is necessary that the execution of the called function again leads to the call of requestAnimationFrame( => func) as long as the animation shall go on.
* Event handlers that react on buttons or other events change the position or speed of visual objects. They do not render them. Also, it's not necessary that they call the function that is responsible for the rendering; the rendering is always going on due to the previous two steps.
* One of those events is stopEvent. It sets a boolean variable that indicates that the game shall stop. This variable is evaluated in renderAll. If it is set to true, the system function cancelAnimationFrame is called instead of requestAnimationFrame to terminate the loop of animations - and the smiley's movement.

### setIntervall

The next program implement the same smiley movement. It uses the traditional setInterval function instead of requestAnimationFrame. The source code of the two solutions differs only slightly.
* At the end of the start function there is a call to setInterval with two parameters. The program's logic, implemented in playTheGame, is given as the first parameter. The second parameter is the time in milliseconds after that this function is called again and again.
* Within the rest of the program setInterval is not invoked again - in opposite to the above requestAnimationFrame. It has initiated its (infinite) looping and doesn't need any further attendance.
* Similar to the above requestAnimationFrame, a clearInterval is called to terminate the looping.

## See also

* MDN: Rendering in a canvas
* MDN: requestAnimationFrame
* MDN: setInterval