correction interaction des blocs sur les timelines des joueurs

This commit is contained in:
2024-10-11 17:11:50 +02:00
parent 84d36ccdb3
commit 5ddd25c2cc
3 changed files with 110 additions and 22 deletions

View File

@@ -100,3 +100,12 @@ canvas {
font-size: 12px;
text-align: center;
}
.time-indicator {
position: absolute;
top: 0;
width: 3px; /* Epaisseur du trait */
height: 100%; /* La hauteur couvre toute la timeline */
background-color: red; /* Couleur du trait de temps */
left: 0; /* Point de départ du trait */
}

View File

@@ -39,9 +39,11 @@
</div> -->
<button (click)="setInteractionMode('move')">Déplacer Élément</button>
<button (click)="setInteractionMode('animate')">Dessiner Vecteur</button>
<button (click)="toggleLoop()">Boucle d'Animation</button>
<button (click)="replayTimeline()">Play again</button>
<button (click)="playTimeline()">Play</button>
<!--<button (click)="toggleLoop()">Boucle d'Animation</button>
<button (click)="replayTimeline()">Play again</button>-->
<button (click)="reinitPlayers()">Ré-init les positions</button>
<button (click)="playTimeline()">Play Timeline</button>
<button (click)="stopTimeline()">Stop Timeline</button>
</div>
<!-- <canvas #canvas width="800" height="600"
@@ -76,6 +78,9 @@
(mousedown)="onTimelineBlockMouseDown($event, player, i)">
{{ i + 1 }}
</div>
<div class="time-indicator" id="time-indicator">
<!-- Trait de visualisation -->
</div>
</div>
</div>
</div>

View File

