accounts-frontend/packages/app/components/ui/bsod/Box.ts
2020-05-24 02:08:24 +03:00

112 lines
3.4 KiB
TypeScript

import Point from './Point';
const shadowLength = 2000; // TODO: should be calculated
export default class Box {
public position: Point;
private angle: number;
public color: string;
private readonly shadowColor: string;
private _size: number;
private _halfSize: number;
constructor(size: number, position: Point, startRotate: number, color: string, shadowColor: string) {
this.size = size;
this.position = position;
this.color = color;
this.angle = startRotate;
this.shadowColor = shadowColor;
}
public get size(): number {
return this._size;
}
public set size(size: number) {
this._size = size;
this._halfSize = Math.floor(size / 2);
}
public get halfSize(): number {
return this._halfSize;
}
get points(): { p1: Point; p2: Point; p3: Point; p4: Point } {
const full = (Math.PI * 2) / 4;
const p1: Point = {
x: this.position.x + this._halfSize * Math.sin(this.angle),
y: this.position.y + this._halfSize * Math.cos(this.angle),
};
const p2: Point = {
x: this.position.x + this._halfSize * Math.sin(this.angle + full),
y: this.position.y + this._halfSize * Math.cos(this.angle + full),
};
const p3: Point = {
x: this.position.x + this._halfSize * Math.sin(this.angle + full * 2),
y: this.position.y + this._halfSize * Math.cos(this.angle + full * 2),
};
const p4: Point = {
x: this.position.x + this._halfSize * Math.sin(this.angle + full * 3),
y: this.position.y + this._halfSize * Math.cos(this.angle + full * 3),
};
return { p1, p2, p3, p4 };
}
rotate(): void {
const speed = (60 - this._halfSize) / 20;
this.angle += speed * 0.002;
this.position.x += speed;
this.position.y += speed;
}
draw(ctx: CanvasRenderingContext2D): void {
const { points } = this;
ctx.beginPath();
ctx.moveTo(points.p1.x, points.p1.y);
ctx.lineTo(points.p2.x, points.p2.y);
ctx.lineTo(points.p3.x, points.p3.y);
ctx.lineTo(points.p4.x, points.p4.y);
ctx.fillStyle = this.color;
ctx.fill();
}
drawShadow(ctx: CanvasRenderingContext2D, light: Point): void {
const boxPoints = this.points;
const points: Array<{
startX: number;
startY: number;
endX: number;
endY: number;
}> = [];
Object.values(boxPoints).forEach((point) => {
const angle = Math.atan2(light.y - point.y, light.x - point.x);
const endX = point.x + shadowLength * Math.sin(-angle - Math.PI / 2);
const endY = point.y + shadowLength * Math.cos(-angle - Math.PI / 2);
points.push({
startX: point.x,
startY: point.y,
endX,
endY,
});
});
for (let i = points.length - 1; i >= 0; i--) {
const n = i === 3 ? 0 : i + 1;
ctx.beginPath();
ctx.moveTo(points[i].startX, points[i].startY);
ctx.lineTo(points[n].startX, points[n].startY);
ctx.lineTo(points[n].endX, points[n].endY);
ctx.lineTo(points[i].endX, points[i].endY);
ctx.fillStyle = this.shadowColor;
ctx.fill();
}
}
}