Refactor and make blob count dynamic

This commit is contained in:
Andras Schmelczer 2022-09-25 19:21:57 +02:00
parent 78dd507be4
commit df040e9a14
No known key found for this signature in database
GPG key ID: 0EA1BC97D0AB076E

View file

@ -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<HTMLElement> = [];
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<HTMLElement> {
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
),
];
}
}