Last active
May 22, 2021 17:29
-
-
Save konecnyna/63dbaaa70fe6fe77ebfa0707e1cbb6b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Adapted from https://codepen.io/pimskie/pen/jEVPNx **/ | |
function Flake(x, y, maxSpeedConfig) { | |
const maxWeight = 5; | |
const maxSpeed = maxSpeedConfig || 3; | |
this.x = x; | |
this.y = y; | |
this.r = randomBetween(0, 1); | |
this.a = randomBetween(0, Math.PI); | |
this.aStep = 0.01; | |
this.weight = randomBetween(2, maxWeight); | |
this.alpha = this.weight / maxWeight; | |
this.speed = (this.weight / maxWeight) * maxSpeed; | |
this.update = function () { | |
this.x += Math.cos(this.a) * this.r; | |
this.a += this.aStep; | |
this.y += this.speed; | |
}; | |
} | |
function init({ numFlakes, flakes, drawLines, imageSrc, maxSpeed }) { | |
let canvasElement = document.querySelector(".snow"); | |
if (!canvasElement) { | |
canvasElement = document.createElement("canvas"); | |
canvasElement.className = "snow"; | |
canvasElement.style.backgroundColor = "transparent"; | |
canvasElement.style.position = "absolute"; | |
canvasElement.style.pointerEvents = "none"; | |
document.body.appendChild(canvasElement); | |
} | |
const canvas = document.querySelector(".snow"); | |
const ctx = canvas.getContext("2d"); | |
canvasElement.style.backgroundColor = "transparent"; | |
canvasElement.style.position = "absolute"; | |
canvasElement.style.pointerEvents = "none"; | |
var i = numFlakes, | |
flake, | |
x, | |
y; | |
while (i--) { | |
x = randomBetween(0, windowW, true); | |
y = randomBetween(0, windowH, true); | |
flake = new Flake(x, y, maxSpeed); | |
flakes.push(flake); | |
} | |
scaleCanvas(canvas); | |
loop(ctx, flakes, drawLines, imageSrc); | |
} | |
function scaleCanvas(canvas) { | |
canvas.width = windowW; | |
canvas.height = windowH; | |
} | |
function loop(ctx, flakes, drawLines, imageSrc) { | |
var i = flakes.length, | |
z, | |
dist, | |
flakeA, | |
flakeB; | |
// clear canvas | |
ctx.save(); | |
ctx.setTransform(1, 0, 0, 1, 0, 0); | |
ctx.clearRect(0, 0, windowW, windowH); | |
ctx.restore(); | |
// loop of hell | |
while (i--) { | |
flakeA = flakes[i]; | |
flakeA.update(); | |
if (drawLines) { | |
for (z = 0; z < flakes.length; z++) { | |
flakeB = flakes[z]; | |
if (flakeA !== flakeB && distanceBetween(flakeA, flakeB) < 150) { | |
ctx.beginPath(); | |
ctx.moveTo(flakeA.x, flakeA.y); | |
ctx.lineTo(flakeB.x, flakeB.y); | |
ctx.strokeStyle = "#444444"; | |
ctx.stroke(); | |
ctx.closePath(); | |
} | |
} | |
} | |
ctx.beginPath(); | |
if (imageSrc) { | |
const background = new Image(); | |
background.src = imageSrc; | |
ctx.drawImage(background, flakeA.x, flakeA.y, 64, 64); | |
} else { | |
ctx.arc(flakeA.x, flakeA.y, flakeA.weight, 0, 2 * Math.PI, false); | |
ctx.fillStyle = "rgba(255, 255, 255, " + flakeA.alpha + ")"; | |
} | |
ctx.fill(); | |
if (flakeA.y >= windowH) { | |
flakeA.y = -flakeA.weight; | |
} | |
} | |
requestAnimationFrame(() => { | |
loop(ctx, flakes, drawLines, imageSrc); | |
}); | |
} | |
function randomBetween(min, max, round) { | |
var num = Math.random() * (max - min + 1) + min; | |
if (round) { | |
return Math.floor(num); | |
} else { | |
return num; | |
} | |
} | |
function distanceBetween(vector1, vector2) { | |
var dx = vector2.x - vector1.x, | |
dy = vector2.y - vector1.y; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
function makeRange(startDay, numberOfDays) { | |
return Array.from(new Array(numberOfDays), (x, i) => i + startDay); | |
} | |
function validateDate(month, days) { | |
const now = new Date(); | |
return days.includes(now.getDate()) && now.getMonth() == month - 1; | |
} | |
const windowW = window.innerWidth; | |
const windowH = window.innerHeight; | |
console.log("Loaded ha-snow.js"); | |
const isOctober = validateDate(11, makeRange(1, 31)); | |
const isDecember = validateDate(12, makeRange(1, 25)); | |
if (isOctober) { | |
console.log("Spooky enabled!"); | |
init({ | |
windowW, | |
windowH, | |
numFlakes: 5, | |
flakes: [], | |
drawLines: false, | |
imageSrc: "http://clipart-library.com/images/M8iGa75ca.png", | |
maxSpeed: 1, | |
}); | |
} else if (isDecember) { | |
console.log("Snow enabled!"); | |
init({ | |
windowW, | |
windowH, | |
numFlakes: 20, | |
flakes: [], | |
drawLines: false, | |
maxSpeed: 3, | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment