The Nature of Motion on the Canvas, Step 2

Example F.9. animatef.html

The motion comes from the motor. We use a JavaScript built in timer, and do the same in each repetition. Every so many milliseconds.

We define what must be done within the timer. We use a language phenomenon called closure. It means that the functions knows what variables it works on at the time of running, not at the time of coding.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>Canvas, Motion, Step 2</title>
        <style>
            #canvas { border: 2px solid blue; }
        </style>
        <script src='nQuery.js'></script>   <!-- access to framework -->
        <script>
            'use strict';
            let Canvas = {
                init(canvasId, color) {             // note new syntax
                    this.canvas = $(canvasId);
                    this.context = this.canvas.getContext("2d");
                    this.color = color;
                    this.context.fillStyle = color;
                    this.context.fillRect(0, 0, this.canvas.width, 
                                          this.canvas.height);
                },
                getContext() {
                    return this.context;
                },
                clear() {
                    this.context.clearRect(0, 0, this.canvas.width, 
                                           this.canvas.height);
                },
                prep() {
                    this.context.fillStyle = this.color;
                    this.context.fillRect(0, 0, this.canvas.width, 
                                          this.canvas.height);
                },
                getHeight() {
                    return this.canvas.height;
                },
                getWidth() {
                    return this.canvas.width;
                }
            }

            let UFO = {
                init(canvas, color) {
                    this.canvas = canvas;
                    this.x = Math.random() * this.canvas.getWidth();
                    this.y = Math.random() * this.canvas.getHeight();
                    this.r = Math.random() * 9 + 3;
                    this.dx = Math.random() * 5;
                    this.dy = Math.random() * 5;
                    this.color = color;
                    this.draw();
                },
                draw() {
                    this.canvas.getContext().beginPath();
                    this.canvas.getContext().fillStyle = this.color;
                    this.canvas.getContext().arc(this.x, this.y, this.r,
                                                 0, Math.PI * 2,
                                                 false);
                    this.canvas.getContext().fill();
                    this.canvas.getContext().closePath();
                },
                move() {
                    this.x += this.dx;  // move object horizontally
                    this.y += this.dy;  // move vertically
                }
            }

            let motor = function (cv, obs) {
                setInterval(function() {            // animate
                    cv.clear();
                    cv.prep();
/*
                    for (let i = 0; i < obs.length; i++) {
                        obs[i].move();              // every element
                        obs[i].draw();              // in array
                    }
*/
                    for (let obj of obs) {
                        obj.move();                 // iterate over
                        obj.draw();                 // all array values
                    }
                }, 10);
            }
            
            let initialize = () => {                // note new syntax
                let canvas = Object.create(Canvas); // create canvas
                canvas.init('canvas', '#ccc');
                let ufos = [];                      // create array
                let ufo0 = Object.create(UFO);      // create ufo
                ufo0.init(canvas, '#f00');
                ufos.push(ufo0);                    // add ufo to array
                ufo0 = Object.create(UFO);          // create ufo          
                ufo0.init(canvas, '#080');
                ufos.push(ufo0);                    // add ufo to array
                ufo0 = Object.create(UFO);          // create ufo
                ufo0.init(canvas, '#00f');
                ufos.push(ufo0);                    // add ufo to array
                motor(canvas, ufos);                // start motor 
            }

            window.addEventListener('load', initialize, false);
        </script>
    </head>
    <body>
        <section>
            <canvas id='canvas' width='400' height='400'>
                If you see this text long enough to read it,
                your browser is very old.
            </canvas>
        </section>
    </body>
</html>

Test it!