diff --git a/global/globalScript.js b/global/globalScript.js index 63e22b8..b053b1e 100644 --- a/global/globalScript.js +++ b/global/globalScript.js @@ -31,6 +31,11 @@ function randomInt(min, max) { } +function randomBool(probablity) { + return Math.random() <= probablity +} + + function clampNearest(n, mul) { if(n > 0) return Math.ceil(n / mul) * mul; diff --git a/global/pxDensity.js b/global/pxDensity.js index e7f394a..8b41224 100644 --- a/global/pxDensity.js +++ b/global/pxDensity.js @@ -1,12 +1,15 @@ let pxDensity = parseFloat(getComputedStyle(document.body).getPropertyValue("--pxDensity")) let pxDensityDefined = false -let densityWidth = document.documentElement.clientWidth / 256 -let densityHeight = document.documentElement.clientHeight / 164 +let pxWidth = 256 +let pxHeight = 164 + +let densityWidth = document.documentElement.clientWidth / pxWidth +let densityHeight = document.documentElement.clientHeight / pxHeight function calcPixelDensity() { - densityWidth = document.documentElement.clientWidth / 256 - densityHeight = document.documentElement.clientHeight / 164 + densityWidth = document.documentElement.clientWidth / pxWidth + densityHeight = document.documentElement.clientHeight / pxHeight let widest = Math.max(densityWidth, densityHeight) diff --git a/index.html b/index.html index af4b56a..0699987 100644 --- a/index.html +++ b/index.html @@ -35,9 +35,12 @@ + + + -
+
@@ -61,6 +64,7 @@ + \ No newline at end of file diff --git a/script.js b/script.js index ebfdd6d..eb0605f 100644 --- a/script.js +++ b/script.js @@ -4,6 +4,9 @@ function loadingScreenSynthwave() { setLoadingProgress("Adding stars...") addStars() + setLoadingProgress("Starting starfall animation...") + startStarfall() + setLoadingProgress("Starting synthwave animation...") defShaderMaterial() preAnimateSynthwave(25) @@ -20,4 +23,13 @@ function addStars() { starNoise.style.top = `round(calc(${randX}px * var(--pxDensity)), var(--pxDensityPx))` starNoise.style.left = `round(calc(${randY}px * var(--pxDensity)), var(--pxDensityPx))` +} + + +function onResizeSynthwave() { + renderer.setSize(window.innerWidth, window.innerHeight) + composer.setSize(window.innerWidth, window.innerHeight) + camera.aspect = window.innerWidth / window.innerHeight + camera.updateProjectionMatrix() + if (shaderMaterial) { updateShaderMatPxDensity() } } \ No newline at end of file diff --git a/starfall.js b/starfall.js new file mode 100644 index 0000000..468c729 --- /dev/null +++ b/starfall.js @@ -0,0 +1,112 @@ +const starfallCanvas = document.getElementById("starfallCanvas") +starfallCanvas.width = window.innerWidth +starfallCanvas.height = window.innerHeight + +const starfallCtx = starfallCanvas.getContext("2d") + + +class Starfall { + constructor() { + this.pos = {x: 0, y: 0} + this.vel = {x: 0, y: 0} + } + + generate() { + const dir = randomBool(0.5) + this.pos.x = dir ? -50 : pxWidth + 50 + this.pos.y = randomInt(-starfallCanvas.height / 2, starfallCanvas.height / 2) + this.vel.x = dir ? randomFloat(3, 6) : randomFloat(-6, -3) + this.vel.y = randomFloat(0.25, 1) + } + + draw() { + // very expensive but idk how to make it less expensive + drawPixelLine( + this.pos.x, + this.pos.y, + this.pos.x - (this.vel.x * 5), + this.pos.y - (this.vel.y * 5) + ) + } + + stepAnimation() { + this.pos.x += this.vel.x + this.pos.y += this.vel.y + } +} + + +function drawPixelLine(fromX, fromY, toX, toY) { + const pxInflate = 0.1; + + const dx = Math.abs(toX - fromX); + const dy = Math.abs(toY - fromY); + const sx = fromX < toX ? 1 : -1; + const sy = fromY < toY ? 1 : -1; + let err = dx - dy; + + let x = fromX; + let y = fromY; + + starfallCtx.beginPath(); + + const steps = Math.max(dx, dy); + + for (let i = 0; i <= steps; i++) { + const alpha = i == 0 ? 1 : 0.1 * (1 - i / steps) + starfallCtx.fillStyle = `rgba(255, 255, 255, ${alpha})`; + + starfallCtx.rect( + clampNearest(x * pxDensity, pxDensity) - 0.5, + clampNearest(y * pxDensity, pxDensity) - 0.5, + pxInflate + pxDensity, + pxInflate + pxDensity + ); + + const e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x += sx; + } + if (e2 < dx) { + err += dx; + y += sy; + } + + starfallCtx.fill(); + } +} + + +let allStarfalls = [] + +function animateStarfalls() { + if (!isAnimating) { return } + + starfallCtx.clearRect(0, 0, starfallCanvas.width, starfallCanvas.height) + + let shouldGenerate = randomBool(0.01) + + if (shouldGenerate) { + let newStarfall = new Starfall() + newStarfall.generate() + allStarfalls.push(newStarfall) + } + + for (let starfall of allStarfalls) { + if (starfall.pos.x < -50 || starfall.pos.x > pxWidth + 50) { + allStarfalls.splice(allStarfalls.indexOf(starfall), 1) + continue + } + + starfall.stepAnimation() + starfall.draw() + } +} + + +function startStarfall() { + animateStarfalls() + + requestAnimationFrame(startStarfall) +} \ No newline at end of file