@@ -1,6 +1,7 @@
import { Component, ViewChild, ElementRef, HostListener } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { C } from '@angular/cdk/keycodes';
interface TimelineStep {
startTime: number; // Le temps de début en millisecondes
@@ -226,10 +227,6 @@ export class FootballFieldComponent {
}
private animate() {
//this.updatePositions();
//if (this.isAnimating && this.selectedPlayer) {
// this.updatePlayerPosition(this.selectedPlayer);
//}
// Effacer le canvas pour redessiner
this.ctx.clearRect(0, 0, this.canvas.nativeElement.width, this.canvas.nativeElement.height);
@@ -251,11 +248,17 @@ export class FootballFieldComponent {
hasAnimation = true; // Indiquer qu'il y a encore de l'animation
}
});
// Mettre à jour la position du trait de visualisation du temps
this.updateTimeIndicator(currentTime);
}
});
this.drawField();
requestAnimationFrame(() => this.animate());
if (this.isPlaying === false) {
this.stopTimeline();
}
// Continuer l'animation seulement si au moins un joueur est encore en mouvement
//if ((this.isAnimating) || (hasAnimation && this.isPlaying)) {
// requestAnimationFrame(() => this.animate());
@@ -269,6 +272,30 @@ export class FootballFieldComponent {
this.isPlaying = false;
}
// Mise à jour de la position du trait de temps sur la timeline
updateTimeIndicator(currentTime: number) {
//const timeIndicator = document.getElementById('time-indicator');
const elmnts = document.querySelectorAll('[id=time-indicator]');
if (elmnts) {
const timeline = document.querySelector('.timeline') as HTMLElement;
const timelineWidth = timeline.offsetWidth; // Largeur totale de la timeline
// Calcul de la position du trait en pixels
let timePosition = (currentTime / this.getTotalTimelineDuration()) * timelineWidth;
// Si l'indicateur est à la fin de la timeline, on arrete l'animation
if(timePosition >= timelineWidth) {
timePosition = timelineWidth;
this.isPlaying = false;
}
// Mettre à jour la position du trait
//timeIndicator.style.left = `${timePosition}px`;
// Mettre à jour la position du trait
elmnts.forEach(element =>
(element as HTMLElement).style.left = `${timePosition}px`
);
}
}
private updatePlayerPosition(player: Circle) {
if (player.timeline.length === 0 || player.currentStepIndex >= player.timeline.length) {
return; // Pas d'animation si la timeline est vide
@@ -544,12 +571,12 @@ export class FootballFieldComponent {
this.selectedPlayer.timeline.push({
startTime: prevStartTime,
endTime: prevStartTime + 200,
endTime: prevStartTime + 1000,
startX: this.startX,
startY: this.startY,
endX: this.endX,
endY: this.endY,
duration: 200 // Durée d'animation arbitraire, peut être ajustée
duration: 1000 // Durée d'animation arbitraire, peut être ajustée
});
console.log("timeline:", this.selectedPlayer.timeline);
this.selectedPlayer.currentStepIndex = 0; // Réinitialiser au début de la timeline
@@ -944,6 +971,18 @@ export class FootballFieldComponent {
this.isAnimating = true; // Redémarrer l'animation
}
reinitPlayers() {
// Réinitialiser la progression et l'étape actuelle
this.players.forEach(player => {
player.progress = 0;
player.currentStepIndex = 0;
this.updatePlayerPosition(player);
});
const currentTime = performance.now();
this.updateTimeIndicator(currentTime);
}
/* GESTION DE LA TIMELINE */
getMousePosOnTimeline(event: MouseEvent): { x: number } {
@@ -965,7 +1004,9 @@ export class FootballFieldComponent {
// La durée totale de la timeline
const totalDuration = this.getTotalTimelineDuration();
// La longueur de la timeline en pixels (par exemple, 1000px)
const timelineWidth = this.timelineWidth;
const timeline = document.querySelector('.timeline') as HTMLElement;
const timelineWidth = timeline.offsetWidth; // Largeur totale de la timeline
//const timelineWidth = this.timelineWidth;
// La durée totale de l'animation en millisecondes
return (time / totalDuration) * timelineWidth;
}
@@ -1011,30 +1052,60 @@ export class FootballFieldComponent {
onTimelineMouseMove(event: MouseEvent) {
if (this.isTimelineDragging && this.draggedTimelinePlayer) {
//const { x } = this.getMousePos(event);
const { x } = this.getMousePosOnTimeline(event);
// Calculer la nouvelle position du bloc
const newStartX = x - this.dragOffsetX;
const totalDuration = this.getTotalTimelineDuration();
//const newStartTime = Math.floor((newStartX / this.canvas.nativeElement.width) * totalDuration);
const newStartTime = Math.floor((newStartX / this.timelineWidth) * totalDuration);
console.log("[onTimelineMouseMove] - x:",x,
" - dragOffsetX:", this.dragOffsetX,
" - newStartX:", newStartX,
" - newStartTime:", newStartTime);
" - newStartTime:", newStartTime,
" - dragged Index:", this.draggedTimelineIndex,
" - timeline len:", this.draggedTimelinePlayer.timeline.length,
);
// Mettre à jour l'étape avec la nouvelle position
const step = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex];
if (step.endTime < this.getTotalTimelineDuration()) {
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
let prevStep:TimelineStep = null;
// Le bloc N ne peut pas dépasser le bloc N+1 si celui-ci existe
// De même, le bloc N ne peut pas dépasser le bloc N-1 si celui-ci existe
if ((this.draggedTimelineIndex + 1) < this.draggedTimelinePlayer.timeline.length) {
const nextStep = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex + 1];
if ((this.draggedTimelineIndex - 1) >= 0) {
prevStep = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex - 1];
}
if ((((newStartTime + step.duration) < nextStep.startTime) &&
prevStep === null) ||
(prevStep != null &&
((prevStep.endTime <= newStartTime) && ((newStartTime + step.duration) < nextStep.startTime)))) {
//console.log("PLOP0.1: (",newStartTime + step.duration, "/", nextStep.startTime,")");
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
step.endTime = Math.max(0, step.startTime + step.duration); // Ne pas permettre les valeurs négatives
}
} else if (((this.draggedTimelineIndex - 1) >= 0) &&
(this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex - 1])) {
const prevStep = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex - 1];
if ((prevStep.endTime <= newStartTime) &&
((newStartTime + step.duration) <= (this.getTotalTimelineDuration()))) {
//console.log("PLOP1.1: (",prevStep.endTime, "/", newStartTime,"),(",newStartTime + step.duration,"/",this.getTotalTimelineDuration(),")");
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
step.endTime = Math.max(0, step.startTime + step.duration); // Ne pas permettre les valeurs négatives
}
} else {
if (step.endTime < this.getTotalTimelineDuration()) {
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
}
step.endTime = Math.max(0, step.startTime + step.duration); // Ne pas permettre les valeurs négatives
}
step.endTime = Math.max(0, newStartTime + step.duration); // Ne pas permettre les valeurs négatives
/*
// Ajuster la position de fin si nécessaire
if (this.draggedTimelineIndex > 0) {
const previousStep = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex - 1];
previousStep.endTime = step.startTime;
}
console.log("PLOP2");
if (step.endTime < this.getTotalTimelineDuration()) {
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
}
step.endTime = Math.max(0, step.startTime + step.duration); // Ne pas permettre les valeurs négatives
*/
}
}
@@ -1042,6 +1113,7 @@ export class FootballFieldComponent {
onTimelineMouseUp() {
console.log("onMouseUp");
if (this.isTimelineDragging) {
console.log("timeline:", this.draggedTimelinePlayer.timeline);
this.isTimelineDragging = false;
this.draggedTimelinePlayer = null;
this.draggedTimelineIndex = -1;
@@ -1075,7 +1147,9 @@ export class FootballFieldComponent {
}
playTimeline() {
if (this.isPlaying) return; // Ne pas relancer si déjà en cours
if (this.isPlaying) {
return; // Ne pas relancer si déjà en cours
}
this.isPlaying = true;
this.animationStartTime = performance.now(); // Obtenir le timestamp de départ