这段代码有什么问题? HTML5的画布

时间:2016-01-28 18:34:01

标签: javascript canvas html5-canvas

我正在尝试使用canvas元素设置黑洞模拟的动画,这样如果距离大于黑洞的半径,它就会以变化的速度离开它。

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>

为什么我无法让它工作或显示任何东西?

1 个答案:

答案 0 :(得分:1)

你需要做更多的工作来实际制作动画。您的更新功能必须:

  1. 遍历每个动画帧中的所有圆圈
  2. 检查他们与黑洞的距离
  3. 必要时移动他们的位置
  4. 如果任何圆圈移动,则重绘整个画布。
  5. 在您现有的代码中,所有更新功能都会绘制更多的圆圈。调用requestAnimationFrame并不会解决如何自己动画圆圈的问题。您还有一个永远不会被调用的drawCircle函数。

    我已将这些添加到此jsfiddle。您Math.atan2(vec2D.y - 700, vec2D.x - 400)中的另一个小错误应该是Math.atan2(vec2D.y - 400, vec2D.x - 700);并且delta应该被启动到(0,0)而不是(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;