这是一个特定季节的问题。我做了一个基本的动画来模拟一些雪。问题是雪只会下降一次,之后屏幕会变黑。我已经按照一个教程将所有内容放在window.onload()中。这对我来说似乎不那么好,所以这就是我提出来的:
let sky, ctx;
let W, H;
const maxSnow = 250;
const snow = [];
function init(){
sky = document.getElementById("sky");
ctx = sky.getContext("2d");
sky.width = W = window.innerWidth;
sky.height = H = window.innerHeight;
for(let i = 0; i < maxSnow; i++)
{
snow.push({
x: Math.random()*W, //x-coordinate
y: -50, //y-coordinate
radius: Math.random()*4+1, //radius
density: Math.random()*maxSnow //density
})
}
}
function draw()
{
ctx.clearRect(0, 0, W, H);
ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
ctx.beginPath();
for(let i = 0; i < maxSnow; i++)
{
var flake = snow[i];
ctx.moveTo(flake.x, flake.y);
ctx.arc(flake.x, flake.y, flake.radius, 0, Math.PI*2, true);
}
ctx.fill();
update();
}
//Function to move the snowflakes
//angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes
var angle = 0;
function update()
{
angle += 0.01;
for(var i = 0; i < maxSnow; i++)
{
var p = snow[i];
//Updating X and Y coordinates
//We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards
//Every particle has its own density which can be used to make the downward movement different for each flake
//Lets make it more random by adding in the radius
p.y += Math.cos(angle+p.density) + 1 + p.radius/2;
p.x += Math.sin(angle) * 2;
//Sending flakes back from the top when it exits
//Lets make it a bit more organic and let flakes enter from the left and right also.
if(p.x > W+5 || p.x < -5 || p.y > H)
{
if(i%3 > 0) //66.67% of the flakes
{
snow[i] = {x: Math.random()*W, y: -10, r: p.radius, d: p.density};
}
else
{
//If the flake is exitting from the right
if(Math.sin(angle) > 0)
{
//Enter from the left
snow[i] = {x: -5, y: Math.random()*H, r: p.radius, d: p.density};
}
else
{
//Enter from the right
snow[i] = {x: W+5, y: Math.random()*H, r: p.radius, d: p.density};
}
}
}
}
}
window.onload = function(){
init();
//animation loop
setInterval(draw, 33);
}
window.addEventListener('resize', function(){
sky.width = W = window.innerWidth;
sky.height = H = window.innerHeight;
}, false);
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
background-color: rgba(0, 0, 0, 1);
}
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="sky"></canvas>
<script src="snow.js"></script>
</body>
</html>
有人看到问题是什么以及为什么粒子只落下一次? 谢谢。
答案 0 :(得分:3)
这是因为当雪花离开屏幕时,您将它们重置为错误的物体。
原始对象(以及所有方法)期望x
,y
,radius
和density
但是当您更新对象时,您需要创建x
,y
,r
和d
。
如果您将r
和d
重命名为正确的名称,则可以使用。
let sky, ctx;
let W, H;
const maxSnow = 250;
const snow = [];
function init(){
sky = document.getElementById("sky");
ctx = sky.getContext("2d");
sky.width = W = window.innerWidth;
sky.height = H = window.innerHeight;
for(let i = 0; i < maxSnow; i++)
{
snow.push({
x: Math.random()*W, //x-coordinate
y: -50, //y-coordinate
radius: Math.random()*4+1, //radius
density: Math.random()*maxSnow //density
})
}
}
function draw()
{
ctx.clearRect(0, 0, W, H);
ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
ctx.beginPath();
for(let i = 0; i < maxSnow; i++)
{
var flake = snow[i];
ctx.moveTo(flake.x, flake.y);
ctx.arc(flake.x, flake.y, flake.radius, 0, Math.PI*2, true);
}
ctx.fill();
update();
}
//Function to move the snowflakes
//angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes
var angle = 0;
function update()
{
angle += 0.01;
for(var i = 0; i < maxSnow; i++)
{
var p = snow[i];
//Updating X and Y coordinates
//We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards
//Every particle has its own density which can be used to make the downward movement different for each flake
//Lets make it more random by adding in the radius
p.y += Math.cos(angle+p.density) + 1 + p.radius/2;
p.x += Math.sin(angle) * 2;
//Sending flakes back from the top when it exits
//Lets make it a bit more organic and let flakes enter from the left and right also.
if(p.x > W+5 || p.x < -5 || p.y > H)
{
if(i%3 > 0) //66.67% of the flakes
{
snow[i] = {x: Math.random()*W, y: -10, radius: p.radius, density: p.density};
}
else
{
//If the flake is exitting from the right
if(Math.sin(angle) > 0)
{
//Enter from the left
snow[i] = {x: -5, y: Math.random()*H, radius: p.radius, density: p.density};
}
else
{
//Enter from the right
snow[i] = {x: W+5, y: Math.random()*H, radius: p.radius, density: p.density};
}
}
}
}
}
window.onload = function(){
init();
//animation loop
setInterval(draw, 33);
}
window.addEventListener('resize', function(){
sky.width = W = window.innerWidth;
sky.height = H = window.innerHeight;
}, false);
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
background-color: rgba(0, 0, 0, 1);
}
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="sky"></canvas>
<script src="snow.js"></script>
</body>
</html>