我正在尝试使用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>


为什么我不能使它工作或显示任何东西?

最佳答案

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


遍历每个动画帧中的所有圆圈
检查他们与黑洞的距离
如有必要,移动他们的位置
如果有任何圆圈移动,请重画整个画布。


在您现有的代码中,所有update函数所做的就是绘制更多的圆圈。调用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;

07-24 18:05