refactored projects site
This commit is contained in:
61
src/app/pages/projects/dialog/project-dialog.component.html
Normal file
61
src/app/pages/projects/dialog/project-dialog.component.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<h2 mat-dialog-title>{{ project.title | translate }}</h2>
|
||||||
|
<mat-dialog-content>
|
||||||
|
<p>{{ project.introduction | translate }}</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@for(bullet of project.bulletPoints; track bullet) {
|
||||||
|
<li>{{ bullet | translate }}</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
@if (project.images.length > 0)
|
||||||
|
{
|
||||||
|
<swiper-container
|
||||||
|
class="my-swiper"
|
||||||
|
[attr.slides-per-view]="1.2"
|
||||||
|
[attr.space-between]="12"
|
||||||
|
[attr.navigation]="true"
|
||||||
|
[attr.pagination]="true"
|
||||||
|
[attr.keyboard]="true"
|
||||||
|
style="width: 100%;"
|
||||||
|
>
|
||||||
|
@for (img of project.images; track img) {
|
||||||
|
<swiper-slide>
|
||||||
|
<img
|
||||||
|
class="slide-img"
|
||||||
|
[src]="img"
|
||||||
|
[alt]="project.title | translate"
|
||||||
|
/>
|
||||||
|
</swiper-slide>
|
||||||
|
}
|
||||||
|
</swiper-container>
|
||||||
|
}
|
||||||
|
|
||||||
|
<mat-chip-set aria-label="Technologies">
|
||||||
|
@for(tech of project.technologies; track tech) {
|
||||||
|
<mat-chip>{{tech}}</mat-chip>
|
||||||
|
}
|
||||||
|
</mat-chip-set>
|
||||||
|
|
||||||
|
<div class="link-section">
|
||||||
|
@if (project.link)
|
||||||
|
{
|
||||||
|
<a mat-button href="{{project.link}}" target="_blank" rel="noopener noreferrer">
|
||||||
|
<mat-icon>open_in_new</mat-icon>
|
||||||
|
{{ 'PROJECTS.LINK_TO_PROJECT' | translate }}
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if(project.assets)
|
||||||
|
{
|
||||||
|
<a mat-button href="{{project.assets}}" rel="noopener noreferrer">
|
||||||
|
<mat-icon>download</mat-icon>
|
||||||
|
{{ 'PROJECTS.DOWNLOAD' | translate}}
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button mat-dialog-close>{{ 'PROJECTS.CLOSE' | translate }}</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
60
src/app/pages/projects/dialog/project-dialog.component.scss
Normal file
60
src/app/pages/projects/dialog/project-dialog.component.scss
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
.my-swiper::part(button-prev),
|
||||||
|
.my-swiper::part(button-next) {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(0,0,0,.5);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-swiper::part(button-prev):hover,
|
||||||
|
.my-swiper::part(button-next):hover {
|
||||||
|
background: rgba(0,0,0,.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-swiper::part(pagination) {
|
||||||
|
bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 512px !important;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-left: 20px;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-chip-set {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-section {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-dialog-actions {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
35
src/app/pages/projects/dialog/project-dialog.component.ts
Normal file
35
src/app/pages/projects/dialog/project-dialog.component.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import {Component, inject, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||||
|
import {
|
||||||
|
MAT_DIALOG_DATA,
|
||||||
|
MatDialogActions,
|
||||||
|
MatDialogClose,
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogTitle
|
||||||
|
} from '@angular/material/dialog';
|
||||||
|
import {Projects} from '../projects.component';
|
||||||
|
import {TranslatePipe} from '@ngx-translate/core';
|
||||||
|
import {MatIcon} from '@angular/material/icon';
|
||||||
|
import {MatChip, MatChipSet} from '@angular/material/chips';
|
||||||
|
import {MatButton} from '@angular/material/button';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-project-dialog',
|
||||||
|
templateUrl: './project-dialog.component.html',
|
||||||
|
styleUrls: ['./project-dialog.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
MatDialogTitle,
|
||||||
|
MatDialogContent,
|
||||||
|
TranslatePipe,
|
||||||
|
MatIcon,
|
||||||
|
MatChip,
|
||||||
|
MatChipSet,
|
||||||
|
MatDialogActions,
|
||||||
|
MatButton,
|
||||||
|
MatDialogClose
|
||||||
|
],
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||||
|
})
|
||||||
|
export class ProjectDialogComponent {
|
||||||
|
project: Projects = inject(MAT_DIALOG_DATA);
|
||||||
|
}
|
||||||
@@ -1,63 +1,54 @@
|
|||||||
<mat-accordion class="project-headers-align">
|
<div class="project-grid">
|
||||||
@for (project of allProjects; track project) {
|
@if (featuredProject(); as project) {
|
||||||
<mat-expansion-panel [expanded]="isExpanded(project.identifier)">
|
<mat-card class="project-card featured">
|
||||||
<mat-expansion-panel-header>
|
<mat-card-header>
|
||||||
<mat-panel-title>{{ project.title | translate }}</mat-panel-title>
|
<mat-card-title>{{ project.title | translate }}</mat-card-title>
|
||||||
<mat-panel-description>
|
<mat-card-subtitle>{{ project.shortDescription | translate }}</mat-card-subtitle>
|
||||||
{{ project.shortDescription | translate}}
|
</mat-card-header>
|
||||||
<mat-icon>{{ project.icon }}</mat-icon>
|
@if(project.images.length > 0) {
|
||||||
</mat-panel-description>
|
<img mat-card-image [src]="project.images[0]" [alt]="project.title | translate">
|
||||||
</mat-expansion-panel-header>
|
} @else {
|
||||||
<p>{{ project.introduction | translate }}</p>
|
<div class="icon-container">
|
||||||
|
<mat-icon class="fallback-icon">{{ project.icon }}</mat-icon>
|
||||||
@if (project.link)
|
|
||||||
{
|
|
||||||
<div class="link-row">
|
|
||||||
<a class="link-with-icon"
|
|
||||||
href="{{project.link}}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer">
|
|
||||||
<mat-icon>open_in_new</mat-icon>
|
|
||||||
{{project.link}}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
<mat-card-content>
|
||||||
@if(project.assets)
|
<p>{{ project.introduction | translate }}</p>
|
||||||
{
|
<mat-chip-set aria-label="Technologies">
|
||||||
<div class="link-row">
|
@for(tech of project.technologies; track tech) {
|
||||||
<a class="link-with-icon"
|
<mat-chip>{{tech}}</mat-chip>
|
||||||
href="{{project.assets}}"
|
|
||||||
rel="noopener noreferrer">
|
|
||||||
<mat-icon>download</mat-icon>
|
|
||||||
{{ 'PROJECTS.DOWNLOAD' | translate}}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (project.images.length > 0)
|
|
||||||
{
|
|
||||||
<swiper-container
|
|
||||||
class="my-swiper"
|
|
||||||
[attr.slides-per-view]="1.2"
|
|
||||||
[attr.space-between]="12"
|
|
||||||
[attr.navigation]="true"
|
|
||||||
[attr.pagination]="true"
|
|
||||||
[attr.keyboard]="true"
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
@for (img of project.images; track img) {
|
|
||||||
<swiper-slide>
|
|
||||||
<img
|
|
||||||
class="slide-img"
|
|
||||||
[src]="img"
|
|
||||||
[alt]="project.title | translate"
|
|
||||||
(click)="openImage(project.title, img)"
|
|
||||||
/>
|
|
||||||
</swiper-slide>
|
|
||||||
}
|
}
|
||||||
</swiper-container>
|
</mat-chip-set>
|
||||||
}
|
</mat-card-content>
|
||||||
</mat-expansion-panel>
|
<mat-card-actions>
|
||||||
|
<button mat-button (click)="openProjectDialog(project)">{{ 'PROJECTS.READ_MORE' | translate }}</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
}
|
}
|
||||||
</mat-accordion>
|
|
||||||
|
@for (project of otherProjects(); track project) {
|
||||||
|
<mat-card class="project-card">
|
||||||
|
<mat-card-header>
|
||||||
|
<mat-card-title>{{ project.title | translate }}</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
@if(project.images.length > 0) {
|
||||||
|
<img mat-card-image [src]="project.images[0]" [alt]="project.title | translate">
|
||||||
|
} @else {
|
||||||
|
<div class="icon-container">
|
||||||
|
<mat-icon class="fallback-icon">{{ project.icon }}</mat-icon>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<mat-card-content>
|
||||||
|
<p>{{ project.shortDescription | translate }}</p>
|
||||||
|
<mat-chip-set aria-label="Technologies">
|
||||||
|
@for(tech of project.technologies; track tech) {
|
||||||
|
<mat-chip>{{tech}}</mat-chip>
|
||||||
|
}
|
||||||
|
</mat-chip-set>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button mat-button (click)="openProjectDialog(project)">{{ 'PROJECTS.READ_MORE' | translate }}</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,40 +1,60 @@
|
|||||||
.project-headers-align .mat-expansion-panel-header-description {
|
.project-grid {
|
||||||
justify-content: space-between;
|
display: grid;
|
||||||
align-items: center;
|
gap: 1.5rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
|
.project-card {
|
||||||
margin-left: 8px;
|
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||||
}
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
.slide-img {
|
|
||||||
width: 100%;
|
&:hover {
|
||||||
height: auto;
|
transform: translateY(-5px);
|
||||||
max-height: 512px !important;
|
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
|
||||||
object-fit: cover;
|
}
|
||||||
border-radius: 12px;
|
|
||||||
display: block;
|
&.featured {
|
||||||
cursor: pointer;
|
grid-column: 1 / -1; // Span full width
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-swiper::part(button-prev),
|
mat-card-header {
|
||||||
.my-swiper::part(button-next) {
|
padding-bottom: 1rem;
|
||||||
width: 35px;
|
}
|
||||||
height: 35px;
|
|
||||||
padding: 5px;
|
mat-card-content {
|
||||||
border-radius: 999px;
|
flex-grow: 1; // Ensure content area expands
|
||||||
background: rgba(0,0,0,.5);
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-chip-set {
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-actions {
|
||||||
|
margin-top: auto; // Push actions to the bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 200px; /* Or a height that fits your design */
|
||||||
|
background-color: #f0f0f0; /* A light background for the icon */
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-swiper::part(button-prev):hover,
|
.fallback-icon {
|
||||||
.my-swiper::part(button-next):hover {
|
font-size: 4rem;
|
||||||
background: rgba(0,0,0,.75);
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-swiper::part(pagination) {
|
// Ensure images don't exceed the card width and maintain aspect ratio
|
||||||
bottom: 12px;
|
img[mat-card-image] {
|
||||||
|
width: 100%;
|
||||||
|
height: 250px;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import {Component, inject, signal, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import {Component, computed, inject, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||||
import {MatAccordion, MatExpansionPanel, MatExpansionPanelDescription, MatExpansionPanelHeader, MatExpansionPanelTitle} from '@angular/material/expansion';
|
import {MatCardModule} from '@angular/material/card';
|
||||||
|
import {MatChipsModule} from '@angular/material/chips';
|
||||||
import {MatIcon} from '@angular/material/icon';
|
import {MatIcon} from '@angular/material/icon';
|
||||||
import {TranslatePipe, TranslateService} from '@ngx-translate/core';
|
import {TranslatePipe, TranslateService} from '@ngx-translate/core';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {AssetsConstants} from '../../constants/AssetsConstants';
|
import {AssetsConstants} from '../../constants/AssetsConstants';
|
||||||
import {MatDialog} from '@angular/material/dialog';
|
import {MatDialog} from '@angular/material/dialog';
|
||||||
import {ImageDialogComponent} from '../../layout/imageDialog/image.component';
|
import {MatButtonModule} from '@angular/material/button';
|
||||||
|
import {ProjectDialogComponent} from './dialog/project-dialog.component';
|
||||||
|
|
||||||
|
|
||||||
export interface Projects {
|
export interface Projects {
|
||||||
@@ -18,18 +20,18 @@ export interface Projects {
|
|||||||
assets: string,
|
assets: string,
|
||||||
link: string,
|
link: string,
|
||||||
bulletPoints: string[],
|
bulletPoints: string[],
|
||||||
|
isFeatured: boolean,
|
||||||
|
technologies: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-projects',
|
selector: 'app-projects',
|
||||||
imports: [
|
imports: [
|
||||||
MatAccordion,
|
MatCardModule,
|
||||||
MatExpansionPanel,
|
MatChipsModule,
|
||||||
MatExpansionPanelHeader,
|
|
||||||
MatExpansionPanelTitle,
|
|
||||||
MatExpansionPanelDescription,
|
|
||||||
MatIcon,
|
MatIcon,
|
||||||
TranslatePipe
|
TranslatePipe,
|
||||||
|
MatButtonModule
|
||||||
],
|
],
|
||||||
templateUrl: './projects.component.html',
|
templateUrl: './projects.component.html',
|
||||||
styleUrl: './projects.component.scss',
|
styleUrl: './projects.component.scss',
|
||||||
@@ -41,8 +43,6 @@ export class ProjectsComponent {
|
|||||||
private readonly dialog = inject(MatDialog);
|
private readonly dialog = inject(MatDialog);
|
||||||
private readonly translateService = inject(TranslateService);
|
private readonly translateService = inject(TranslateService);
|
||||||
|
|
||||||
selectedKey = signal<string | null>(null);
|
|
||||||
|
|
||||||
allProjects: Projects[] = [
|
allProjects: Projects[] = [
|
||||||
{
|
{
|
||||||
identifier: "playground",
|
identifier: "playground",
|
||||||
@@ -53,7 +53,14 @@ export class ProjectsComponent {
|
|||||||
icon: 'web',
|
icon: 'web',
|
||||||
assets: '',
|
assets: '',
|
||||||
link: 'https://andreas-dahm.eu',
|
link: 'https://andreas-dahm.eu',
|
||||||
bulletPoints: []
|
bulletPoints: [
|
||||||
|
'PROJECTS.PLAYGROUND.BULLET_1',
|
||||||
|
'PROJECTS.PLAYGROUND.BULLET_2',
|
||||||
|
'PROJECTS.PLAYGROUND.BULLET_3',
|
||||||
|
'PROJECTS.PLAYGROUND.BULLET_4',
|
||||||
|
],
|
||||||
|
isFeatured: false,
|
||||||
|
technologies: ['Angular', 'TypeScript', 'SCSS', 'HTML', 'GitHub Actions', 'Docker']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: "elmucho",
|
identifier: "elmucho",
|
||||||
@@ -63,8 +70,15 @@ export class ProjectsComponent {
|
|||||||
images: [AssetsConstants.EL_MUCHO_1, AssetsConstants.EL_MUCHO_2, AssetsConstants.EL_MUCHO_3, AssetsConstants.EL_MUCHO_4],
|
images: [AssetsConstants.EL_MUCHO_1, AssetsConstants.EL_MUCHO_2, AssetsConstants.EL_MUCHO_3, AssetsConstants.EL_MUCHO_4],
|
||||||
icon: 'sports_esports',
|
icon: 'sports_esports',
|
||||||
assets: '',
|
assets: '',
|
||||||
link: 'https://store.steampowered.com/app/1532640/El_Mucho/',
|
link: 'https.store.steampowered.com/app/1532640/El_Mucho/',
|
||||||
bulletPoints: []
|
bulletPoints: [
|
||||||
|
'PROJECTS.EL_MUCHO.BULLET_1',
|
||||||
|
'PROJECTS.EL_MUCHO.BULLET_2',
|
||||||
|
'PROJECTS.EL_MUCHO.BULLET_3',
|
||||||
|
'PROJECTS.EL_MUCHO.BULLET_4',
|
||||||
|
],
|
||||||
|
isFeatured: true,
|
||||||
|
technologies: ['Unity', 'C#', 'Steamworks', 'Git']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: "gamejams",
|
identifier: "gamejams",
|
||||||
@@ -74,8 +88,15 @@ export class ProjectsComponent {
|
|||||||
images: [AssetsConstants.GAME_JAMS_1, AssetsConstants.GAME_JAMS_2, AssetsConstants.GAME_JAMS_3],
|
images: [AssetsConstants.GAME_JAMS_1, AssetsConstants.GAME_JAMS_2, AssetsConstants.GAME_JAMS_3],
|
||||||
icon: 'videogame_asset',
|
icon: 'videogame_asset',
|
||||||
assets: '',
|
assets: '',
|
||||||
link: 'https://itch.io/c/6628860/lobos-collection',
|
link: 'https.itch.io/c/6628860/lobos-collection',
|
||||||
bulletPoints: []
|
bulletPoints: [
|
||||||
|
'PROJECTS.GAME_JAMS.BULLET_1',
|
||||||
|
'PROJECTS.GAME_JAMS.BULLET_2',
|
||||||
|
'PROJECTS.GAME_JAMS.BULLET_3',
|
||||||
|
'PROJECTS.GAME_JAMS.BULLET_4',
|
||||||
|
],
|
||||||
|
isFeatured: false,
|
||||||
|
technologies: ['Unity', 'C#', 'Git']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: "diploma",
|
identifier: "diploma",
|
||||||
@@ -85,32 +106,33 @@ export class ProjectsComponent {
|
|||||||
images: [AssetsConstants.DIPLOMA_1, AssetsConstants.DIPLOMA_2, AssetsConstants.DIPLOMA_3, AssetsConstants.DIPLOMA_4, AssetsConstants.DIPLOMA_5, AssetsConstants.DIPLOMA_6],
|
images: [AssetsConstants.DIPLOMA_1, AssetsConstants.DIPLOMA_2, AssetsConstants.DIPLOMA_3, AssetsConstants.DIPLOMA_4, AssetsConstants.DIPLOMA_5, AssetsConstants.DIPLOMA_6],
|
||||||
icon: 'history_edu',
|
icon: 'history_edu',
|
||||||
assets: AssetsConstants.DIPLOMA,
|
assets: AssetsConstants.DIPLOMA,
|
||||||
link: 'https://www.th-bingen.de',
|
link: 'https.www.th-bingen.de',
|
||||||
bulletPoints: []
|
bulletPoints: [
|
||||||
|
'PROJECTS.DIPLOMA.BULLET_1',
|
||||||
|
'PROJECTS.DIPLOMA.BULLET_2',
|
||||||
|
'PROJECTS.DIPLOMA.BULLET_3',
|
||||||
|
'PROJECTS.DIPLOMA.BULLET_4',
|
||||||
|
],
|
||||||
|
isFeatured: false,
|
||||||
|
technologies: ['C++', 'OpenGL', 'Qt', '3D-Scanner']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
featuredProject = computed(() => this.allProjects.find(p => p.isFeatured));
|
||||||
|
otherProjects = computed(() => this.allProjects.filter(p => !p.isFeatured));
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.route.queryParamMap.subscribe(params => {
|
this.route.queryParamMap.subscribe(params => {
|
||||||
this.selectedKey.set(params.get('project'));
|
// this.selectedKey.set(params.get('project'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
isExpanded(projectKey: string): boolean {
|
openProjectDialog(project: Projects) {
|
||||||
return this.selectedKey() === projectKey;
|
this.dialog.open(ProjectDialogComponent, {
|
||||||
}
|
data: project,
|
||||||
|
width: '90vw',
|
||||||
openImage(title: string, src: string) {
|
maxWidth: '900px',
|
||||||
const translatedTitle = this.translateService.instant(title);
|
});
|
||||||
this.dialog.open(ImageDialogComponent, {
|
|
||||||
data: { title: translatedTitle, src },
|
|
||||||
width: '96vw',
|
|
||||||
height: '96vh',
|
|
||||||
maxWidth: '96vw',
|
|
||||||
maxHeight: '96vh',
|
|
||||||
panelClass: 'image-dialog-panel',
|
|
||||||
autoFocus: false,
|
|
||||||
restoreFocus: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,25 +228,44 @@
|
|||||||
},
|
},
|
||||||
"PROJECTS": {
|
"PROJECTS": {
|
||||||
"DOWNLOAD": "Herunterladen",
|
"DOWNLOAD": "Herunterladen",
|
||||||
|
"READ_MORE": "Mehr erfahren",
|
||||||
|
"LINK_TO_PROJECT": "Zum Projekt",
|
||||||
|
"CLOSE": "Schließen",
|
||||||
"PLAYGROUND": {
|
"PLAYGROUND": {
|
||||||
"TITLE": "Playground Website",
|
"TITLE": "Playground Website",
|
||||||
"SHORT_DESCRIPTION": "Hier geht es um diese Webseite.",
|
"SHORT_DESCRIPTION": "Hier geht es um diese Webseite.",
|
||||||
"INTRODUCTION": "Dieses Projekt ist hauptsächlich als eine Art 'Spielwiese' gestartet, daher der Name. Es ist geplant, die Seite mit der Zeit weiter auszubauen. Dabei werden hier neue Projekte auftauchen, oder ich werde die Seite an für sich weiter ausbauen, weil ich neue Sachen im Rahmen von Web Technologien ausprobieren möchte."
|
"INTRODUCTION": "Dieses Projekt ist hauptsächlich als eine Art 'Spielwiese' gestartet, daher der Name. Es ist geplant, die Seite mit der Zeit weiter auszubauen. Dabei werden hier neue Projekte auftauchen, oder ich werde die Seite an für sich weiter ausbauen, weil ich neue Sachen im Rahmen von Web Technologien ausprobieren möchte.",
|
||||||
|
"BULLET_1": "Verwendung moderner Technologien und CI/CD-Pipelines (Angular 20+, Spring Boot 4, GitHub).",
|
||||||
|
"BULLET_2": "Präsentation persönlicher Projekte und kontinuierliche Verbesserung algorithmischer Fähigkeiten.",
|
||||||
|
"BULLET_3": "Vertiefung von JavaScript/TypeScript-, Angular- und Spring-Boot-Kenntnissen durch praktisches Arbeiten.",
|
||||||
|
"BULLET_4": "Die Seite ist Open Source und auf GitHub verfügbar."
|
||||||
},
|
},
|
||||||
"EL_MUCHO": {
|
"EL_MUCHO": {
|
||||||
"TITLE": "El Mucho",
|
"TITLE": "El Mucho",
|
||||||
"SHORT_DESCRIPTION": "Hier geht es um mein ersten Spiel auf Steam.",
|
"SHORT_DESCRIPTION": "Hier geht es um mein ersten Spiel auf Steam.",
|
||||||
"INTRODUCTION": "El Mucho ist ein rundenbasiertes taktisches RPG in einer fiktiven Welt namens Liberika. Es ist angelehnt an alte Klassiker wie Langrisser aka Warsong. In El Mucho geht es darum, die Welt gegen die Angriffe der fiesen Monster zu verteidigen."
|
"INTRODUCTION": "El Mucho ist ein rundenbasiertes taktisches RPG in einer fiktiven Welt namens Liberika. Es ist angelehnt an alte Klassiker wie Langrisser aka Warsong. In El Mucho geht es darum, die Welt gegen die Angriffe der fiesen Monster zu verteidigen.",
|
||||||
|
"BULLET_1": "Veröffentlichung eines Spiels auf Steam und Integration der Steam-API.",
|
||||||
|
"BULLET_2": "Konzeption, Planung und vollständige Entwicklung eines eigenen Spiels.",
|
||||||
|
"BULLET_3": "Implementierung komplexer Algorithmen wie einer eigenen A*-Pfadfindungslogik und Spiel-KI.",
|
||||||
|
"BULLET_4": "Das Spiel wurde mit Unity und C# entwickelt."
|
||||||
},
|
},
|
||||||
"GAME_JAMS": {
|
"GAME_JAMS": {
|
||||||
"TITLE": "Game Jams",
|
"TITLE": "Game Jams",
|
||||||
"SHORT_DESCRIPTION": "Hier geht es meine Teilnahme an mehreren Game Jams.",
|
"SHORT_DESCRIPTION": "Hier geht es meine Teilnahme an mehreren Game Jams.",
|
||||||
"INTRODUCTION": "Da ich mich für die Entwicklung von Spielen interessiert, sind Game Jams für mich optimal, um fokussiert an neuen Ideen zu arbeiten und dabei Prototypen zu entwickeln, um zu sehen, ob Spielideen funktionieren oder nicht. In den letzten Jahren habe ich an einigen Game Jams teilgenommen und fasse das hier zusammen."
|
"INTRODUCTION": "Da ich mich für die Entwicklung von Spielen interessiert, sind Game Jams für mich optimal, um fokussiert an neuen Ideen zu arbeiten und dabei Prototypen zu entwickeln, um zu sehen, ob Spielideen funktionieren oder nicht. In den letzten Jahren habe ich an einigen Game Jams teilgenommen und fasse das hier zusammen.",
|
||||||
|
"BULLET_1": "Planung eines realistischen Projektumfangs mit einem Team, der innerhalb von 48 Stunden umsetzbar ist.",
|
||||||
|
"BULLET_2": "Lernen, fokussiert und effizient unter strengen Zeitvorgaben zu arbeiten.",
|
||||||
|
"BULLET_3": "Die Freude zu erleben, in kurzer Zeit ein spielbares Projekt zu erstellen und andere damit spielen zu sehen.",
|
||||||
|
"BULLET_4": "Alle Projekte sind auf Itch.io verfügbar und spielbar."
|
||||||
},
|
},
|
||||||
"DIPLOMA": {
|
"DIPLOMA": {
|
||||||
"TITLE": "Diplomarbeit",
|
"TITLE": "Diplomarbeit",
|
||||||
"SHORT_DESCRIPTION": "Kollisionserkennung und Behandlung von komplexen Kleidungsstücken.",
|
"SHORT_DESCRIPTION": "Kollisionserkennung und Behandlung von komplexen Kleidungsstücken.",
|
||||||
"INTRODUCTION": "Die Diplomarbeit handelt von der Erkennung und der Behandlung von Kollisionen zwischen, sowie innerhalb, einzelnen Kleidungsstücken in Echtzeit. Das ist gerade aufgrund der Flexibilität von Stoffen und deren unterschiedlichen Eigenschaften besonders herausfordernd."
|
"INTRODUCTION": "Die Diplomarbeit handelt von der Erkennung und der Behandlung von Kollisionen zwischen, sowie innerhalb, einzelnen Kleidungsstücken in Echtzeit. Das ist gerade aufgrund der Flexibilität von Stoffen und deren unterschiedlichen Eigenschaften besonders herausfordernd.",
|
||||||
|
"BULLET_1": "Echtzeit behandlung von Kollisionserkennung und Behandlung.",
|
||||||
|
"BULLET_2": "Verstehen und Einschätzen von wissenschaftlichen Arbeiten.",
|
||||||
|
"BULLET_3": "Adaption und Weiterentwicklung von vorausgegangenen Forschungsarbeiten.",
|
||||||
|
"BULLET_4": "Die Arbeit wurde mit C++ und OpenGL geschrieben und in die Vidya-Software integriert."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IMPRINT": {
|
"IMPRINT": {
|
||||||
|
|||||||
@@ -228,25 +228,44 @@
|
|||||||
},
|
},
|
||||||
"PROJECTS": {
|
"PROJECTS": {
|
||||||
"DOWNLOAD": "Download",
|
"DOWNLOAD": "Download",
|
||||||
|
"READ_MORE": "Read More",
|
||||||
|
"LINK_TO_PROJECT": "To the project",
|
||||||
|
"CLOSE": "Close",
|
||||||
"PLAYGROUND": {
|
"PLAYGROUND": {
|
||||||
"TITLE": "Playground Website",
|
"TITLE": "Playground Website",
|
||||||
"SHORT_DESCRIPTION": "This is about this website.",
|
"SHORT_DESCRIPTION": "This is about this website.",
|
||||||
"INTRODUCTION": "This project was mainly started as a kind of “playground”, hence the name. The plan is to expand the site over time. New projects will appear here, or I will continue to expand the site itself because I want to try out new things in the field of web technologies."
|
"INTRODUCTION": "This project was mainly started as a kind of “playground”, hence the name. The plan is to expand the site over time. New projects will appear here, or I will continue to expand the site itself because I want to try out new things in the field of web technologies.",
|
||||||
|
"BULLET_1": "Using modern technologies and CI/CD pipelines (Angular 20+, Spring Boot 4, GitHub).",
|
||||||
|
"BULLET_2": "Showcasing personal projects and improving algorithmic skills over time.",
|
||||||
|
"BULLET_3": "Deepening knowledge in JavaScript/TypeScript, Angular, Spring Boot and related technologies through hands-on practice.",
|
||||||
|
"BULLET_4": "The site is open source and available on GitHub."
|
||||||
},
|
},
|
||||||
"EL_MUCHO": {
|
"EL_MUCHO": {
|
||||||
"TITLE": "El Mucho",
|
"TITLE": "El Mucho",
|
||||||
"SHORT_DESCRIPTION": "This is about my first game on steam.",
|
"SHORT_DESCRIPTION": "This is about my first game on steam.",
|
||||||
"INTRODUCTION": "El Mucho is a turn-based tactical RPG set in a fictional world called Liberika. It is inspired by old classics such as Langrisser, also known as Warsong. El Mucho is about defending the world against attacks from nasty monsters."
|
"INTRODUCTION": "El Mucho is a turn-based tactical RPG set in a fictional world called Liberika. It is inspired by old classics such as Langrisser, also known as Warsong. El Mucho is about defending the world against attacks from nasty monsters.",
|
||||||
|
"BULLET_1": "Publishing a game on Steam and integrating the Steam API.",
|
||||||
|
"BULLET_2": "Designing, planning and developing a complete game from scratch.",
|
||||||
|
"BULLET_3": "Implementing complex algorithms, including a custom A* pathfinding system and game AI logic.",
|
||||||
|
"BULLET_4": "The game was developed with Unity and C#."
|
||||||
},
|
},
|
||||||
"GAME_JAMS": {
|
"GAME_JAMS": {
|
||||||
"TITLE": "Game Jams",
|
"TITLE": "Game Jams",
|
||||||
"SHORT_DESCRIPTION": "This is about my participation at several game jams.",
|
"SHORT_DESCRIPTION": "This is about my participation at several game jams.",
|
||||||
"INTRODUCTION": "Since I am interested in game development, game jams are ideal for me to focus on new ideas and develop prototypes to see whether game ideas work or not. I have participated in several game jams over the past few years and summarise my experiences here."
|
"INTRODUCTION": "Since I am interested in game development, game jams are ideal for me to focus on new ideas and develop prototypes to see whether game ideas work or not. I have participated in several game jams over the past few years and summarise my experiences here.",
|
||||||
|
"BULLET_1": "Planning a realistic project scope with a team that can be built within 48 hours.",
|
||||||
|
"BULLET_2": "Learning to stay focused and work effectively under strict time constraints.",
|
||||||
|
"BULLET_3": "Experiencing the joy of creating a playable game in a short timeframe and seeing others enjoy it.",
|
||||||
|
"BULLET_4": "All projects are available and playable on Itch.io."
|
||||||
},
|
},
|
||||||
"DIPLOMA": {
|
"DIPLOMA": {
|
||||||
"TITLE": "Diploma thesis",
|
"TITLE": "Diploma thesis",
|
||||||
"SHORT_DESCRIPTION": "Collision detection and handling of complex garments.",
|
"SHORT_DESCRIPTION": "Collision detection and handling of complex garments.",
|
||||||
"INTRODUCTION": "The thesis deals with the detection and handling of collisions between and within individual items of clothing in real time. This is particularly challenging due to the flexibility of fabrics and their varying properties."
|
"INTRODUCTION": "The thesis deals with the detection and handling of collisions between and within individual items of clothing in real time. This is particularly challenging due to the flexibility of fabrics and their varying properties.",
|
||||||
|
"BULLET_1": "Real-time handling of collision detection and response.",
|
||||||
|
"BULLET_2": "Understanding and evaluating scientific papers.",
|
||||||
|
"BULLET_3": "Adaptation and further development of previous research work.",
|
||||||
|
"BULLET_4": "The thesis was written with C++ and OpenGL and integrated into the Vidya software."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"IMPRINT": {
|
"IMPRINT": {
|
||||||
|
|||||||
Reference in New Issue
Block a user