diff --git a/src/app/app.html b/src/app/app.html
index 7dd570e..e5f86a8 100644
--- a/src/app/app.html
+++ b/src/app/app.html
@@ -1 +1,2 @@
-
+
+
\ No newline at end of file
diff --git a/src/app/app.ts b/src/app/app.ts
index 2c33e2d..32569c1 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ThemeSwitchService } from './core/service/theme-switch.service';
+import { Background } from "./core/components/background/background";
@Component({
selector: 'app-root',
- imports: [RouterOutlet],
+ imports: [RouterOutlet, Background],
templateUrl: './app.html',
})
export class App {
diff --git a/src/app/core/components/background/background.html b/src/app/core/components/background/background.html
new file mode 100644
index 0000000..e0bd711
--- /dev/null
+++ b/src/app/core/components/background/background.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/app/core/components/background/background.scss b/src/app/core/components/background/background.scss
new file mode 100644
index 0000000..08d0458
--- /dev/null
+++ b/src/app/core/components/background/background.scss
@@ -0,0 +1,8 @@
+canvas {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: -1;
+}
\ No newline at end of file
diff --git a/src/app/core/components/background/background.ts b/src/app/core/components/background/background.ts
new file mode 100644
index 0000000..66a566b
--- /dev/null
+++ b/src/app/core/components/background/background.ts
@@ -0,0 +1,108 @@
+import { Component, ElementRef, HostListener, ViewChild } from '@angular/core';
+
+@Component({
+ selector: 'app-background',
+ imports: [],
+ templateUrl: './background.html',
+ styleUrl: './background.scss'
+})
+export class Background {
+
+ @ViewChild('canvas', { static: true }) canvasRef!: ElementRef;
+
+ // Config
+ private numStars = 150;
+ private minBlink = 0.2;
+ private maxBlink = 1;
+ private blinkSpeed = 0.002; // Stern blinkt langsamer oder schneller
+ private maxSpeed = 0.1; // Sternbewegungsgeschwindigkeit
+ private parallaxFactor = 0.5; // Scroll-Parallax-Faktor
+
+ // Feature toggles
+ private enableBlink = true;
+ private enableMovement = true;
+
+ private ctx!: CanvasRenderingContext2D;
+ private stars: Star[] = [];
+ private width = window.innerWidth;
+ private height = window.innerHeight;
+ private animationId!: number;
+ private scrollY = window.scrollY;
+
+ ngOnInit() {
+ const canvas = this.canvasRef.nativeElement;
+ this.ctx = canvas.getContext('2d')!;
+ canvas.width = this.width;
+ canvas.height = this.height;
+
+ for (let i = 0; i < (this.numStars) * (document.body.scrollHeight / this.height); i++) {
+ this.stars.push({
+ x: Math.random() * this.width,
+ y: Math.random() * document.body.scrollHeight,
+ radius: Math.random() * 1.5 + 0.5,
+ alpha: this.minBlink + Math.random() * (this.maxBlink - this.minBlink),
+ alphaChange: (Math.random() * this.blinkSpeed) + 0.0005,
+ vx: (Math.random() - 0.5) * this.maxSpeed,
+ vy: (Math.random() - 0.5) * this.maxSpeed
+ });
+ }
+
+ this.animate();
+ }
+
+ @HostListener('window:resize')
+ onResize() {
+ this.width = window.innerWidth;
+ this.height = window.innerHeight;
+ const canvas = this.canvasRef.nativeElement;
+ canvas.width = this.width;
+ canvas.height = this.height;
+ }
+
+ @HostListener('window:scroll')
+ onScroll() {
+ this.scrollY = window.scrollY;
+ }
+
+ private animate() {
+ const ctx = this.ctx;
+ ctx.clearRect(0, 0, this.width, this.height);
+
+ for (let star of this.stars) {
+ // Blinken
+ if (this.enableBlink) {
+ star.alpha += star.alphaChange;
+ if (star.alpha > this.maxBlink || star.alpha < this.minBlink) star.alphaChange *= -1;
+ }
+
+ // Bewegung
+ if (this.enableMovement) {
+ star.x += star.vx;
+ star.y += star.vy;
+ }
+
+ // Stern zeichnen mit Scroll-Parallax
+ ctx.beginPath();
+ ctx.arc(star.x, star.y - this.scrollY * this.parallaxFactor, star.radius, 0, Math.PI * 2);
+ ctx.fillStyle = `rgba(255, 215, 0, ${star.alpha})`; // gold
+ ctx.fill();
+ }
+
+ this.animationId = requestAnimationFrame(() => this.animate());
+ }
+
+ ngOnDestroy() {
+ cancelAnimationFrame(this.animationId);
+ }
+
+}
+
+interface Star {
+ x: number;
+ y: number;
+ radius: number;
+ alpha: number;
+ alphaChange: number;
+ vx: number;
+ vy: number;
+}
diff --git a/src/styles.scss b/src/styles.scss
index 31340f5..b94a413 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -4,6 +4,8 @@
body {
font-family: 'Open Sans Variable', sans-serif;
+ width: 100vw;
+ min-height: 100vh;
margin: 0;
padding: 15px;
font-size: 14px;
diff --git a/tsconfig.json b/tsconfig.json
index 769b80e..e2047cd 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,7 +9,7 @@
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
- "isolatedModules": false,
+ "isolatedModules": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "ES2022",