AltitudeWeb/frontend/src/app/pages/particles/particles.component.ts

131 lines
4.0 KiB
TypeScript

import {Component, ElementRef, ViewChild} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelectModule} from '@angular/material/select';
import {MatSliderModule} from '@angular/material/slider';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatTabsModule} from '@angular/material/tabs';
import {MatCardModule} from '@angular/material/card';
import {MatIconModule} from '@angular/material/icon';
import {HeaderComponent} from '@header/header.component';
// Services
import {IntersectionPlaneService} from './services/intersection-plane.service';
import {ParticleManagerService} from './services/particle-manager.service';
// Models
import {PropertiesComponent} from './components/properties/properties.component';
import {ParticleComponent} from './components/particle/particle.component';
import {FramesComponent} from './components/frames/frames.component';
import {MatSnackBar} from '@angular/material/snack-bar';
import {RenderContainerComponent} from './components/render-container/render-container.component';
import {ParticlesService} from '@api';
@Component({
selector: 'app-particles',
standalone: true,
imports: [
FormsModule,
ReactiveFormsModule,
MatButtonModule,
MatInputModule,
MatFormFieldModule,
MatSelectModule,
MatSliderModule,
MatCheckboxModule,
MatTabsModule,
MatCardModule,
MatIconModule,
HeaderComponent,
PropertiesComponent,
ParticleComponent,
FramesComponent,
RenderContainerComponent
],
templateUrl: './particles.component.html',
styleUrl: './particles.component.scss'
})
export class ParticlesComponent {
@ViewChild('planeSlider') planeSlider!: ElementRef;
constructor(
private intersectionPlaneService: IntersectionPlaneService,
private particleManagerService: ParticleManagerService,
private matSnackBar: MatSnackBar,
private particlesService: ParticlesService,
) {
}
/**
* Update plane position based on slider
*/
public updatePlanePosition(event: Event): void {
const slider = event.target as HTMLInputElement;
const value = Number(slider.value);
this.intersectionPlaneService.updatePlanePosition(value);
}
/**
* Get the current plane position
*/
public get planePosition(): number {
return this.intersectionPlaneService.getPlanePosition();
}
public set planePosition(newPlanePosition: number) {
this.intersectionPlaneService.updatePlanePosition(newPlanePosition);
}
public get maxOffset(): number {
return this.intersectionPlaneService.getMaxOffset();
}
public get minOffset(): number {
return this.intersectionPlaneService.getMinOffset();
}
/**
* Generate JSON output
*/
public generateJson(): string {
return this.particleManagerService.generateJson();
}
public getJsonFile(): Blob {
const jsonContent = this.generateJson();
return new Blob([jsonContent], {type: 'application/json'});
}
public saveJsonToFile(): void {
const jsonContent = this.generateJson();
const blob = new Blob([jsonContent], {type: 'application/json'});
const url = window.URL.createObjectURL(blob);
// Create a temporary link element
const a = document.createElement('a');
a.href = url;
a.download = 'particle-data.json';
// Append to the document, click it, and remove it
document.body.appendChild(a);
a.click();
// Clean up
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
this.matSnackBar.open('JSON file downloaded', '', {duration: 2000});
}
public copyJson() {
navigator.clipboard.writeText(this.generateJson()).then(() => {
this.matSnackBar.open('Copied to clipboard', '', {duration: 2000})
});
//TODO validation
this.particlesService.saveFile(this.particleManagerService.getParticleData().particle_name, this.getJsonFile());
}
}