Spadający śnieg za pomocą HTML 5 i JS


ja

odwiedził stronę internetową Stack Exchange Winter
http://winterba.sh/
Bash, naprawdę kocham padający śnieg! Moje pytanie brzmi, jak odtworzyć podobny efekt, który wygląda równie dobrze. Próbowałem odtworzyć kod, aby sprawdzić, czy mogę go zrozumieć, ale niestety bezskutecznie. JS jest nad moją głową. Trochę googlowałem i znalazłem kilka

przykłady
http://seb.ly/demos/JSSnow/snow3d.html
ale nie były tak eleganckie jak strona SE lub nie wyglądały zbyt dobrze.
Czy ktoś może podać instrukcje, jak odtworzyć to, co tworzy strona SE Winter Bash, lub miejsce, w którym mógłbym się dowiedzieć, jak to zrobić?

Edit:

Chciałbym odwzorować efekt jak najbliżej, czyli padający śnieg z płatkami śniegu oraz możliwość poruszania myszą i wprawiania myszką w ruch lub wirowanie.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Świetne pytanie, tak naprawdę jakiś czas temu napisałem wtyczkę śnieżną, do której aktualizuję


zobacz to w akcji

http://loktar00.github.com/JQuery-Snowfall/
.

Połącz także z czystym źródłem js
https://github.com/loktar00/JQ ... ll.js
Zauważyłem, że otagowałeś pytanie HTML5 i Canvas, ale możesz to zrobić bez używania któregokolwiek z tych, tylko standardowe elementy z obrazami lub różnymi kolorami tła.
Oto dwie bardzo proste rzeczy, które właśnie dla Ciebie złożyłem. Moim zdaniem kluczem jest użycie sinusa, aby uzyskać ładny efekt falowania, gdy płatki opadają. Pierwsza wykorzystuje element canvas, druga używa zwykłych elementów dom.
Ponieważ jestem całkowicie zależny od płótna, oto wersja płótna, która moim zdaniem działa całkiem nieźle.

Wersja na płótnie

http://jsfiddle.net/loktar/UdyN6/

pełny ekran

http://codepen.io/loktar00/full/CHpGo
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
window.requestAnimationFrame = requestAnimationFrame;
})();
var flakes = [],
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
flakeCount = 200,
mX = -100,
mY = -100 canvas.width = window.innerWidth;
canvas.height = window.innerHeight;function snow() {
ctx.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < flakeCount; i++) {
var flake = flakes[i],
x = mX,
y = mY,
minDist = 150,
x2 = flake.x,
y2 = flake.y; var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
dx = x2 - x,
dy = y2 - y; if (dist < minDist) {
var force = minDist/(dist * dist),
xcomp = (x - x2)/dist,
ycomp = (y - y2)/dist,
deltaV = force/2; flake.velX -= deltaV * xcomp;
flake.velY -= deltaV * ycomp; } else {
flake.velX *= .98;
if (flake.velY <= flake.speed) {
flake.velY = flake.speed
}
flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
} ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")";
flake.y += flake.velY;
flake.x += flake.velX; if (flake.y >= canvas.height || flake.y <= 0) {
reset(flake);
}
if (flake.x >= canvas.width || flake.x <= 0) {
reset(flake);
} ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(snow);
};function reset(flake) {
flake.x = Math.floor(Math.random() * canvas.width);
flake.y = 0;
flake.size = (Math.random() * 3) + 2;
flake.speed = (Math.random() * 1) + 0.5;
flake.velY = flake.speed;
flake.velX = 0;
flake.opacity = (Math.random() * 0.5) + 0.3;
}function init() {
for (var i = 0; i < flakeCount; i++) {
var x = Math.floor(Math.random() * canvas.width),
y = Math.floor(Math.random() * canvas.height),
size = (Math.random() * 3) + 2,
speed = (Math.random() * 1) + 0.5,
opacity = (Math.random() * 0.5) + 0.3; flakes.push({
speed: speed,
velY: speed,
velX: 0,
x: x,
y: y,
size: size,
stepSize: (Math.random())/30,
step: 0,
angle: 180,
opacity: opacity
});
} snow();
};canvas.addEventListener("mousemove", function(e) {
mX = e.clientX,
mY = e.clientY
});init();​


Pozycja standardowa wersja

http://jsfiddle.net/loktar/guexx/
var flakes = [],
bodyHeight = getDocHeight(),
bodyWidth = document.body.offsetWidth;
function snow() {
for (var i = 0; i < 50; i++) {
var flake = flakes[i]; flake.y += flake.velY; if (flake.y > bodyHeight - (flake.size + 6)) {
flake.y = 0;
} flake.el.style.top = flake.y + 'px';
flake.el.style.left = ~~flake.x + 'px'; flake.step += flake.stepSize;
flake.velX = Math.cos(flake.step); flake.x += flake.velX; if (flake.x > bodyWidth - 40 || flake.x < 30) {
flake.y = 0;
}
}
setTimeout(snow, 10);
};
function init() {
var docFrag = document.createDocumentFragment();
for (var i = 0; i < 50; i++) {
var flake = document.createElement("div"),
x = Math.floor(Math.random() * bodyWidth),
y = Math.floor(Math.random() * bodyHeight),
size = (Math.random() * 5) + 2,
speed = (Math.random() * 1) + 0.5; flake.style.width = size + 'px';
flake.style.height = size + 'px';
flake.style.background = "#fff"; flake.style.left = x + 'px';
flake.style.top = y;
flake.classList.add("flake"); flakes.push({
el: flake,
speed: speed,
velY: speed,
velX: 0,
x: x,
y: y,
size: 2,
stepSize: (Math.random() * 5)/100,
step: 0
});
docFrag.appendChild(flake);
} document.body.appendChild(docFrag);
snow();
};document.addEventListener("mousemove", function(e) {
var x = e.clientX,
y = e.clientY,
minDist = 150; for (var i = 0; i < flakes.length; i++) {
var x2 = flakes[i].x,
y2 = flakes[i].y; var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)); if (dist < minDist) {
rad = Math.atan2(y2, x2), angle = rad/Math.PI * 180; flakes[i].velX = (x2/dist) * 0.2;
flakes[i].velY = (y2/dist) * 0.2; flakes[i].x += flakes[i].velX;
flakes[i].y += flakes[i].velY;
} else {
flakes[i].velY *= 0.9;
flakes[i].velX
if (flakes[i].velY <= flakes[i].speed) {
flakes[i].velY = flakes[i].speed;
}
}
}
});init();function getDocHeight() {
return Math.max( Math.max(document.body.scrollHeight, document.documentElement.scrollHeight), Math.max(document.body.offsetHeight, document.documentElement.offsetHeight), Math.max(document.body.clientHeight, document.documentElement.clientHeight));
}​
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Padający śnieg jest prosty: stwórz płótno, stwórz wiązkę płatków śniegu, narysuj je.
Możesz utworzyć klasę płatka śniegu w następujący sposób:
function Snowflake() {
this.x = Math.random()*canvas.width;
this.y = -16;
this.speed = Math.random()*3+1;
this.direction = Math.random()*360;
this.maxSpeed = 4;
}

Czy jakoś tak. Następnie masz zegar, który dostosowuje kierunek każdego płatka śniegu o niewielką wartość na każdym kroku, a następnie oblicza nowe X i Y, biorąc pod uwagę prędkość i kierunek.
Trudno to wyjaśnić, ale w rzeczywistości jest to dość proste.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się