|
|
|
|
@@ -82,7 +82,7 @@ export class FootballFieldComponent {
|
|
|
|
|
// '#0000ff', '#ffff00',
|
|
|
|
|
// '#ff00ff', '#00ffff',
|
|
|
|
|
// '#000000', '#808080',
|
|
|
|
|
// '#ffa500', '#8a2be2'];
|
|
|
|
|
// '#ffa500', '#8a2be2'];
|
|
|
|
|
//public selectedColor: string = this.colors[0]; // Couleur sélectionné par défaut (rouge)
|
|
|
|
|
// Options de forme
|
|
|
|
|
//public selectedShape: string = 'none'; // Par défaut, aucune forme
|
|
|
|
|
@@ -94,21 +94,21 @@ export class FootballFieldComponent {
|
|
|
|
|
public plots: Circle[] = [];
|
|
|
|
|
public piquets: Rectangle[] = [];
|
|
|
|
|
public ball: Circle = { id: 0,
|
|
|
|
|
x:400,
|
|
|
|
|
y:300,
|
|
|
|
|
number:1,
|
|
|
|
|
radius:10,
|
|
|
|
|
isDragging:false,
|
|
|
|
|
vx:0,
|
|
|
|
|
vy:0,
|
|
|
|
|
destinationX: null,
|
|
|
|
|
destinationY: null,
|
|
|
|
|
isMoving:false,
|
|
|
|
|
progress: 0,
|
|
|
|
|
startX: 150,
|
|
|
|
|
startY: 150,
|
|
|
|
|
timeline: null,
|
|
|
|
|
currentStepIndex: 0 };
|
|
|
|
|
x:400,
|
|
|
|
|
y:300,
|
|
|
|
|
number:1,
|
|
|
|
|
radius:10,
|
|
|
|
|
isDragging:false,
|
|
|
|
|
vx:0,
|
|
|
|
|
vy:0,
|
|
|
|
|
destinationX: null,
|
|
|
|
|
destinationY: null,
|
|
|
|
|
isMoving:false,
|
|
|
|
|
progress: 0,
|
|
|
|
|
startX: 150,
|
|
|
|
|
startY: 150,
|
|
|
|
|
timeline: null,
|
|
|
|
|
currentStepIndex: 0 };
|
|
|
|
|
public selectedPlayer: Circle | null = null;
|
|
|
|
|
public isDrawingLine: boolean = false;
|
|
|
|
|
public loopAnimation: boolean = false; // Pour répéter l'animation
|
|
|
|
|
@@ -122,7 +122,7 @@ export class FootballFieldComponent {
|
|
|
|
|
// La largeur totale de la timeline en pixels.
|
|
|
|
|
// Cela représente la taille visuelle de la timeline dans laquelle
|
|
|
|
|
// les différents étapes de mouvement d'un élément sont affichés.
|
|
|
|
|
public timelineWidth: number = 800;
|
|
|
|
|
public timelineWidth: number = 722;
|
|
|
|
|
// Décalage horizontal en pixels utilisé lorsque vous commencez à déplacer
|
|
|
|
|
// un bloc sur la timeline.
|
|
|
|
|
public dragOffsetX: number = 0;
|
|
|
|
|
@@ -251,6 +251,17 @@ export class FootballFieldComponent {
|
|
|
|
|
// Temps actuel
|
|
|
|
|
const currentTime = performance.now();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// Vérifier si le temps actuel correspond à l'intervalle de cette étape
|
|
|
|
|
if (currentTime >= step.startTime && currentTime <= step.endTime) {
|
|
|
|
|
const t = (currentTime - step.startTime) / (step.endTime - step.startTime);
|
|
|
|
|
player.x = (1 - t) * step.startX + t * step.endX;
|
|
|
|
|
player.y = (1 - t) * step.startY + t * step.endY;
|
|
|
|
|
} else if (currentTime > step.endTime) {
|
|
|
|
|
player.currentStepIndex++;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (player.progress >= 1) {
|
|
|
|
|
player.progress = 0; // Réinitialiser la progression
|
|
|
|
|
player.x = step.endX;
|
|
|
|
|
@@ -274,10 +285,12 @@ export class FootballFieldComponent {
|
|
|
|
|
|
|
|
|
|
// Mettre à jour debugInfo avec les positions des joueurs et du ballon
|
|
|
|
|
private updateDebugInfo() {
|
|
|
|
|
const playerPositions = this.players.map((player, index) => `Joueur ${index + 1}: (${player.x.toFixed(1)}, ${player.y.toFixed(1)})`).join(', ');
|
|
|
|
|
const ballPosition = `Ballon: (${this.ball.x.toFixed(1)}, ${this.ball.y.toFixed(1)})`;
|
|
|
|
|
const playerPositions = this.players.map((player, index) =>
|
|
|
|
|
`Joueur ${index + 1}: (${player.x.toFixed(1)}, ${player.y.toFixed(1)})`
|
|
|
|
|
).join(', ');
|
|
|
|
|
const ballPosition = `Ballon: (${this.ball.x.toFixed(1)}, ${this.ball.y.toFixed(1)})`;
|
|
|
|
|
|
|
|
|
|
this.debugInfo = `${playerPositions}, ${ballPosition}`;
|
|
|
|
|
this.debugInfo = `${playerPositions}, ${ballPosition}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Créer les cercles nuerotes representant les joueurs
|
|
|
|
|
@@ -493,16 +506,23 @@ export class FootballFieldComponent {
|
|
|
|
|
this.endY = y;
|
|
|
|
|
this.isDrawingLine = false;
|
|
|
|
|
// Ajouter l'étape dans la timeline du joueur
|
|
|
|
|
console.log("timeline:", this.selectedPlayer.timeline);
|
|
|
|
|
let prevStartTime:number = 0;
|
|
|
|
|
if (this.selectedPlayer.timeline && this.selectedPlayer.timeline.length > 0) {
|
|
|
|
|
prevStartTime = this.selectedPlayer.timeline[this.selectedPlayer.timeline.length - 1].endTime;
|
|
|
|
|
} else {
|
|
|
|
|
prevStartTime = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.selectedPlayer.timeline.push({
|
|
|
|
|
startTime: 0,
|
|
|
|
|
endTime: 1000,
|
|
|
|
|
startTime: prevStartTime,
|
|
|
|
|
endTime: prevStartTime + 200,
|
|
|
|
|
startX: this.startX,
|
|
|
|
|
startY: this.startY,
|
|
|
|
|
endX: this.endX,
|
|
|
|
|
endY: this.endY,
|
|
|
|
|
duration: 100 // Durée d'animation arbitraire, peut être ajustée
|
|
|
|
|
duration: 200 // 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
|
|
|
|
|
this.startAnimation();
|
|
|
|
|
}
|
|
|
|
|
@@ -898,17 +918,25 @@ export class FootballFieldComponent {
|
|
|
|
|
/* GESTION DE LA TIMELINE */
|
|
|
|
|
|
|
|
|
|
getMousePosOnTimeline(event: MouseEvent): { x: number } {
|
|
|
|
|
const timelineRect = (event.target as HTMLElement).getBoundingClientRect();
|
|
|
|
|
return {
|
|
|
|
|
x: event.clientX - timelineRect.left // Position X par rapport à la timeline
|
|
|
|
|
};
|
|
|
|
|
// Récupérer l'élément avec la classe 'timeline'
|
|
|
|
|
const timelineElement = document.querySelector('.timeline') as HTMLElement;
|
|
|
|
|
if (timelineElement) {
|
|
|
|
|
// Récupérer la position de la timeline relative à la fenêtre
|
|
|
|
|
const timelineRect = timelineElement.getBoundingClientRect();
|
|
|
|
|
// Position X par rapport à la timeline
|
|
|
|
|
//console.log("[getMousePosOnTimeline] timeline rectangle left:", timelineRect.left, " - x:", event.clientX, "- res: ", event.clientX - timelineRect.left);
|
|
|
|
|
// Calculer la position X relative de la souris par rapport à la timeline
|
|
|
|
|
return { x: event.clientX - timelineRect.left };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { x: 0 };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calculateBlockPixelPosition(time: number): number {
|
|
|
|
|
// La durée totale de la timeline
|
|
|
|
|
const totalDuration = this.getTotalTimelineDuration();
|
|
|
|
|
// La largeur de la timeline en pixels (par exemple, 1000px)
|
|
|
|
|
const timelineWidth = this.timelineWidth;
|
|
|
|
|
const totalDuration = this.getTotalTimelineDuration();
|
|
|
|
|
// La longueur de la timeline en pixels (par exemple, 1000px)
|
|
|
|
|
const timelineWidth = this.timelineWidth;
|
|
|
|
|
// La durée totale de l'animation en millisecondes
|
|
|
|
|
return (time / totalDuration) * timelineWidth;
|
|
|
|
|
}
|
|
|
|
|
@@ -920,52 +948,69 @@ export class FootballFieldComponent {
|
|
|
|
|
// Chercher si un bloc (une étape du joueur) a été cliqué
|
|
|
|
|
for (let i = 0; i < player.timeline.length; i++) {
|
|
|
|
|
const step = player.timeline[i];
|
|
|
|
|
|
|
|
|
|
//console.log("[OnTimelineMouseDown | Joueur",player.id,"] - Timeline[",i,"]:", step);
|
|
|
|
|
// Calculer la position du bloc en pixels sur la timeline
|
|
|
|
|
const blockStartX = this.calculateBlockPixelPosition(step.startTime);
|
|
|
|
|
const blockEndX = this.calculateBlockPixelPosition(step.endTime);
|
|
|
|
|
|
|
|
|
|
console.log("[OnTimelineMouseDown | Joueur",player.id," | Block:",
|
|
|
|
|
i+1,"] x:",
|
|
|
|
|
x,
|
|
|
|
|
" - blockStartX:", blockStartX,
|
|
|
|
|
" - blockEndX:", blockEndX);
|
|
|
|
|
// Si la souris clique dans un bloc
|
|
|
|
|
if (x >= blockStartX && x <= blockEndX) {
|
|
|
|
|
console.log("clique dans un bloc !");
|
|
|
|
|
// Début du déplacement du bloc
|
|
|
|
|
this.isTimelineDragging = true;
|
|
|
|
|
this.draggedTimelinePlayer = player;
|
|
|
|
|
this.draggedTimelineIndex = i;
|
|
|
|
|
// Garder une référence pour un déplacement fluide
|
|
|
|
|
this.dragOffsetX = x - blockStartX;
|
|
|
|
|
this.dragOffsetX = x - blockStartX;
|
|
|
|
|
console.log("[OnTimelineMouseDown | Joueur",player.id,"] clique dans un bloc",
|
|
|
|
|
i+1,
|
|
|
|
|
" ! dragOffsetX:", this.dragOffsetX);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onTimelineBlockMouseDown(event: MouseEvent, player: Circle, index: number) {
|
|
|
|
|
console.log("onTimelineBlockMouseDown");
|
|
|
|
|
console.log("[onTimelineBlockMouseDown] index:", index);
|
|
|
|
|
this.isTimelineDragging = true;
|
|
|
|
|
this.draggedTimelinePlayer = player;
|
|
|
|
|
this.draggedTimelineIndex = index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseMove(event: MouseEvent) {
|
|
|
|
|
onTimelineMouseMove(event: MouseEvent) {
|
|
|
|
|
if (this.isTimelineDragging && this.draggedTimelinePlayer) {
|
|
|
|
|
console.log("onMouseMove");
|
|
|
|
|
const { x } = this.getMousePos(event);
|
|
|
|
|
//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 = (x / this.canvas.nativeElement.width) * totalDuration;
|
|
|
|
|
//const newStartTime = Math.floor((newStartX / this.canvas.nativeElement.width) * totalDuration);
|
|
|
|
|
const newStartTime = Math.floor((newStartX / this.timelineWidth) * totalDuration);
|
|
|
|
|
console.log("[onTimelineMouseMove] - x:",x,
|
|
|
|
|
" - newStartX:", newStartX,
|
|
|
|
|
" - newStartTime:", newStartTime);
|
|
|
|
|
|
|
|
|
|
// Mettre à jour l'étape avec la nouvelle position
|
|
|
|
|
const step = this.draggedTimelinePlayer.timeline[this.draggedTimelineIndex];
|
|
|
|
|
step.startTime = Math.max(0, newStartTime); // Ne pas permettre les valeurs négatives
|
|
|
|
|
|
|
|
|
|
if (step.endTime < this.getTotalTimelineDuration()) {
|
|
|
|
|
step.startTime = Math.max(0, newStartTime); // 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;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMouseUp() {
|
|
|
|
|
onTimelineMouseUp() {
|
|
|
|
|
console.log("onMouseUp");
|
|
|
|
|
if (this.isTimelineDragging) {
|
|
|
|
|
this.isTimelineDragging = false;
|
|
|
|
|
@@ -977,12 +1022,21 @@ export class FootballFieldComponent {
|
|
|
|
|
calculateLeftPosition(step: TimelineStep): string {
|
|
|
|
|
const totalDuration = this.getTotalTimelineDuration();
|
|
|
|
|
const left = (step.startTime / totalDuration) * 100;
|
|
|
|
|
//console.log("[calculateLeftPosition], left:", left, " - startTime:", step.startTime);
|
|
|
|
|
return `${left}%`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calculateBlockWidth(step: TimelineStep): string {
|
|
|
|
|
const totalDuration = this.getTotalTimelineDuration();
|
|
|
|
|
const width = ((step.endTime - step.startTime) / totalDuration) * 100;
|
|
|
|
|
/*
|
|
|
|
|
if (step.endTime >= step.startTime) {
|
|
|
|
|
const width = ((step.endTime - step.startTime) / totalDuration) * 100;
|
|
|
|
|
console.log("block width:", width);
|
|
|
|
|
return `${width}%`;
|
|
|
|
|
}
|
|
|
|
|
return "0";
|
|
|
|
|
*/
|
|
|
|
|
const width = (step.duration / totalDuration) * 100;
|
|
|
|
|
return `${width}%`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|