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