From df040e9a14aa782d6eabdc862ce29430d288b0d8 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sun, 25 Sep 2022 19:21:57 +0200 Subject: [PATCH] Refactor and make blob count dynamic --- src/page/background/background.ts | 77 ++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/page/background/background.ts b/src/page/background/background.ts index c3800c8..99d22cd 100644 --- a/src/page/background/background.ts +++ b/src/page/background/background.ts @@ -10,33 +10,65 @@ export class Background extends PageElement { private static readonly perspective = 5; private static readonly zMin = 6; private static readonly zMax = 50; + private static readonly minHeight = 360; + private static readonly maxHeight = 740; + private static readonly minBlobCount = 30; + private static readonly blobCountScaler = 0.1; + private static readonly stableSeed = 50; - private random: Random = new Random(); + private random = new Random(); + private stableRandom = new Random(); private blobs: Array = []; + private windowHeight = 0; + private windowWidth = 0; + private contentHeight = 0; public constructor( private readonly topOffsetElementCount: number, private readonly bottomOffsetElementCount: number ) { super(createElement(generate())); + } - for (let i = 0; i < Math.max(30, window.innerWidth / 10); i++) { - const blob = document.createElement('div'); - const z = this.random.inInterval(Background.zMin, Background.zMax); - blob.style.zIndex = (-z).toFixed(0); - blob.style.opacity = ( - 1 - - (z - Background.zMin) / (Background.zMax - Background.zMin) - ).toString(); - blob.style.height = `${this.random.inInterval(360, 740)}px`; + protected initialize() { + super.initialize(); + this.drawIfNecessary(); + } + + private maintainBlobCount() { + const targetCount = Math.max( + Background.minBlobCount, + Math.ceil(window.innerWidth * Background.blobCountScaler) + ); + const deltaCount = targetCount - this.blobs.length; + + for (let i = 0; i < deltaCount; i++) { + const blob = this.createBlob(); this.blobs.push(blob); this.htmlRoot.appendChild(blob); } + for (let i = 0; i < -deltaCount; i++) { + const blob = this.blobs.pop(); + this.htmlRoot.removeChild(blob!); + } + } + + private createBlob(): HTMLElement { + const blob = document.createElement('div'); + const z = this.random.inInterval(Background.zMin, Background.zMax); + blob.style.zIndex = (-z).toFixed(0); + blob.style.opacity = ( + 1 - + (z - Background.zMin) / (Background.zMax - Background.zMin) + ).toString(); + blob.style.height = `${this.random.inInterval( + Background.minHeight, + Background.maxHeight + )}px`; + + return blob; } - private windowHeight = 0; - private windowWidth = 0; - private contentHeight = 0; private drawIfNecessary() { const siblings = this.getSiblings(); const currentContentHeight = sum(siblings.map(getHeight)); @@ -48,6 +80,7 @@ export class Background extends PageElement { this.windowWidth = window.innerWidth; this.windowHeight = window.innerHeight; this.contentHeight = currentContentHeight; + this.maintainBlobCount(); this.randomizeBlobs( sum(siblings.slice(0, this.topOffsetElementCount).map(getHeight)), @@ -58,11 +91,6 @@ export class Background extends PageElement { requestAnimationFrame(this.drawIfNecessary.bind(this)); } - protected initialize() { - super.initialize(); - this.drawIfNecessary(); - } - private getSiblings(): Array { return Array.prototype.slice .call(this.htmlRoot.parentElement!.childNodes) @@ -70,10 +98,10 @@ export class Background extends PageElement { } private randomizeBlobs(topOffset: number, bottomOffset: number) { - this.random.seed = 50; + this.stableRandom.seed = Background.stableSeed; this.blobs.forEach((b) => { const z = -parseFloat(b.style.zIndex); - const [x, y] = this.getRandomPosition( + const [x, y] = this.getRandomPositionInSafeArea( z, topOffset, bottomOffset, @@ -83,7 +111,7 @@ export class Background extends PageElement { }); } - private getRandomPosition( + private getRandomPositionInSafeArea( z: number, topOffset: number, bottomOffset: number, @@ -109,7 +137,7 @@ export class Background extends PageElement { 2; return [ - this.random.inInterval( + this.stableRandom.inInterval( mix(0, -(endXSpan - this.windowWidth / 2), z / Background.zMax), mix( this.windowWidth, @@ -117,7 +145,10 @@ export class Background extends PageElement { z / Background.zMax ) ), - this.random.inInterval(mix(topOffset, farTop, z / Background.zMax), farBottom), + this.stableRandom.inInterval( + mix(topOffset, farTop, z / Background.zMax), + farBottom + ), ]; } }