carretero_1
carretero_1

Reputation: 27

What is wrong with this code? HTML5-Canvas

I am trying to animate a blackhole simulation using the canvas element so that if the distance is greater than the radius of the blackhole it goes out of it at a changing speed.

HTML


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>test trou noir</title>
        <script>
            var canvas, ctx;
            var blackhole;
            var circle;
            var circles = new Array();
            var G = 6.67e-11, //gravitational constant 
                c = 3e8, //speed of light (m/s)
                M = 12e31, // masseof the blackhole in kg (60 solar masses)  
                Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
                pixel_Rs = Rs / 1e3, // scaled radius 


            function update() {
                for (var i = 0; i < 200; i++) {
                    var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
                    circle = new Ball(5, vec2D.x, vec2D.y, "grey");
                    circle.draw(ctx)
                    circles.push(circle);
                    var distance = Math.sqrt(((vec2D.x - 700) * (vec2D.x - 700)) + ((vec2D.y - 400) * (vec2D.y - 400)));

                }
                if (distance > pixel_Rs) {
                    var delta = new Vector2D(1, 1);
                    var forceDirection = Math.atan2(vec2D.y - 700, vec2D.x - 400);
                    delta.x += Math.cos(forceDirection) * 3;
                    delta.y += Math.sin(forceDirection) * 3;
                    vec2D.x += delta.x;
                    vec2D.y += delta.y;
                    requestAnimationFrame(update);

                }
            };

            function init() {
                var G = 6.67e-11, //gravitational constant 
                    c = 3e8, //speed of light (m/s)
                    M = 12e31, // masseof the blackhole in kg (60 solar masses)  
                    Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
                    pixel_Rs = Rs / 1e3, // scaled radius 

                    canvas = document.getElementById("space");
                ctx = canvas.getContext('2d');



                blackhole = new Ball(pixel_Rs, 700, 400, "black");

                blackhole.draw(ctx);

                requestAnimationFrame(update);



            };

            function Ball(radius, posx, posy, color) {
                this.radius = radius;
                this.posy = posy;
                this.posx = posx;
                this.color = color;

            };
            Ball.prototype.draw = function(ctx) {
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.posx, this.posy, this.radius, 0, 2 * Math.PI);
                ctx.closePath();
                ctx.fill();
            };



            function drawCircle(ctx) {

                for (var i = 0; i < 200; i++) {
                    var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
                    circle = new Ball(5, vec2D.x, vec2D.y, "grey");
                    circle.draw(ctx)
                    circles.push(circle);
                }
            };

            function Vector2D(x, y) {
                this.x = x;
                this.y = y;
            }

            Vector2D.prototype = {
                length: function() {
                    return this.x * this.x + this.y * this.y;
                },
                add: function(vec) {
                    return new Vector2D(this.x + vec.x, this.y + vec.y);

                },

                subtract: function(vec) {
                    return new Vector2D(this.x - vec.x, this.y - vec.y);
                },
                decrementBy: function(vec) {
                    this.x -= vec.x;
                    this.y -= vec.y;
                }

            };

            window.onload = init;

        </script>
        <style>
            body {
                background-color: #021c36;
                margin: 0px;
            }
        </style>
    </head>
    <body>
        <canvas id="space" , width="1400" , height="800">
        </canvas>
    </body>
</html>

Why can't I get it to work or display anything ?

Upvotes: 1

Views: 142

Answers (1)

Stuart
Stuart

Reputation: 9868

You need to do a lot more work to actually animate this. Your update function has to:

  1. loop through all the circles in each animation frame
  2. check their distance from the black hole
  3. move their position if necessary
  4. redraw the whole canvas if any of the circles have moved.

In your existing code, all the update function does is draw a load more circles. Calling requestAnimationFrame is not going to work out how to animate the circles by itself. You also have a drawCircle function that is never called.

I have added these to this jsfiddle. Another small error was in your Math.atan2(vec2D.y - 700, vec2D.x - 400) which should be Math.atan2(vec2D.y - 400, vec2D.x - 700); and delta should be initiated to (0, 0) not (1, 1).

var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();
var G = 6.67e-11, //gravitational constant 
    c = 3e8, //speed of light (m/s)
    M = 12e31, // masseof the blackhole in kg (60 solar masses)  
    Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
    pixel_Rs = Rs / 1e3; // scaled radius 

function update() {
    var pos, i, distance, somethingMoved = false;
    for (i = 0; i < circles.length; i++) {
        pos = circles[i].position;
        distance = Math.sqrt(((pos.x - 700) * (pos.x - 700)) + ((pos.y - 400) * (pos.y - 400)));
        if (distance > pixel_Rs && visible(circles[i])) {
            var delta = new Vector2D(0, 0);
            var forceDirection = Math.atan2(pos.y - 700, pos.x - 400);
            delta.x += Math.cos(forceDirection) * 3;
            delta.y += Math.sin(forceDirection) * 3;
            pos.x += delta.x;
            pos.y += delta.y;
            somethingMoved = true;
        }
    }
    if (somethingMoved) {
        drawEverything();
        requestAnimationFrame(update);
    }
}

function visible(ball) {
    // --- Test whether ball is visible
    return ball.position.x > ball.radius && ball.position.x < canvas.width - ball.radius &&
        ball.position.y > ball.radius && ball.position.y < canvas.height - ball.radius;
}

function drawEverything() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    blackhole.draw(ctx);
    for (var i = 0; i < circles.length; i++) {
        if (visible(circles[i])) {
            circles[i].draw(ctx);
        }
    }
}

function init() {
    canvas = document.getElementById("space");
    ctx = canvas.getContext('2d');
    blackhole = new Ball(pixel_Rs, {
        x: 700,
        y: 400
    }, "black");
    for (var i = 0; i < 200; i++) {
        var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
        circle = new Ball(5, vec2D, "grey");
        circles.push(circle);
    }
    drawEverything();
    requestAnimationFrame(update);
}

function Ball(radius, position, color) {
    this.radius = radius;
    this.position = position;
    this.color = color;
}
Ball.prototype.draw = function(ctx) {
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fill();
};

function Vector2D(x, y) {
    this.x = x;
    this.y = y;
}

Vector2D.prototype = {
    length: function() {
        return this.x * this.x + this.y * this.y;
    },
    add: function(vec) {
        return new Vector2D(this.x + vec.x, this.y + vec.y);

    },

    subtract: function(vec) {
        return new Vector2D(this.x - vec.x, this.y - vec.y);
    },
    decrementBy: function(vec) {
        this.x -= vec.x;
        this.y -= vec.y;
    }

};

window.onload = init;

Upvotes: 1

Related Questions