styling(core): add star background
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
<router-outlet/>
|
<app-background/>
|
||||||
|
<router-outlet/>
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
import { ThemeSwitchService } from './core/service/theme-switch.service';
|
import { ThemeSwitchService } from './core/service/theme-switch.service';
|
||||||
|
import { Background } from "./core/components/background/background";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet],
|
imports: [RouterOutlet, Background],
|
||||||
templateUrl: './app.html',
|
templateUrl: './app.html',
|
||||||
})
|
})
|
||||||
export class App {
|
export class App {
|
||||||
|
|||||||
1
src/app/core/components/background/background.html
Normal file
1
src/app/core/components/background/background.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<canvas #canvas></canvas>
|
||||||
8
src/app/core/components/background/background.scss
Normal file
8
src/app/core/components/background/background.scss
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
canvas {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
108
src/app/core/components/background/background.ts
Normal file
108
src/app/core/components/background/background.ts
Normal file
@@ -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<HTMLCanvasElement>;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Open Sans Variable', sans-serif;
|
font-family: 'Open Sans Variable', sans-serif;
|
||||||
|
width: 100vw;
|
||||||
|
min-height: 100vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"isolatedModules": false,
|
"isolatedModules": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
|
|||||||
Reference in New Issue
Block a user