Add an option to highlight particles
This commit is contained in:
parent
fdb57289f8
commit
c3a7be82e9
|
|
@ -11,11 +11,16 @@
|
|||
<h3>Particles in {{ frameId }}</h3>
|
||||
<div class="particles-list">
|
||||
<div *ngFor="let particle of particleData.frames[frameId]; let i = index" class="particle-item">
|
||||
<span>Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }}
|
||||
, {{ particle.z.toFixed(2) }})</span>
|
||||
<button mat-icon-button color="warn" (click)="removeParticle(frameId, i)">
|
||||
<span class="particle-item-text">
|
||||
Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }}
|
||||
, {{ particle.z.toFixed(2) }})
|
||||
</span>
|
||||
<button mat-icon-button (click)="removeParticle(frameId, i)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="highlightParticle(frameId, i)">
|
||||
<mat-icon>lightbulb</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="!particleData.frames[frameId] || particleData.frames[frameId].length === 0"
|
||||
class="no-particles">
|
||||
|
|
|
|||
|
|
@ -17,10 +17,14 @@
|
|||
|
||||
.particle-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.particle-item-text {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.particle-item:last-child {
|
||||
|
|
|
|||
|
|
@ -83,4 +83,7 @@ export class FramesComponent {
|
|||
}
|
||||
|
||||
|
||||
public highlightParticle(frameId: string, i: number) {
|
||||
this.particleManagerService.highlightParticle(frameId, i);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import {Injectable} from '@angular/core';
|
||||
import * as THREE from 'three';
|
||||
import { RendererService } from './renderer.service';
|
||||
import { ParticleData, ParticleInfo, ParticleType } from '../models/particle.model';
|
||||
import {RendererService} from './renderer.service';
|
||||
import {ParticleData, ParticleInfo, ParticleType} from '../models/particle.model';
|
||||
|
||||
/**
|
||||
* Service responsible for managing particles in the scene
|
||||
|
|
@ -32,7 +32,8 @@ export class ParticleManagerService {
|
|||
private frames: string[] = ['frame1'];
|
||||
private selectedColor: string = '#ff0000';
|
||||
|
||||
constructor(private rendererService: RendererService) {}
|
||||
constructor(private rendererService: RendererService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a particle at the specified position
|
||||
|
|
@ -120,6 +121,51 @@ export class ParticleManagerService {
|
|||
}
|
||||
}
|
||||
|
||||
highlightParticle(frameId: string, index: number): void {
|
||||
if (!(this.particleData.frames[frameId] && this.particleData.frames[frameId].length > index)) {
|
||||
return;
|
||||
}
|
||||
const particleInfo = this.particleData.frames[frameId][index];
|
||||
const colorParts = particleInfo.color.split(',');
|
||||
const color = new THREE.Color(
|
||||
parseFloat(colorParts[0]),
|
||||
parseFloat(colorParts[1]),
|
||||
parseFloat(colorParts[2])
|
||||
);
|
||||
const particleMaterial = new THREE.MeshBasicMaterial({color});
|
||||
const particleGeometry = new THREE.SphereGeometry(0.03, 16, 16);
|
||||
const particleMesh = new THREE.Mesh(particleGeometry, particleMaterial);
|
||||
particleMesh.position.set(particleInfo.x, particleInfo.y, particleInfo.z);
|
||||
this.rendererService.scene.add(particleMesh);
|
||||
this.particles.push(particleMesh);
|
||||
this.animatePulse(particleMesh, 3, () => {
|
||||
this.rendererService.scene.remove(particleMesh);
|
||||
this.clearParticleVisuals();
|
||||
this.renderFrameParticles(this.currentFrame);
|
||||
});
|
||||
}
|
||||
|
||||
private animatePulse(mesh: THREE.Mesh, cycles: number, onComplete: () => void): void {
|
||||
const duration = 300;
|
||||
const maxScale = 0.08 / 0.03;
|
||||
const startTime = performance.now();
|
||||
|
||||
const animate = (time: number) => {
|
||||
const elapsed = (time - startTime) % duration;
|
||||
const t = elapsed / (duration / 2);
|
||||
const scaleFactor = t <= 1 ? 1 + (maxScale - 1) * t : maxScale - (maxScale - 1) * (t - 1);
|
||||
mesh.scale.setScalar(scaleFactor);
|
||||
|
||||
if (time - startTime >= duration * cycles) {
|
||||
onComplete();
|
||||
} else {
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected color for new particles
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user