BachelorarbeitUmfrage/src/app/components/test-suite/assessments/spatial-position-assessment/spatial-position-assessment...

109 lines
2.9 KiB
TypeScript

import {
Component,
AfterViewInit,
OnDestroy,
ViewChild,
ElementRef,
ChangeDetectorRef,
CUSTOM_ELEMENTS_SCHEMA,
EventEmitter,
Output,
inject
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { MetricsTrackerService } from '../../../../services/metrics-tracker.service';
import '../../../../../assets/scripts/model-viewer';
@Component({
selector: 'app-spatial-position-assessment',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './spatial-position-assessment.component.html',
styleUrls: ['./spatial-position-assessment.component.css'],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class SpatialPositionAssessmentComponent implements AfterViewInit {
@ViewChild('modelViewer') modelViewerRef!: ElementRef<any>;
@Output() testComplete = new EventEmitter<void>();
@Output() redoTest = new EventEmitter<number>();
private metricsService = inject(MetricsTrackerService);
public scale = 1;
public verticalOffset = 0;
protected isModelPlaced = false;
private initialArAnchor: { x: number; y: number; z: number } | null = null;
constructor(private cdr: ChangeDetectorRef) {
this.logInteraction = this.logInteraction.bind(this);
}
ngAfterViewInit() {
const mv = this.modelViewerRef.nativeElement;
mv.addEventListener('ar-status', (e: any) => {
if (e.detail.status === 'session-started') {
setTimeout(() => this.captureAnchor(), 500);
this.metricsService.startTracking(mv);
}
});
}
public logInteraction(event: Event) {
this.metricsService.logInteraction(event);
}
private async captureAnchor() {
const mv = this.modelViewerRef.nativeElement;
const anchor = mv.getAnchor();
if (!anchor.includes('not placed')) {
const [x, y, z] = anchor.split(' ').map(parseFloat);
this.initialArAnchor = { x, y, z };
this.isModelPlaced = true;
this.cdr.detectChanges();
} else {
setTimeout(() => this.captureAnchor(), 500);
}
}
onSliderInput() {
if (!this.initialArAnchor) return;
const { x, y, z } = this.initialArAnchor!;
const newY = y + this.verticalOffset;
this.modelViewerRef.nativeElement.setAttribute('ar-anchor', `${x} ${newY} ${z}`);
}
resetPosition() {
this.scale = 1;
this.verticalOffset = 0;
this.onSliderInput();
}
confirmPlacement() {
const finalPlacement = {
finalScale: this.scale,
finalVerticalOffset: this.verticalOffset,
initialAnchor: this.initialArAnchor,
finalAnchor: this.modelViewerRef.nativeElement.getAttribute('ar-anchor')
};
this.metricsService.logInteraction(new CustomEvent('test-results', {
detail: {
testName: 'SpatialPositionAssessment',
results: finalPlacement
}
}));
console.log('Spatial position results captured locally.');
this.testComplete.emit();
}
retryCurrent() {
this.redoTest.emit(1);
}
}