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
| (()=>{ const snowConf = { flakeCount: 100, minDist: 150, color: "255, 255, 255", size: 2, speed: 0.5, opacity: 0.3, stepsize: .5, };
let isSnowing = true;
const requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){window.setTimeout(callback, 1000/60);}; window.requestAnimationFrame = requestAnimationFrame; const canvas = document.getElementById("snow"); const ctx = canvas.getContext("2d"); const flakeCount = snowConf.flakeCount; let mX = -100, mY = -100; let flakes = []; canvas.width = window.innerWidth; canvas.height = window.innerHeight; const snow = () => { if (!isSnowing) { return; }
ctx.clearRect(0, 0, canvas.width, canvas.height);
const minDist = snowConf.minDist; for (let i = 0; i < flakeCount; i++){ let flake = flakes[i]; const x = mX, y = mY; const x2 = flake.x, y2 = flake.y; const dist = Math.sqrt((x - x2)*(x - x2) + (y - y2)*(y - y2)); if (dist < minDist) { const force = minDist / (dist*dist); const xcomp = (x - x2) / dist; const ycomp = (y - y2) / dist; const deltaV = force / 2; flake.velX -= deltaV * xcomp; flake.velY -= deltaV * ycomp; } else { flake.velX *= 0.98; if (flake.velY < flake.speed && (flake.speed - flake.velY > .01)) { flake.velY += (flake.speed - flake.velY) * .01; } flake.velX += Math.cos(flake.step += .05) * flake.stepSize; } ctx.fillStyle = "rgba(" + snowConf.color + ", " + 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); }; const 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; }; const startSnow = () => { for (let i = 0; i < flakeCount; i++) { const x = Math.floor(Math.random()*canvas.width); const y = Math.floor(Math.random()*canvas.height); const size = (Math.random()*3) + snowConf.size; const speed = (Math.random()*1) + snowConf.speed; const opacity = (Math.random()*0.5) + snowConf.opacity; flakes.push({ speed: speed, velX: 0, velY: speed, x: x, y: y, size: size, stepSize: (Math.random()) / 30 * snowConf.stepsize, step: 0, angle: 180, opacity: opacity }); } snow(); }; document.addEventListener("mousemove", (e)=>{mX = e.clientX, mY = e.clientY}); window.addEventListener("resize",()=>{canvas.width = window.innerWidth; canvas.height = window.innerHeight;});
startSnow(); })();
|