我用javascript制作了这个星域动画。我不确定让它从另一侧循环相同动画的最佳方法。我喜欢让星星从画布的一边滚动到另一边。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
stars = [];
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getSpeed(depth) {
switch (depth / 2) {
case 0:
return 6;
case 1:
return 5;
case 2:
return 4;
case 3:
return 3;
case 4:
return 2;
case 5:
return 1;
}
}
var i;
for (i = 0; i < 2000; i++) {
var star = {
x: 0,
y: 0,
z: 0,
v: 0
};
star.x = getRandomInt(0, 500);
star.y = getRandomInt(0, 500);
star.z = getRandomInt(0, 5) * 2;
star.v = getSpeed(star.z);
stars.push(star);
}
function animation() {
//clears background
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
// populates space with stars
for (i = 0; i < 2000; i++) {
ctx.fillStyle = "rgb(" + (256 / stars[i].z) + "," + (256 / stars[i].z) + "," + (256 / stars[i].z) + ")";
ctx.fillRect(stars[i].x, stars[i].y, 2, 2);
stars[i].x += stars[i].v;
}
setTimeout(animation, 33);
}
animation();
&#13;
<canvas id="myCanvas"></canvas>
&#13;
答案 0 :(得分:2)
只要在x值低于零时重置x值。
if (star.x < 0) star.x = canvasWidth;
我做了一些其他的改动,比较。
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function StarField(ctx, numStars, width, height) {
var stars = new Array(numStars).fill(null).map(getStar);
function getStar() {
var z = getRandomInt(0, 5),
c = (256 / z).toString(16);
return {
x: getRandomInt(0, width),
y: getRandomInt(0, height),
z: z * 2,
v: 6 - z,
c: "#" + c + c + c
};
}
this.animate = function () {
var i, s;
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, width, height);
for (i = 0; i < numStars; i++) {
s = stars[i];
ctx.fillStyle = s.c;
ctx.fillRect(s.x, s.y, 2, 2);
s.x -= s.v;
if (s.x < 0) s.x = width;
}
setTimeout(this.animate.bind(this), 32);
};
}
var canvas = document.getElementById("myCanvas");
var s = new StarField(canvas.getContext("2d"), 2000, 500, 500);
s.animate();
<canvas id="myCanvas"></canvas>
答案 1 :(得分:1)
要反转
stars[i].x -= stars[i].v;
你可以永远循环,当i == 1999时,将v乘以-1并再次将i设为0
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
stars = [];
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getSpeed(depth) {
switch (depth / 2) {
case 0:
return 6;
case 1:
return 5;
case 2:
return 4;
case 3:
return 3;
case 4:
return 2;
case 5:
return 1;
}
}
var i;
for (i = 0; i < 2000; i++) {
var star = {
x: 0,
y: 0,
z: 0,
v: 0
};
star.x = getRandomInt(0, 500);
star.y = getRandomInt(0, 500);
star.z = getRandomInt(0, 5) * 2;
star.v = getSpeed(star.z);
stars.push(star);
}
function animation() {
//clears background
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
// populates space with stars
for (i = 0; i < 2000; i++) {
ctx.fillStyle = "rgb(" + (256 / stars[i].z) + "," + (256 / stars[i].z) + "," + (256 / stars[i].z) + ")";
ctx.fillRect(stars[i].x, stars[i].y, 2, 2);
stars[i].x -= stars[i].v;
}
setTimeout(animation, 33);
}
animation();
<canvas id="myCanvas"></canvas>
答案 2 :(得分:1)
你可以通过添加新属性d(方向)看到星星双向移动,当星星到达屏幕末尾时方向会发生变化......
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
stars = [];
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getSpeed( depth)
{
switch(depth/2)
{
case 0:
return 6;
case 1:
return 5;
case 2:
return 4;
case 3:
return 3;
case 4:
return 2;
case 5:
return 1;
}
}
var i;
for (i = 0; i < 2000; i++) {
var star= { x: 0, y: 0, z: 0, v: 0 };
star.x = getRandomInt(0, 500);
star.y = getRandomInt(0, 500);
star.z = getRandomInt(0, 5) * 2;
star.v = getSpeed(star.z);
star.d = 1;
stars.push(star);
}
function animation () {
//clears background
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 500, 500);
// populates space with stars
for (i = 0; i < 2000; i++) {
ctx.fillStyle = "rgb(" + (256 / stars[i].z) + "," + (256 / stars[i].z) + "," + (256 / stars[i].z) + ")";
ctx.fillRect(stars[i].x, stars[i].y, 2, 2);
if(stars[i].x>=500)stars[i].d=-1;
if(stars[i].x<=0)stars[i].d=1;
stars[i].x += stars[i].v * stars[i].d;
}
setTimeout(animation, 33);
}
animation ();
</script>
</body>
</html>
答案 3 :(得分:1)
移动并重复使用余数运算符%
。因为它返回负值,所以你必须弄得一点点,以确保数字总是正数。此外,您还希望确保星星在完全偏离一侧时仅移动到画布的另一侧,因此模数值必须包含星号500+2
。
因此star pos x
x %= 502; // get remainder could be negative
x += 502; // ensure it is positive
x %= 502; // do modulo again
我是如何在你的例子中做到的
// set up
var w = canvas.width;
var h = canvas.height;
const starCount = 2000;
const starSize = 2;
const widthModulo = w + starSize;
const heightModulo = h + starSize;
// in iteration
x = ((star.x % widthModulo) + widthModulo) % widthModulo - starSize / 2;
y = ((star.y % heightModulo) + heightModulo) % heightModulo - starSize / 2;
// draw the star
ctx.fillRect(x, y, starSize, starSize);
我已经更改了您的代码,让星星向多个方向展示,以显示此方法的效果。还添加了一些其他更改。主要是使用requestAnimationFrame来调用动画函数。
var ctx = canvas.getContext("2d");
const stars = [];
var dir = Math.PI;
var w = canvas.width;
var h = canvas.height;
const starCount = 2000;
const starSize = 2;
const widthModulo = w + starSize;
const heightModulo = h + starSize;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var i;
for (i = 0; i < starCount; i++) {
// following 4 randoms give a semi bell curve to the random value
// this is to make more star at lower z values
var z = (Math.random() + Math.random() +Math.random() +Math.random());
z = Math.abs(z-2) * 8;
var col = Math.floor(16 * z);
stars.push({
x: getRandomInt(0, w),
y: getRandomInt(0, h),
v: z / 6,
col : "rgb("+col+","+col+","+col+")",
});
}
stars.sort((a,b)=>a.v - b.v); // sort from back to front
function animation (timer) {
var star, dx, dy, x, y, i;
// set the direction to make stars move in long circles
dir = (Math.sin(timer / 13289) + 1) * Math.PI ;
//clears background
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, w, h);
// get direction vector
dx = Math.cos(dir);
dy = Math.sin(dir);
for (i = 0; i < starCount; i += 1) {
star = stars[i];
ctx.fillStyle = star.col;
// move the star
star.x += star.v * dx;
star.y += star.v * dy;
// make sure that stars are rendered on the current viewport
x = ((star.x % widthModulo) + widthModulo) % widthModulo - starSize / 2;
y = ((star.y % heightModulo) + heightModulo) % heightModulo - starSize / 2;
// draw the star
ctx.fillRect(x, y, starSize, starSize);
}
requestAnimationFrame(animation);
}
requestAnimationFrame(animation);
&#13;
<canvas id=canvas width = 500 height = 500></canvas>
&#13;