This commit is contained in:
Schmelczer András 2020-01-11 13:05:40 +01:00
parent 65c0e3469e
commit 1893b774e7
14 changed files with 345 additions and 174 deletions

View file

@ -1,22 +1,22 @@
import { Vec2 } from './vec2';
import { Vec3 } from './vec3';
import { mixColors } from '../../framework/helper/mix-colors';
import { createElement } from '../../framework/helper/create-element';
import { Random } from '../../framework/helper/random';
import { generate } from './blob.html';
import { Animation } from './animation';
export class Blob {
private static readonly creatorRandom = new Random(44);
private static readonly darkColors = ['#2c477a'];
private static readonly lightColors = ['#fff9e0', '#ffd6d6'];
private static readonly rotation = (-20 / 180) * Math.PI;
private static readonly creatorRandom = new Random(51);
private static colorPickerRandom = new Random(132);
private static isDarkThemed = false;
private static zMin: number;
private static zMax: number;
private static perspective: number;
public static initialize(zMin: number, zMax: number, perspective: number) {
public static initialize(zMin: number, zMax: number) {
Blob.zMin = zMin;
Blob.zMax = zMax;
Blob.perspective = perspective;
}
public static changeTheme(isDarkThemed: boolean) {
@ -24,89 +24,79 @@ export class Blob {
Blob.isDarkThemed = isDarkThemed;
}
private readonly z = Blob.creatorRandom.randomInInterval(
Blob.zMin,
Blob.zMax
public readonly z = Blob.creatorRandom.randomInInterval(Blob.zMin, Blob.zMax);
private color: Animation<string>;
private readonly positionQ = new Vec2(
Blob.creatorRandom.next,
Blob.creatorRandom.next
);
private _positionScale = new Vec2(0, 0);
private _positionOffset = new Vec2(0, 0);
private readonly _size = new Vec2(
140,
Blob.creatorRandom.randomInInterval(260, 740)
);
private readonly element: HTMLElement = createElement(generate());
constructor() {
public constructor() {
this.decideColor();
this.element.style.zIndex = Math.round(-this.z).toString();
this.element.style.height = `${Blob.creatorRandom.randomInInterval(
160,
740
)}px`;
}
public decideColor() {
this.element.style.backgroundColor = mixColors(
Blob.isDarkThemed ? '#242638 ' : '#ffffff',
const target = mixColors(
Blob.isDarkThemed ? '#242638' : '#ffffff',
Blob.colorPickerRandom.choose(
Blob.isDarkThemed ? Blob.darkColors : Blob.lightColors
),
(this.z - Blob.zMin) / (Blob.zMax - Blob.zMin)
);
this.color = new Animation<string>(
this.color ? this.color.value : target,
target,
250,
(f, t, q) => mixColors(f, t, 1 - q)
);
}
get htmlElement(): HTMLElement {
return this.element;
public step(value) {
this.color?.step(value);
}
private randomWithKnownZ(
random: Random,
viewportSize: number,
scrollSize: number,
startOffset = 0,
endOffset = 0
): number {
const m = 1 + this.z / Blob.perspective;
const variableOffset = (offset, q) =>
Math.max(
0,
offset - ((this.z - Blob.zMin) / (Blob.zMax - Blob.zMin)) * (offset * q)
);
startOffset = variableOffset(startOffset, 1);
endOffset = variableOffset(endOffset, 0.2);
const lowerBound = viewportSize / 2 - (viewportSize / 2 - startOffset) * m;
const l =
scrollSize - viewportSize + (viewportSize - startOffset - endOffset) * m;
return random.randomInInterval(lowerBound, lowerBound + l);
public get topLeft(): Vec3 {
return Vec3.from(
this.positionQ.multiply(this._positionScale).add(this._positionOffset),
this.z
);
}
public show() {
this.element.style.opacity = '1';
public get size(): Vec2 {
return this._size;
}
public hide() {
this.element.style.opacity = '0';
public set positionScale(value: Vec2) {
this._positionScale = value;
}
public transform(
random: Random,
width: number,
viewportHeight: number,
scrollHeight: number,
startOffset: number,
endOffset: number
) {
const value = `
translateX(${this.randomWithKnownZ(random, width, width)}px)
translateY(${this.randomWithKnownZ(
random,
viewportHeight,
scrollHeight,
startOffset,
endOffset
)}px)
translateZ(${-this.z}px)
rotate(-20deg)
`;
this.element.style['-webkit-transform'] = value;
this.element.style.transform = value;
public set positionOffset(value: Vec2) {
this._positionOffset = value;
}
public draw(ctx: CanvasRenderingContext2D, position: Vec2, size: Vec2) {
ctx.save();
ctx.translate(position.x, position.y);
ctx.rotate(Blob.rotation);
ctx.beginPath();
ctx.arc(0, size.x / 2, size.x / 2, Math.PI, 0);
ctx.arc(0, size.y - size.x / 2, size.x / 2, 0, Math.PI);
ctx.closePath();
ctx.fillStyle = this.color.value;
ctx.fill();
ctx.restore();
}
}