Remove particles background and update routing

Deleted the particles background component and its related files. Updated routing logic and constants, refactored topbar and algorithms pages, and performed dependency updates and cleanup in package files. Also improved i18n translations and adjusted TypeScript configuration.
This commit is contained in:
2026-02-02 08:51:10 +01:00
parent 05fc70e583
commit 3a13d62c9e
18 changed files with 957 additions and 6608 deletions

7311
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "playground-frontend", "name": "playground-frontend",
"version": "0.1.0", "version": "0.2.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
@@ -11,7 +11,6 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular-devkit/build-angular": "~21.1.0",
"@angular/animations": "~21.1.0", "@angular/animations": "~21.1.0",
"@angular/cdk": "~21.1.0", "@angular/cdk": "~21.1.0",
"@angular/common": "~21.1.0", "@angular/common": "~21.1.0",
@@ -23,18 +22,14 @@
"@angular/router": "~21.1.0", "@angular/router": "~21.1.0",
"@ngx-translate/core": "~17.0.0", "@ngx-translate/core": "~17.0.0",
"@ngx-translate/http-loader": "~17.0.0", "@ngx-translate/http-loader": "~17.0.0",
"@tsparticles/angular": "~3.0.0",
"@tsparticles/engine": "~3.9.1",
"rxjs": "~7.8.2", "rxjs": "~7.8.2",
"swiper": "~12.0.3", "swiper": "~12.1.0",
"tslib": "~2.8.1", "tslib": "~2.8.1"
"tsparticles": "~3.9.1"
}, },
"devDependencies": { "devDependencies": {
"@angular/build": "~21.1.0", "@angular/build": "~21.1.0",
"@angular/cli": "~21.1.0", "@angular/cli": "~21.1.0",
"@angular/compiler-cli": "~21.1.0", "@angular/compiler-cli": "~21.1.0",
"@angular/platform-browser-dynamic": "~21.1.0",
"@types/jasmine": "~5.1.15", "@types/jasmine": "~5.1.15",
"angular-eslint": "21.2.0", "angular-eslint": "21.2.0",
"eslint": "^9.39.2", "eslint": "^9.39.2",

View File

@@ -1,16 +1,13 @@
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import {AboutComponent} from './pages/about/about.component'; import {AboutComponent} from './pages/about/about.component';
import {ProjectsComponent} from './pages/projects/projects.component'; import {RouterConstants} from './constants/RouterConstants';
import {ImprintComponent} from './pages/imprint/imprint.component';
import {AlgorithmsComponent} from './pages/algorithms/algorithms.component';
import {PathfindingComponent} from './pages/algorithms/pathfinding/pathfinding.component';
export const routes: Routes = [ export const routes: Routes = [
{ path: '', component: AboutComponent }, { path: '', component: AboutComponent },
{ path: 'about', component: AboutComponent}, { path: RouterConstants.ABOUT.PATH, component: RouterConstants.ABOUT.COMPONENT},
{ path: 'projects', component: ProjectsComponent}, { path: RouterConstants.PROJECTS.PATH, component: RouterConstants.PROJECTS.COMPONENT},
{ path: 'algorithms', component: AlgorithmsComponent}, { path: RouterConstants.ALGORITHMS.PATH, component: RouterConstants.ALGORITHMS.COMPONENT},
{ path: 'algorithms/pathfinding', component: PathfindingComponent }, { path: RouterConstants.PATHFINDING.PATH, component: RouterConstants.PATHFINDING.COMPONENT},
{ path: 'imprint', component: ImprintComponent}, { path: RouterConstants.IMPRINT.PATH, component: RouterConstants.IMPRINT.COMPONENT},
]; ];

View File

@@ -0,0 +1,39 @@
import {AboutComponent} from '../pages/about/about.component';
import {ProjectsComponent} from '../pages/projects/projects.component';
import {ImprintComponent} from '../pages/imprint/imprint.component';
import {AlgorithmsComponent} from '../pages/algorithms/algorithms.component';
import {PathfindingComponent} from '../pages/algorithms/pathfinding/pathfinding.component';
export class RouterConstants {
static readonly ABOUT = {
PATH: 'about',
LINK: ['/about'] as const,
COMPONENT: AboutComponent
};
static readonly PROJECTS = {
PATH: 'projects',
LINK: ['/projects'] as const,
COMPONENT: ProjectsComponent
};
static readonly ALGORITHMS = {
PATH: 'algorithms',
LINK: ['/algorithms'] as const,
COMPONENT: AlgorithmsComponent
};
static readonly PATHFINDING = {
PATH: 'algorithms/pathfinding',
LINK: ['/algorithms', 'pathfinding'] as const,
COMPONENT: PathfindingComponent
};
static readonly IMPRINT = {
PATH: 'imprint',
LINK: ['/imprint'] as const,
COMPONENT: ImprintComponent
};
}

View File

@@ -1,6 +0,0 @@
<ngx-particles
[id]="id"
[options]="particlesOptions"
[particlesInit]="particlesInit"
(particlesLoaded)="particlesLoaded($event)"
></ngx-particles>

View File

@@ -1,2 +0,0 @@
:host { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.particles { width: 100%; height: 100%; display: block; }

View File

@@ -1,104 +0,0 @@
import {
Container,
Engine
} from "@tsparticles/engine";
import {NgParticlesService, NgxParticlesModule} from "@tsparticles/angular";
import { Component, inject } from '@angular/core';
import {loadFull} from 'tsparticles';
@Component({
selector: 'app-particles-bg',
standalone: true,
imports: [
NgxParticlesModule
],
templateUrl: './particles-bg.component.html',
styleUrl: './particles-bg.component.scss',
})
export class ParticlesBgComponent {
private readonly ngParticlesService = inject(NgParticlesService);
id = "tsparticles";
/* Starting from 1.19.0 you can use a remote url (AJAX request) to a JSON with the configuration */
particlesUrl = "http://foo.bar/particles.json";
/* or the classic JavaScript object */
particlesOptions = {
/*background: {
color: {
value: "#0d47a1",
},
},
fpsLimit: 120,
interactivity: {
events: {
onClick: {
enable: true,
},
onHover: {
enable: true,
},
resize: true,
},
modes: {
push: {
quantity: 4,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color: {
value: "#ffffff",
},
links: {
color: "#ffffff",
distance: 150,
enable: true,
opacity: 0.5,
width: 1,
},
move: {
direction: MoveDirection.none,
enable: true,
outModes: {
default: OutMode.bounce,
},
random: false,
speed: 6,
straight: false,
},
number: {
density: {
enable: true,
area: 800,
},
value: 80,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
value: { min: 1, max: 5 },
},
},
detectRetina: true,*/
};
async particlesInit(engine: Engine): Promise<void> {
await loadFull(engine);
}
particlesLoaded(container: Container): void {
console.log(container);
}
}

View File

@@ -10,10 +10,10 @@
</a> </a>
<nav class="nav"> <nav class="nav">
<a routerLink="/about" mat-button>{{ 'TOPBAR.ABOUT' | translate }}</a> <a [routerLink]="RouterConstants.ABOUT.LINK" mat-button>{{ 'TOPBAR.ABOUT' | translate }}</a>
<a routerLink="/projects" mat-button>{{ 'TOPBAR.PROJECTS' | translate }}</a> <a [routerLink]="RouterConstants.PROJECTS.LINK" mat-button>{{ 'TOPBAR.PROJECTS' | translate }}</a>
<a routerLink="/algorithms" mat-button>{{ 'TOPBAR.ALGORITHMS' | translate }}</a> <a [routerLink]="RouterConstants.ALGORITHMS.LINK" mat-button>{{ 'TOPBAR.ALGORITHMS' | translate }}</a>
<a routerLink="/imprint" mat-button>{{ 'TOPBAR.IMPRINT' | translate }}</a> <a [routerLink]="RouterConstants.IMPRINT.LINK" mat-button>{{ 'TOPBAR.IMPRINT' | translate }}</a>
</nav> </nav>
<!-- Mobile nav menu button --> <!-- Mobile nav menu button -->
@@ -29,16 +29,16 @@
<!-- Mobile nav menu --> <!-- Mobile nav menu -->
<mat-menu #navMenu="matMenu" xPosition="before"> <mat-menu #navMenu="matMenu" xPosition="before">
<button mat-menu-item routerLink="/about"> <button mat-menu-item [routerLink]="RouterConstants.ABOUT.LINK">
{{ 'TOPBAR.ABOUT' | translate }} {{ 'TOPBAR.ABOUT' | translate }}
</button> </button>
<button mat-menu-item routerLink="/projects"> <button mat-menu-item [routerLink]="RouterConstants.PROJECTS.LINK">
{{ 'TOPBAR.PROJECTS' | translate }} {{ 'TOPBAR.PROJECTS' | translate }}
</button> </button>
<button mat-menu-item routerLink="/algorithms"> <button mat-menu-item [routerLink]="RouterConstants.ALGORITHMS.LINK">
{{ 'TOPBAR.ALGORITHMS' | translate }} {{ 'TOPBAR.ALGORITHMS' | translate }}
</button> </button>
<button mat-menu-item routerLink="/imprint"> <button mat-menu-item [routerLink]="RouterConstants.IMPRINT.LINK">
{{ 'TOPBAR.IMPRINT' | translate }} {{ 'TOPBAR.IMPRINT' | translate }}
</button> </button>
</mat-menu> </mat-menu>

View File

@@ -10,6 +10,7 @@ import { ThemeService } from '../../service/theme.service';
import { LanguageService } from '../../service/language.service'; import { LanguageService } from '../../service/language.service';
import { MatDivider } from '@angular/material/divider'; import { MatDivider } from '@angular/material/divider';
import {AssetsConstants} from '../../constants/AssetsConstants'; import {AssetsConstants} from '../../constants/AssetsConstants';
import {RouterConstants} from '../../constants/RouterConstants';
@Component({ @Component({
selector: 'app-topbar', selector: 'app-topbar',
@@ -41,4 +42,5 @@ export class TopbarComponent {
setLang(code: 'de' | 'en') { this.lang.use(code); } setLang(code: 'de' | 'en') { this.lang.use(code); }
protected readonly AssetsConstants = AssetsConstants; protected readonly AssetsConstants = AssetsConstants;
protected readonly RouterConstants = RouterConstants;
} }

View File

@@ -1,13 +1,13 @@
<div class="container"> <div class="container">
<h1>Algorithmen</h1> <h1>{{ 'ALGORITHM.TITLE' |translate }}</h1>
<div class="category-cards"> <div class="category-cards">
@for (category of categories$ | async; track category.id) { @for (category of categories$ | async; track category.id) {
<mat-card [routerLink]="[category.routerLink]"> <mat-card [routerLink]="[category.routerLink]">
<mat-card-header> <mat-card-header>
<mat-card-title>{{ category.title }}</mat-card-title> <mat-card-title>{{ category.title | translate }}</mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<p>{{ category.description }}</p> <p>{{ category.description | translate}}</p>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
} }

View File

@@ -10,10 +10,7 @@
mat-card { mat-card {
cursor: pointer; cursor: pointer;
max-width: 300px; min-width: 300px;
max-width: 400px;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
} }
} }

View File

@@ -5,22 +5,20 @@ import { Observable } from 'rxjs';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router'; import { RouterLink } from '@angular/router';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import {TranslatePipe} from '@ngx-translate/core';
@Component({ @Component({
selector: 'app-algorithms', selector: 'app-algorithms',
templateUrl: './algorithms.component.html', templateUrl: './algorithms.component.html',
styleUrls: ['./algorithms.component.scss'], styleUrls: ['./algorithms.component.scss'],
standalone: true, standalone: true,
imports: [CommonModule, RouterLink, MatCardModule], imports: [CommonModule, RouterLink, MatCardModule, TranslatePipe],
}) })
export class AlgorithmsComponent implements OnInit { export class AlgorithmsComponent implements OnInit {
private algorithmsService = inject(AlgorithmsService); private readonly algorithmsService = inject(AlgorithmsService);
categories$: Observable<AlgorithmCategory[]> | undefined; categories$: Observable<AlgorithmCategory[]> | undefined;
ngOnInit(): void { ngOnInit(): void {
this.categories$ = this.algorithmsService.getCategories(); this.categories$ = this.algorithmsService.getCategories();
} }

View File

@@ -7,19 +7,13 @@ import { Observable, of } from 'rxjs';
}) })
export class AlgorithmsService { export class AlgorithmsService {
private categories: AlgorithmCategory[] = [ private readonly categories: AlgorithmCategory[] = [
{ {
id: 'pathfinding', id: 'pathfinding',
title: 'Pfadfindungsalgorithmen', title: 'ALGORITHM.PATHFINDING.TITLE',
description: 'Vergleich von Pfadfindungsalgorithmen wie Dijkstra und A*.', description: 'ALGORITHM.PATHFINDING.DESCRIPTION',
routerLink: 'pathfinding' routerLink: 'pathfinding'
}, }
// {
// id: 'sorting',
// title: 'Sortieralgorithmen',
// description: 'Visualisierung von Sortieralgorithmen wie Bubble Sort, Merge Sort und Quick Sort.',
// routerLink: 'sorting'
// }
]; ];
getCategories(): Observable<AlgorithmCategory[]> { getCategories(): Observable<AlgorithmCategory[]> {

View File

@@ -310,5 +310,12 @@
"ALERT": { "ALERT": {
"START_END_NODES": "Bitte wählen Sie einen Start- und Endknoten aus, bevor Sie den Algorithmus starten." "START_END_NODES": "Bitte wählen Sie einen Start- und Endknoten aus, bevor Sie den Algorithmus starten."
} }
},
"ALGORITHM": {
"TITLE": "Algorithmen",
"PATHFINDING": {
"TITLE": "Wegfindung",
"DESCRIPTION": "Vergleich von Dijkstra vs. A*."
}
} }
} }

View File

@@ -310,5 +310,12 @@
"ALERT": { "ALERT": {
"START_END_NODES": "Please select a start and end node before running the algorithm." "START_END_NODES": "Please select a start and end node before running the algorithm."
} }
},
"ALGORITHM": {
"TITLE": "Algorithms",
"PATHFINDING": {
"TITLE": "Pathfinding",
"DESCRIPTION": "Comparing of Dijkstra vs. A*."
}
} }
} }

View File

@@ -2,8 +2,6 @@ import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config'; import { appConfig } from './app/app.config';
import packageJson from '../package.json'; import packageJson from '../package.json';
import {AppComponent} from './app/layout/app/app.component'; import {AppComponent} from './app/layout/app/app.component';
import { register } from 'swiper/element/bundle';
register();
if (packageJson.version) { if (packageJson.version) {

View File

@@ -3,6 +3,7 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"resolveJsonModule": true,
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": [] "types": []
}, },

View File

@@ -13,7 +13,10 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"importHelpers": true, "importHelpers": true,
"target": "ES2022", "target": "ES2022",
"module": "preserve" "module": "preserve",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"esModuleInterop": true
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false, "enableI18nLegacyMessageIdFormat": false,