-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
starfield.js
134 lines (118 loc) · 3.36 KB
/
starfield.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
Starfield lets you take a div and turn it into a starfield.
*/
// Define the starfield class.
function Starfield() {
this.fps = 30;
this.canvas = null;
this.width = 0;
this.height = 0;
this.minVelocity = 2;
this.maxVelocity = 5;
this.stars = 100;
this.intervalId = 0;
}
// The main function - initialises the starfield.
Starfield.prototype.initialise = function (div) {
var self = this;
// Store the div.
this.containerDiv = div;
self.width = window.innerWidth;
self.height = window.innerHeight;
window.addEventListener("resize", function resize(event) {
self.width = window.innerWidth;
self.height = window.innerHeight;
self.canvas.width = self.width;
self.canvas.height = self.height;
self.draw();
});
// Create the canvas.
var canvas = document.createElement("canvas");
div.appendChild(canvas);
this.canvas = canvas;
this.canvas.width = this.width;
this.canvas.height = this.height;
};
Starfield.prototype.start = function () {
// Create the stars.
var stars = [];
for (var i = 0; i < this.stars; i++) {
var angle = 2 * Math.PI * Math.random();
var x = Math.cos(angle);
var y = Math.sin(angle);
var velocity =
Math.random() * (this.maxVelocity - this.minVelocity) + this.minVelocity;
stars[i] = new Star(x, y, Math.random() * 3 + 1, velocity);
}
this.stars = stars;
var self = this;
// Start the timer.
this.intervalId = setInterval(function () {
self.update();
self.draw();
}, 1000 / this.fps);
// Skip 10000 frames so stars start in random places.
for (var i = 0; i < 10000; i++) {
self.update();
}
};
Starfield.prototype.stop = function () {
clearInterval(this.intervalId);
};
Starfield.prototype.update = function () {
var dt = 1 / this.fps;
for (var i = 0; i < this.stars.length; i++) {
var star = this.stars[i];
star.t += dt;
// If the star has moved from the bottom of the screen, spawn it at the top.
var x = star.x * star.t ** 2 * star.velocity;
var y = star.y * star.t ** 2 * star.velocity;
if (
x < -0.5 * this.width ||
x > 0.5 * this.width ||
y > 0.5 * this.height ||
y < -0.5 * this.height
) {
var angle = 2 * Math.PI * Math.random();
var x = Math.cos(angle);
var y = Math.sin(angle);
var velocity =
Math.random() * (this.maxVelocity - this.minVelocity) +
this.minVelocity;
this.stars[i] = new Star(x, y, Math.random() * 3 + 1, velocity);
}
}
};
Starfield.prototype.draw = function () {
// Get the drawing context.
var ctx = this.canvas.getContext("2d");
// Draw the background.
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, this.width, this.height);
// Draw stars.
ctx.fillStyle = "#ffffff";
for (var i = 0; i < this.stars.length; i++) {
var star = this.stars[i];
var x = star.x * star.t ** 2 * star.velocity;
var y = star.y * star.t ** 2 * star.velocity;
var relX = Math.abs((2 * x) / this.width) ** 1.2;
var relY = Math.abs((2 * y) / this.height) ** 1.2;
ctx.fillStyle = `rgb(
${Math.floor(relX * 200)},
${Math.floor(relY * 200)},
10)`;
ctx.fillRect(
this.canvas.width * 0.5 + x,
this.canvas.height * 0.5 + y,
star.size,
star.size,
);
}
};
function Star(x, y, size, velocity) {
this.x = x;
this.y = y;
this.t = 0;
this.size = size;
this.velocity = velocity;
}