159 lines
4.2 KiB
TypeScript
159 lines
4.2 KiB
TypeScript
// src/app/training.component.ts
|
|
import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core';
|
|
import { Deck, DeckImage, DeckService, Box } from '../deck.service';
|
|
import { CommonModule } from '@angular/common';
|
|
import { switchMap } from 'rxjs/operators';
|
|
import { forkJoin } from 'rxjs';
|
|
|
|
@Component({
|
|
selector: 'app-training',
|
|
templateUrl: './training.component.html',
|
|
standalone: true,
|
|
imports: [CommonModule]
|
|
})
|
|
export class TrainingComponent implements OnInit {
|
|
@Input() deck!: Deck;
|
|
@Output() close = new EventEmitter<void>();
|
|
|
|
@ViewChild('canvas') canvasRef!: ElementRef<HTMLCanvasElement>;
|
|
|
|
currentImageIndex: number = 0;
|
|
currentImageData: DeckImage | null = null;
|
|
currentBoxIndex: number = 0;
|
|
boxes: Box[] = [];
|
|
boxRevealed: boolean[] = [];
|
|
|
|
knownCount: number = 0;
|
|
unknownCount: number = 0;
|
|
|
|
isShowingBox: boolean = false;
|
|
isTrainingFinished: boolean = false;
|
|
|
|
constructor(private deckService: DeckService) { }
|
|
|
|
ngOnInit(): void {
|
|
if (this.deck && this.deck.images.length > 0) {
|
|
this.loadImage(this.currentImageIndex);
|
|
} else {
|
|
alert('Kein Deck oder keine Bilder vorhanden.');
|
|
this.close.emit();
|
|
}
|
|
}
|
|
|
|
loadImage(imageIndex: number): void {
|
|
if (imageIndex >= this.deck.images.length) {
|
|
this.endTraining();
|
|
return;
|
|
}
|
|
|
|
const imageName = this.deck.images[imageIndex].name;
|
|
this.deckService.getImage(imageName).subscribe({
|
|
next: (imageData: DeckImage) => {
|
|
this.currentImageData = imageData;
|
|
this.boxes = imageData.boxes;
|
|
this.boxRevealed = new Array(this.boxes.length).fill(false);
|
|
this.currentBoxIndex = 0;
|
|
this.isShowingBox = false;
|
|
this.drawCanvas();
|
|
},
|
|
error: (err) => {
|
|
console.error('Fehler beim Laden des Bildes:', err);
|
|
alert('Fehler beim Laden des Bildes.');
|
|
this.close.emit();
|
|
}
|
|
});
|
|
}
|
|
|
|
drawCanvas(): void {
|
|
const canvas = this.canvasRef.nativeElement;
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx || !this.currentImageData) return;
|
|
|
|
const img = new Image();
|
|
img.src = `/api/debug_image/${this.currentImageData.name}`;
|
|
img.onload = () => {
|
|
// Set canvas size to image size
|
|
canvas.width = img.width;
|
|
canvas.height = img.height;
|
|
|
|
// Draw image
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
|
|
// Draw boxes
|
|
this.boxes.forEach((box, index) => {
|
|
if (this.boxRevealed[index]) {
|
|
// Box ist bereits enthüllt, nichts zeichnen
|
|
return;
|
|
}
|
|
|
|
ctx.beginPath();
|
|
ctx.rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
|
|
ctx.fillStyle = index === this.currentBoxIndex ? 'rgba(0, 255, 0, 0.99)' : 'rgba(255, 0, 0, 0.99)';
|
|
ctx.fill();
|
|
ctx.lineWidth = 2;
|
|
ctx.strokeStyle = 'black';
|
|
ctx.stroke();
|
|
});
|
|
};
|
|
|
|
img.onerror = () => {
|
|
console.error('Fehler beim Laden des Bildes für Canvas.');
|
|
alert('Fehler beim Laden des Bildes für Canvas.');
|
|
this.close.emit();
|
|
};
|
|
}
|
|
|
|
showText(): void {
|
|
if (this.currentBoxIndex >= this.boxes.length) return;
|
|
this.boxRevealed[this.currentBoxIndex] = true;
|
|
this.isShowingBox = true;
|
|
this.drawCanvas();
|
|
}
|
|
|
|
markKnown(): void {
|
|
this.knownCount++;
|
|
this.nextBox();
|
|
}
|
|
|
|
markUnknown(): void {
|
|
this.unknownCount++;
|
|
this.nextBox();
|
|
}
|
|
|
|
nextBox(): void {
|
|
this.currentBoxIndex++;
|
|
this.isShowingBox = false;
|
|
|
|
if (this.currentBoxIndex >= this.boxes.length) {
|
|
// Alle Boxen für dieses Bild sind bearbeitet
|
|
this.nextImage();
|
|
} else {
|
|
// Aktualisiere die Farben der Boxen
|
|
this.drawCanvas();
|
|
}
|
|
}
|
|
|
|
nextImage(): void {
|
|
this.currentImageIndex++;
|
|
this.loadImage(this.currentImageIndex);
|
|
}
|
|
|
|
endTraining(): void {
|
|
this.isTrainingFinished = true;
|
|
alert(`Training beendet!\nGewusst: ${this.knownCount}\nNicht gewusst: ${this.unknownCount}`);
|
|
this.close.emit();
|
|
}
|
|
|
|
closeTraining(): void {
|
|
if (confirm('Möchtest du das Training wirklich beenden?')) {
|
|
this.close.emit();
|
|
}
|
|
}
|
|
|
|
get progress(): string {
|
|
return `Bild ${this.currentImageIndex + 1} von ${this.deck.images.length}`;
|
|
}
|
|
}
|
|
|