Spaces:
Running
Running
Update stars.js
Browse files
stars.js
CHANGED
@@ -2,66 +2,143 @@ const canvas = document.getElementById("starfield");
|
|
2 |
const ctx = canvas.getContext("2d");
|
3 |
|
4 |
let stars = [];
|
|
|
|
|
5 |
|
|
|
6 |
function resizeCanvas() {
|
7 |
canvas.width = window.innerWidth;
|
8 |
canvas.height = window.innerHeight;
|
9 |
}
|
10 |
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
stars = [];
|
13 |
for (let i = 0; i < count; i++) {
|
14 |
stars.push({
|
15 |
x: Math.random() * canvas.width - canvas.width / 2,
|
16 |
y: Math.random() * canvas.height - canvas.height / 2,
|
17 |
z: Math.random() * canvas.width,
|
|
|
|
|
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 |
-
ctx.beginPath();
|
47 |
-
ctx.arc(x, y, size, 0, Math.PI * 2);
|
48 |
-
ctx.fill();
|
49 |
}
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
function animate() {
|
54 |
-
|
55 |
-
|
56 |
requestAnimationFrame(animate);
|
57 |
}
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
62 |
});
|
63 |
|
64 |
-
|
65 |
resizeCanvas();
|
66 |
-
|
67 |
animate();
|
|
|
2 |
const ctx = canvas.getContext("2d");
|
3 |
|
4 |
let stars = [];
|
5 |
+
let comets = [];
|
6 |
+
let speedFactor = 1;
|
7 |
|
8 |
+
// Resize canvas to full window
|
9 |
function resizeCanvas() {
|
10 |
canvas.width = window.innerWidth;
|
11 |
canvas.height = window.innerHeight;
|
12 |
}
|
13 |
|
14 |
+
window.addEventListener("resize", () => {
|
15 |
+
resizeCanvas();
|
16 |
+
initStars(800);
|
17 |
+
});
|
18 |
+
|
19 |
+
// Initialize starfield
|
20 |
+
function initStars(count) {
|
21 |
stars = [];
|
22 |
for (let i = 0; i < count; i++) {
|
23 |
stars.push({
|
24 |
x: Math.random() * canvas.width - canvas.width / 2,
|
25 |
y: Math.random() * canvas.height - canvas.height / 2,
|
26 |
z: Math.random() * canvas.width,
|
27 |
+
alpha: Math.random(),
|
28 |
+
color: randomStarColor(),
|
29 |
});
|
30 |
}
|
31 |
}
|
32 |
|
33 |
+
// Pick a random star color
|
34 |
+
function randomStarColor() {
|
35 |
+
const palette = ["#ffffff", "#fff9c4", "#a0d8f1"];
|
36 |
+
return palette[Math.floor(Math.random() * palette.length)];
|
37 |
+
}
|
38 |
+
|
39 |
+
// Occasionally spawn a shooting star/comet
|
40 |
+
function maybeAddComet() {
|
41 |
+
if (Math.random() < 0.005) {
|
42 |
+
comets.push({
|
43 |
+
x: Math.random() * canvas.width,
|
44 |
+
y: Math.random() * canvas.height * 0.3,
|
45 |
+
len: 0,
|
46 |
+
maxLen: 100 + Math.random() * 200,
|
47 |
+
angle: Math.PI * 0.25 + (Math.random() - 0.5) * 0.2,
|
48 |
+
speed: 10 + Math.random() * 10,
|
49 |
+
});
|
50 |
}
|
51 |
}
|
52 |
|
53 |
+
// Update star positions, twinkling, and comets
|
54 |
+
function update() {
|
55 |
+
const baseSpeed = 4 * speedFactor;
|
56 |
|
57 |
+
stars.forEach(s => {
|
58 |
+
s.z -= baseSpeed;
|
59 |
+
if (s.z <= 0) {
|
60 |
+
s.z = canvas.width;
|
61 |
+
s.x = Math.random() * canvas.width - canvas.width / 2;
|
62 |
+
s.y = Math.random() * canvas.height - canvas.height / 2;
|
63 |
+
s.alpha = Math.random();
|
64 |
+
s.color = randomStarColor();
|
|
|
|
|
|
|
65 |
}
|
66 |
+
// twinkle effect
|
67 |
+
s.alpha += (Math.random() - 0.5) * 0.03;
|
68 |
+
s.alpha = Math.max(0.2, Math.min(1, s.alpha));
|
69 |
+
});
|
70 |
+
|
71 |
+
comets = comets.filter(c => c.len < c.maxLen);
|
72 |
+
comets.forEach(c => {
|
73 |
+
c.len += c.speed;
|
74 |
+
c.x += Math.cos(c.angle) * c.speed;
|
75 |
+
c.y += Math.sin(c.angle) * c.speed;
|
76 |
+
});
|
77 |
+
|
78 |
+
maybeAddComet();
|
79 |
}
|
80 |
|
81 |
+
// Draw stars, trails, and comets
|
82 |
+
function draw() {
|
83 |
+
// motion trails
|
84 |
+
ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
|
85 |
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
86 |
+
|
87 |
+
// subtle gradient glow
|
88 |
+
const grad = ctx.createRadialGradient(
|
89 |
+
canvas.width / 2, canvas.height / 2, 0,
|
90 |
+
canvas.width / 2, canvas.height / 2, canvas.width
|
91 |
+
);
|
92 |
+
grad.addColorStop(0, "rgba(30,30,40,0.3)");
|
93 |
+
grad.addColorStop(1, "black");
|
94 |
+
ctx.fillStyle = grad;
|
95 |
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
96 |
+
|
97 |
+
// draw stars
|
98 |
+
stars.forEach(s => {
|
99 |
+
const k = 128 / s.z;
|
100 |
+
const x = s.x * k + canvas.width / 2;
|
101 |
+
const y = s.y * k + canvas.height / 2;
|
102 |
+
if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) return;
|
103 |
+
|
104 |
+
const size = (1 - s.z / canvas.width) * 3;
|
105 |
+
ctx.globalAlpha = s.alpha;
|
106 |
+
ctx.fillStyle = s.color;
|
107 |
+
ctx.beginPath();
|
108 |
+
ctx.arc(x, y, size, 0, Math.PI * 2);
|
109 |
+
ctx.fill();
|
110 |
+
});
|
111 |
+
|
112 |
+
ctx.globalAlpha = 1;
|
113 |
+
|
114 |
+
// draw comets
|
115 |
+
comets.forEach(c => {
|
116 |
+
ctx.strokeStyle = "rgba(255, 255, 255, 0.8)";
|
117 |
+
ctx.lineWidth = 2;
|
118 |
+
ctx.beginPath();
|
119 |
+
ctx.moveTo(c.x, c.y);
|
120 |
+
ctx.lineTo(
|
121 |
+
c.x - Math.cos(c.angle) * c.len,
|
122 |
+
c.y - Math.sin(c.angle) * c.len
|
123 |
+
);
|
124 |
+
ctx.stroke();
|
125 |
+
});
|
126 |
+
}
|
127 |
+
|
128 |
+
// Main loop
|
129 |
function animate() {
|
130 |
+
update();
|
131 |
+
draw();
|
132 |
requestAnimationFrame(animate);
|
133 |
}
|
134 |
|
135 |
+
// Speed boost based on mouse X position
|
136 |
+
window.addEventListener("mousemove", e => {
|
137 |
+
const pct = e.clientX / canvas.width;
|
138 |
+
speedFactor = 0.5 + pct * 2; // 0.5x to 2.5x speed
|
139 |
});
|
140 |
|
141 |
+
// Initialize and start animation
|
142 |
resizeCanvas();
|
143 |
+
initStars(800);
|
144 |
animate();
|