Add particle type selection, size control, and enhance particle property handling
This commit is contained in:
parent
1e5862bae6
commit
d4363b3a8a
|
|
@ -1,12 +1,36 @@
|
|||
<div class="card-div">
|
||||
<mat-card class="color-picker-card">
|
||||
<mat-card class="particle-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Particle Color</mat-card-title>
|
||||
<mat-card-title>Particle Properties</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="color-picker">
|
||||
<input type="color" [(ngModel)]="selectedColor">
|
||||
<span>Selected Color: {{ selectedColor }}</span>
|
||||
<div class="particle-properties">
|
||||
<div class="property-row">
|
||||
<div class="color-picker">
|
||||
<input type="color" [(ngModel)]="selectedColor">
|
||||
<span>Current color: {{ selectedColor }}</span>
|
||||
</div>
|
||||
<mat-form-field appearance="fill" class="type-field">
|
||||
<mat-label>Select Particle Type</mat-label>
|
||||
<input type="text"
|
||||
placeholder="Search for a particle type"
|
||||
matInput
|
||||
[formControl]="particleTypeControl"
|
||||
[matAutocomplete]="auto">
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
|
||||
<mat-option *ngFor="let type of filteredParticleTypes | async" [value]="type">
|
||||
{{ type }}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="size-slider">
|
||||
<mat-slider min="0.1" max="4" step="0.1" class="full-width">
|
||||
<input matSliderThumb [(ngModel)]="selectedSize">
|
||||
</mat-slider>
|
||||
<span>Size: {{ selectedSize }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,37 @@
|
|||
.color-picker-card {
|
||||
.particle-card {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.particle-properties {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.property-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.type-field {
|
||||
flex: 1;
|
||||
min-width: 20ch;
|
||||
max-width: 40ch;
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.color-picker input[type="color"] {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
|
@ -23,6 +44,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.size-slider {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--font-color);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,16 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {ParticleManagerService} from '../../services/particle-manager.service';
|
||||
import {Particle} from '../../models/particle.model';
|
||||
import {MatSliderModule} from '@angular/material/slider';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatAutocompleteModule} from '@angular/material/autocomplete';
|
||||
import {Observable} from 'rxjs';
|
||||
import {map, startWith} from 'rxjs/operators';
|
||||
import {AsyncPipe, NgForOf} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-particle',
|
||||
|
|
@ -11,16 +20,55 @@ import {ParticleManagerService} from '../../services/particle-manager.service';
|
|||
MatCardHeader,
|
||||
MatCardTitle,
|
||||
ReactiveFormsModule,
|
||||
FormsModule
|
||||
FormsModule,
|
||||
MatSliderModule,
|
||||
MatSelectModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatAutocompleteModule,
|
||||
NgForOf,
|
||||
AsyncPipe
|
||||
],
|
||||
templateUrl: './particle.component.html',
|
||||
styleUrl: './particle.component.scss'
|
||||
})
|
||||
export class ParticleComponent {
|
||||
export class ParticleComponent implements OnInit {
|
||||
// Available particle types from the enum
|
||||
particleTypes = Object.values(Particle);
|
||||
|
||||
// Form control for the particle type dropdown with filtering
|
||||
particleTypeControl = new FormControl();
|
||||
filteredParticleTypes: Observable<string[]>;
|
||||
|
||||
constructor(
|
||||
private particleManagerService: ParticleManagerService,
|
||||
) {
|
||||
this.filteredParticleTypes = this.particleTypeControl.valueChanges.pipe(
|
||||
startWith(''),
|
||||
map(value => this._filterParticleTypes(value || ''))
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// Initialize the particle type control with the current value
|
||||
this.particleTypeControl.setValue(this.selectedParticle);
|
||||
|
||||
// Update the selected particle when the control value changes
|
||||
this.particleTypeControl.valueChanges.subscribe(value => {
|
||||
if (value && Object.values(Particle).includes(value)) {
|
||||
this.selectedParticle = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _filterParticleTypes(value: string): string[] {
|
||||
const filterValue = value.toLowerCase();
|
||||
return this.particleTypes.filter(type => type.toLowerCase().includes(filterValue));
|
||||
}
|
||||
|
||||
// Display function for the autocomplete
|
||||
displayFn(particle: string): string {
|
||||
return particle ? particle : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,4 +85,31 @@ export class ParticleComponent {
|
|||
this.particleManagerService.setSelectedColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected particle type
|
||||
*/
|
||||
public get selectedParticle(): Particle {
|
||||
return this.particleManagerService.particle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected particle type
|
||||
*/
|
||||
public set selectedParticle(particle: Particle) {
|
||||
this.particleManagerService.particle = particle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected particle size
|
||||
*/
|
||||
public get selectedSize(): number {
|
||||
return this.particleManagerService.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected particle size
|
||||
*/
|
||||
public set selectedSize(size: number) {
|
||||
this.particleManagerService.size = size;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export class ParticleManagerService {
|
|||
*/
|
||||
addParticle(x: number, y: number, z: number): void {
|
||||
// Create a visual representation of the particle
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03, 16, 16);
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03 * this.selectedSize, 16, 16);
|
||||
const particleMaterial = new THREE.MeshBasicMaterial({color: this.selectedColor});
|
||||
const particleMesh = new THREE.Mesh(particleGeometry, particleMaterial);
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ export class ParticleManagerService {
|
|||
if (!this.particleData.frames[frameId]) return;
|
||||
|
||||
for (const particleInfo of this.particleData.frames[frameId]) {
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03, 16, 16);
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03 * (particleInfo.size ?? 1), 16, 16);
|
||||
|
||||
const color = this.getColor(particleInfo);
|
||||
const particleMaterial = new THREE.MeshBasicMaterial({color});
|
||||
|
|
@ -123,7 +123,7 @@ export class ParticleManagerService {
|
|||
const particleInfo = this.particleData.frames[frameId][index];
|
||||
const color = this.getColor(particleInfo);
|
||||
const particleMaterial = new THREE.MeshBasicMaterial({color});
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03, 16, 16);
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03 * (particleInfo.size ?? 1), 16, 16);
|
||||
const particleMesh = new THREE.Mesh(particleGeometry, particleMaterial);
|
||||
particleMesh.position.set(particleInfo.x, particleInfo.y, particleInfo.z);
|
||||
this.rendererService.scene.add(particleMesh);
|
||||
|
|
@ -135,17 +135,6 @@ export class ParticleManagerService {
|
|||
});
|
||||
}
|
||||
|
||||
private getColor(particleInfo: ParticleInfo) {
|
||||
if (particleInfo.color) {
|
||||
const r = parseInt(particleInfo.color.substring(0, 2), 16) / 255;
|
||||
const g = parseInt(particleInfo.color.substring(2, 4), 16) / 255;
|
||||
const b = parseInt(particleInfo.color.substring(4, 6), 16) / 255;
|
||||
return new THREE.Color(r, g, b);
|
||||
} else {
|
||||
return new THREE.Color(255, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private animatePulse(mesh: THREE.Mesh, cycles: number, onComplete: () => void): void {
|
||||
const duration = 300;
|
||||
const maxScale = 0.08 / 0.03;
|
||||
|
|
@ -167,6 +156,17 @@ export class ParticleManagerService {
|
|||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
private getColor(particleInfo: ParticleInfo) {
|
||||
if (particleInfo.color) {
|
||||
const r = parseInt(particleInfo.color.substring(0, 2), 16) / 255;
|
||||
const g = parseInt(particleInfo.color.substring(2, 4), 16) / 255;
|
||||
const b = parseInt(particleInfo.color.substring(4, 6), 16) / 255;
|
||||
return new THREE.Color(r, g, b);
|
||||
} else {
|
||||
return new THREE.Color(255, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected color for new particles
|
||||
*/
|
||||
|
|
@ -181,6 +181,22 @@ export class ParticleManagerService {
|
|||
return this.selectedColor;
|
||||
}
|
||||
|
||||
public get particle(): Particle {
|
||||
return this.selectedParticle;
|
||||
}
|
||||
|
||||
public set particle(selectedParticle: Particle) {
|
||||
this.selectedParticle = selectedParticle;
|
||||
}
|
||||
|
||||
public get size(): number {
|
||||
return this.selectedSize;
|
||||
}
|
||||
|
||||
public set size(selectedSize: number) {
|
||||
this.selectedSize = selectedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the particle data
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user