106 lines
2.4 KiB
TypeScript
106 lines
2.4 KiB
TypeScript
import {AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
|
|
import {getEvents} from "./decode-replay";
|
|
import {DecimalPipe, JsonPipe, NgForOf} from "@angular/common";
|
|
import {ReplayService} from "./replay-service";
|
|
import {FormsModule} from "@angular/forms";
|
|
import {parseHitObjects} from "./decode-beatmap";
|
|
import {processReplay} from "./process-replay";
|
|
import {ReplayViewerData} from "../../../app/replays";
|
|
|
|
export enum KeyPress {
|
|
M1 = 1,
|
|
M2 = 2,
|
|
K1 = 5,
|
|
K2 = 10,
|
|
Smoke = 16,
|
|
}
|
|
|
|
export interface ReplayEvent {
|
|
/**
|
|
* Time in milliseconds since the previous action
|
|
*/
|
|
timeDelta: number;
|
|
|
|
/**
|
|
* x-coordinate of the cursor from 0 - 512
|
|
*/
|
|
x: number;
|
|
|
|
/**
|
|
* y-coordinate of the cursor from 0 - 384
|
|
*/
|
|
y: number;
|
|
|
|
/**
|
|
* Keys being pressed.
|
|
*/
|
|
keys: KeyPress[];
|
|
|
|
}
|
|
|
|
@Component({
|
|
selector: 'app-replay-viewer',
|
|
standalone: true,
|
|
imports: [
|
|
JsonPipe,
|
|
FormsModule,
|
|
DecimalPipe,
|
|
NgForOf
|
|
],
|
|
templateUrl: './replay-viewer.component.html',
|
|
styleUrl: './replay-viewer.component.css'
|
|
})
|
|
export class ReplayViewerComponent implements OnInit, AfterViewInit {
|
|
|
|
@ViewChild('replayCanvas') replayCanvas!: ElementRef<HTMLCanvasElement>;
|
|
private ctx!: CanvasRenderingContext2D;
|
|
|
|
@Input() replayViewerData!: ReplayViewerData;
|
|
|
|
// TODO: Calculate AudioLeadIn
|
|
// TODO: Hard-Rock, DT, Easy
|
|
|
|
// TODO: Cursor trail and where keys are pressed
|
|
// TODO: Button for -100 ms, +100 ms, etc (precise seeking) (or keyboard shortcuts)
|
|
|
|
// TODO: UR bar
|
|
// Todo: Customizable speed
|
|
// TODO: Customizable zoom
|
|
// TODO: Fullscreen mode
|
|
|
|
// TODO: Hit/Miss, Combo, Accuracy
|
|
|
|
// TODO: Compare two replays for similarity (different cursor color)
|
|
|
|
constructor(public replayService: ReplayService) { }
|
|
|
|
ngOnInit() {
|
|
this.replayService.loadReplay(this.replayViewerData);
|
|
}
|
|
|
|
ngAfterViewInit() {
|
|
this.ctx = this.replayCanvas.nativeElement.getContext('2d')!;
|
|
|
|
this.replayService.setCanvasElement(this.replayCanvas);
|
|
this.replayService.setCanvasContext(this.ctx);
|
|
|
|
this.replayService.start(); // Start the animation loop
|
|
}
|
|
|
|
togglePlayPause() {
|
|
if (this.replayService.getIsPlaying()) {
|
|
this.replayService.pause();
|
|
} else {
|
|
this.replayService.start();
|
|
}
|
|
}
|
|
|
|
seek(time: number) {
|
|
this.replayService.seek(time);
|
|
if (!this.replayService.getIsPlaying()) {
|
|
// Redraw the canvas for the new current time without resuming playback
|
|
}
|
|
}
|
|
|
|
}
|