animation du ballon avec le joueur et debut d'animation du ballon seul
This commit is contained in:
@@ -7,9 +7,10 @@
|
|||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
justify-content: space-evenly;
|
||||||
width: 620px; /* largeur égale au canvas pour aligner */
|
align-items: stretch;
|
||||||
|
width: 690px; /* largeur égale au canvas pour aligner */
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,13 +49,22 @@ canvas {
|
|||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar-act {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-mode {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.clear-button {
|
.clear-button {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
margin: 2px;
|
||||||
background-color: #ff4d4d; /* Rouge vif */
|
background-color: #ff4d4d; /* Rouge vif */
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: 12px bold;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +72,36 @@ canvas {
|
|||||||
background-color: #ff1a1a; /* couleur plus foncée au survol */
|
background-color: #ff1a1a; /* couleur plus foncée au survol */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 2px;
|
||||||
|
background-color: #a04dff; /* Rouge vif */
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px bold;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:hover {
|
||||||
|
background-color: #ca1aff; /* couleur plus foncée au survol */
|
||||||
|
}
|
||||||
|
|
||||||
|
.anim-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 2px;
|
||||||
|
background-color: hsl(224, 100%, 65%); /* Rouge vif */
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px bold;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anim-button:hover {
|
||||||
|
background-color: #1a3cff; /* couleur plus foncée au survol */
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-container {
|
.timeline-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|||||||
@@ -1,50 +1,39 @@
|
|||||||
<div class="football-container">
|
<div class="football-container">
|
||||||
<!-- Sélecteur de couleurs au-dessus du canvas -->
|
<!-- Sélecteur de couleurs au-dessus du canvas -->
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<!-- <div class="color-palette">
|
<!-- Saisie du nombre de joueurs -->
|
||||||
<div *ngFor="let color of colors" [style.background]="color" (click)="setColor(color)" class="color-box" [class.selected]="color === selectedColor">
|
<div class="player-count">
|
||||||
|
<label for="playerCount">Nombre de joueurs : </label>
|
||||||
|
<input type="number" id="playerCount" [(ngModel)]="playerCount" min="1" max="25" (change)="updatePlayers()">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Saisie du nombre de plots -->
|
||||||
|
<div class="plot-count">
|
||||||
|
<label for="plotCount">Nombre de plots : </label>
|
||||||
|
<input type="number" id="plotCount" [(ngModel)]="plotCount" min="1" max="50" (change)="updatePlots()">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Saisie du nombre de plots -->
|
||||||
|
<div class="piquet-count">
|
||||||
|
<label for="piquetCount">Nombre de piquets : </label>
|
||||||
|
<input type="number" id="piquetCount" [(ngModel)]="piquetCount" min="1" max="20" (change)="updatePiquets()">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bouton pour réinitialiser le dessin -->
|
||||||
|
<!--<button (click)="clearCanvas()" class="clear-button">Réinitialiser</button>-->
|
||||||
|
|
||||||
|
<div class="toolbar-act">
|
||||||
|
<button (click)="setInteractionMode('move')" class="action-button">Déplacer Élément</button>
|
||||||
|
<button (click)="setInteractionMode('animate')" class="action-button">Dessiner Vecteur</button>
|
||||||
|
<button (click)="reinitPlayers()" class="anim-button">Initialiser</button>
|
||||||
|
<button (click)="playTimeline()" class="anim-button">Play Timeline</button>
|
||||||
|
<button (click)="stopTimeline()" class="anim-button">Stop Timeline</button>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- Saisie du nombre de joueurs -->
|
<div class="toolbar-mode">
|
||||||
<div class="player-count">
|
<span><h2>{{ interactionMode }}</h2></span>
|
||||||
<label for="playerCount">Nombre de joueurs : </label>
|
</div>
|
||||||
<input type="number" id="playerCount" [(ngModel)]="playerCount" min="1" max="25" (change)="updatePlayers()">
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Saisie du nombre de plots -->
|
|
||||||
<div class="plot-count">
|
|
||||||
<label for="plotCount">Nombre de plots : </label>
|
|
||||||
<input type="number" id="plotCount" [(ngModel)]="plotCount" min="1" max="50" (change)="updatePlots()">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Saisie du nombre de plots -->
|
|
||||||
<div class="piquet-count">
|
|
||||||
<label for="piquetCount">Nombre de piquets : </label>
|
|
||||||
<input type="number" id="piquetCount" [(ngModel)]="piquetCount" min="1" max="20" (change)="updatePiquets()">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Bouton pour réinitialiser le dessin -->
|
|
||||||
<button (click)="clearCanvas()" class="clear-button">Réinitialiser</button>
|
|
||||||
|
|
||||||
<!-- Sélection de forme -->
|
|
||||||
<!-- <div class="shape-selector">
|
|
||||||
<label for="shape">Forme :</label>
|
|
||||||
<select id="shape" [(ngModel)]="selectedShape">
|
|
||||||
<option value="none">Aucune</option>
|
|
||||||
<option value="rectangle">Rectangle</option>
|
|
||||||
<option value="circle">Cercle</option>
|
|
||||||
<option value="line">Ligne</option>
|
|
||||||
</select>
|
|
||||||
</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)="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"
|
<!-- <canvas #canvas width="800" height="600"
|
||||||
(mousedown)="startDrawing($event)"
|
(mousedown)="startDrawing($event)"
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ interface Player {
|
|||||||
isMoving: boolean; // Flag d'animation du joueur
|
isMoving: boolean; // Flag d'animation du joueur
|
||||||
progress: number; // Paramètre de progression sur la courbe
|
progress: number; // Paramètre de progression sur la courbe
|
||||||
hasBall: boolean; // Indique si le joueur a le ballon
|
hasBall: boolean; // Indique si le joueur a le ballon
|
||||||
startX: number;
|
|
||||||
startY: number;
|
|
||||||
steps: TimelineStep[]; // Stockage des étapes d'animation
|
steps: TimelineStep[]; // Stockage des étapes d'animation
|
||||||
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
||||||
}
|
}
|
||||||
@@ -89,21 +87,17 @@ interface Player {
|
|||||||
export class FootballFieldComponent {
|
export class FootballFieldComponent {
|
||||||
@ViewChild('canvas', { static: true }) canvas!: ElementRef<HTMLCanvasElement>;
|
@ViewChild('canvas', { static: true }) canvas!: ElementRef<HTMLCanvasElement>;
|
||||||
private ctx!: CanvasRenderingContext2D;
|
private ctx!: CanvasRenderingContext2D;
|
||||||
//private drawing = false;
|
|
||||||
//private lastX = 0;
|
|
||||||
//private lastY = 0;
|
|
||||||
private startX = 0;
|
private startX = 0;
|
||||||
private startY = 0;
|
private startY = 0;
|
||||||
private draggingPlayer: Player | null = null;
|
private draggingPlayer: Player | null = null;
|
||||||
private draggingElement: any = null; // Element (plot, piquet) en cours de déplacement sur le terrain
|
private draggingElement: any = null; // Element (plot, piquet) en cours de déplacement sur le terrain
|
||||||
private attachedPlayer: Player | null = null;
|
private attachedPlayer: Player | null = null;
|
||||||
private magnetRadius: number = 35; // Distance à laquelle le ballon s'attache au joueur
|
private magnetRadius: number = 50; // Distance à laquelle le ballon s'attache au joueur
|
||||||
//private attachedToPlayer: boolean = false; // indique si le ballon est attache a un joueur
|
//private attachedToPlayer: boolean = false; // indique si le ballon est attache a un joueur
|
||||||
private offsetX: number = 0;
|
private offsetX: number = 0;
|
||||||
private offsetY: number = 0;
|
private offsetY: number = 0;
|
||||||
private test: boolean = false;
|
private test: boolean = false;
|
||||||
private prevAngle: number = 0;
|
private prevAngle: number = 0;
|
||||||
//private isDrawingVector: boolean = false;
|
|
||||||
|
|
||||||
private endX: number = 0;
|
private endX: number = 0;
|
||||||
private endY: number = 0;
|
private endY: number = 0;
|
||||||
@@ -114,31 +108,12 @@ export class FootballFieldComponent {
|
|||||||
// Timestamp de début de l'animation
|
// Timestamp de début de l'animation
|
||||||
private animationStartTime: number = 0;
|
private animationStartTime: number = 0;
|
||||||
|
|
||||||
//public colors: string[] = ['#ff0000', '#00ff00',
|
|
||||||
// '#0000ff', '#ffff00',
|
|
||||||
// '#ff00ff', '#00ffff',
|
|
||||||
// '#000000', '#808080',
|
|
||||||
// '#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
|
|
||||||
public playerCount: number = 8; // Nombre de joueurs par défaut
|
public playerCount: number = 8; // Nombre de joueurs par défaut
|
||||||
public plotCount: number = 2; // Nombre de plots par défaut
|
public plotCount: number = 2; // Nombre de plots par défaut
|
||||||
public piquetCount: number = 2; // Nombre de plots par défaut
|
public piquetCount: number = 2; // Nombre de plots par défaut
|
||||||
public players: Player[] = [];
|
public players: Player[] = [];
|
||||||
public plots: Plot[] = [];
|
public plots: Plot[] = [];
|
||||||
public piquets: Piquet[] = [];
|
public piquets: Piquet[] = [];
|
||||||
/*public ball: Circle = { id: 0,
|
|
||||||
x:400,
|
|
||||||
y:300,
|
|
||||||
radius:10,
|
|
||||||
isDragging:false,
|
|
||||||
isMoving:false,
|
|
||||||
progress: 0,
|
|
||||||
startX: 150,
|
|
||||||
startY: 150,
|
|
||||||
timeline: [],
|
|
||||||
currentStepIndex: 0 };*/
|
|
||||||
public ball: Ball = { id: 0,
|
public ball: Ball = { id: 0,
|
||||||
design: { x:400, y:300,
|
design: { x:400, y:300,
|
||||||
radius:10,
|
radius:10,
|
||||||
@@ -150,7 +125,8 @@ export class FootballFieldComponent {
|
|||||||
currentStepIndex: 0,
|
currentStepIndex: 0,
|
||||||
attachedToPlayer: null };
|
attachedToPlayer: null };
|
||||||
public selectedPlayer: Player | null = null;
|
public selectedPlayer: Player | null = null;
|
||||||
public isDrawingLine: boolean = false;
|
public isDrawingPlayerLine: boolean = false;
|
||||||
|
public isDrawingBallLine: boolean = false;
|
||||||
public loopAnimation: boolean = false; // Pour répéter l'animation
|
public loopAnimation: boolean = false; // Pour répéter l'animation
|
||||||
public debugInfo: string = ""; // Variable pour les informations de debogage
|
public debugInfo: string = ""; // Variable pour les informations de debogage
|
||||||
public interactionMode: 'move' | 'animate' = 'move'; // Mode d'interaction sélectionné
|
public interactionMode: 'move' | 'animate' = 'move'; // Mode d'interaction sélectionné
|
||||||
@@ -249,7 +225,7 @@ export class FootballFieldComponent {
|
|||||||
this.updateDebugInfo();
|
this.updateDebugInfo();
|
||||||
|
|
||||||
// Dessiner la ligne si en mode dessin
|
// Dessiner la ligne si en mode dessin
|
||||||
if (this.isDrawingLine && this.selectedPlayer) {
|
if (this.isDrawingPlayerLine && this.selectedPlayer) {
|
||||||
//console.log("[Draw Field] drawing vector");
|
//console.log("[Draw Field] drawing vector");
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.startX, this.startY);
|
ctx.moveTo(this.startX, this.startY);
|
||||||
@@ -257,6 +233,13 @@ export class FootballFieldComponent {
|
|||||||
ctx.strokeStyle = '#FF0000';
|
ctx.strokeStyle = '#FF0000';
|
||||||
ctx.lineWidth = 4;
|
ctx.lineWidth = 4;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
} else if (this.isDrawingBallLine) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.startX, this.startY);
|
||||||
|
ctx.lineTo(this.endX, this.endY);
|
||||||
|
ctx.strokeStyle = '#00FF00';
|
||||||
|
ctx.lineWidth = 4;
|
||||||
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,9 +269,8 @@ export class FootballFieldComponent {
|
|||||||
// Déplacer le ballon si attaché à un joueur
|
// Déplacer le ballon si attaché à un joueur
|
||||||
if (this.ball.attachedToPlayer) {
|
if (this.ball.attachedToPlayer) {
|
||||||
const player = this.ball.attachedToPlayer;
|
const player = this.ball.attachedToPlayer;
|
||||||
// Le ballon suit le joueur avec un léger décalage (ajustable)
|
// Le ballon suit le joueur
|
||||||
this.ball.design.x = player.design.x + player.design.radius + this.ball.design.radius + 5; // Décalage à droite du joueur
|
this.updateBallPositionOnPlayer(player);
|
||||||
this.ball.design.y = player.design.y; // Même hauteur que le joueur
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mettre à jour la position du trait de visualisation du temps
|
// Mettre à jour la position du trait de visualisation du temps
|
||||||
@@ -296,6 +278,14 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mettre à jour la position du ballon
|
||||||
|
if (this.isAnimating) {
|
||||||
|
if (this.ball.steps.length > 0) {
|
||||||
|
console.log("PLUP");
|
||||||
|
this.updateBallPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.drawField();
|
this.drawField();
|
||||||
requestAnimationFrame(() => this.animate());
|
requestAnimationFrame(() => this.animate());
|
||||||
|
|
||||||
@@ -321,16 +311,15 @@ export class FootballFieldComponent {
|
|||||||
const elmnts = document.querySelectorAll('[id=time-indicator]');
|
const elmnts = document.querySelectorAll('[id=time-indicator]');
|
||||||
if (elmnts) {
|
if (elmnts) {
|
||||||
const timeline = document.querySelector('.timeline') as HTMLElement;
|
const timeline = document.querySelector('.timeline') as HTMLElement;
|
||||||
const timelineWidth = timeline.offsetWidth; // Largeur totale de la timeline
|
this.timelineWidth = timeline.offsetWidth; // Largeur totale de la timeline
|
||||||
// Calcul de la position du trait en pixels
|
// Calcul de la position du trait en pixels
|
||||||
let timePosition = (currentTime / this.getTotalTimelineDuration()) * timelineWidth;
|
let timePosition = (currentTime / this.getTotalTimelineDuration()) * this.timelineWidth;
|
||||||
// Si l'indicateur est à la fin de la timeline, on arrete l'animation
|
// Si l'indicateur est à la fin de la timeline, on arrete l'animation et on replace
|
||||||
if(timePosition >= timelineWidth) {
|
// l'indicateur au debut de la timeline
|
||||||
timePosition = timelineWidth;
|
if(timePosition >= this.timelineWidth) {
|
||||||
|
timePosition = 0;
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
}
|
}
|
||||||
// Mettre à jour la position du trait
|
|
||||||
//timeIndicator.style.left = `${timePosition}px`;
|
|
||||||
|
|
||||||
// Mettre à jour la position du trait
|
// Mettre à jour la position du trait
|
||||||
elmnts.forEach(element =>
|
elmnts.forEach(element =>
|
||||||
@@ -353,6 +342,33 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateBallPosition() {
|
||||||
|
if (this.ball.steps.length === 0 || this.ball.currentStepIndex >= this.ball.steps.length) {
|
||||||
|
return; // Pas d'animation si la timeline est vide
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = this.ball.steps[this.ball.currentStepIndex];
|
||||||
|
// Avancer le joueur sur la ligne avec un LERP (Linear Interpolation)
|
||||||
|
this.ball.progress += this.animationSpeed;
|
||||||
|
// Temps actuel
|
||||||
|
const currentTime = performance.now();
|
||||||
|
if (this.ball.progress >= 1) {
|
||||||
|
this.ball.progress = 0; // Réinitialiser la progression
|
||||||
|
this.ball.design.x = step.endX;
|
||||||
|
this.ball.design.y = step.endY;
|
||||||
|
this.ball.currentStepIndex++; // Passer à l'étape suivante
|
||||||
|
|
||||||
|
// Si on atteint la fin de la timeline, arrêter
|
||||||
|
if (this.ball.currentStepIndex >= this.ball.steps.length) {
|
||||||
|
this.isAnimating = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const t = this.ball.progress;
|
||||||
|
this.ball.design.x = (1 - t) * step.startX + t * step.endX;
|
||||||
|
this.ball.design.y = (1 - t) * step.startY + t * step.endY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private updatePlayerPosition(player: Player) {
|
private updatePlayerPosition(player: Player) {
|
||||||
if (player.steps.length === 0 || player.currentStepIndex >= player.steps.length) {
|
if (player.steps.length === 0 || player.currentStepIndex >= player.steps.length) {
|
||||||
return; // Pas d'animation si la timeline est vide
|
return; // Pas d'animation si la timeline est vide
|
||||||
@@ -363,17 +379,6 @@ export class FootballFieldComponent {
|
|||||||
player.progress += this.animationSpeed;
|
player.progress += this.animationSpeed;
|
||||||
// Temps actuel
|
// Temps actuel
|
||||||
const currentTime = performance.now();
|
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) {
|
if (player.progress >= 1) {
|
||||||
player.progress = 0; // Réinitialiser la progression
|
player.progress = 0; // Réinitialiser la progression
|
||||||
@@ -394,11 +399,10 @@ export class FootballFieldComponent {
|
|||||||
player.design.x = (1 - t) * step.startX + t * step.endX;
|
player.design.x = (1 - t) * step.startX + t * step.endX;
|
||||||
player.design.y = (1 - t) * step.startY + t * step.endY;
|
player.design.y = (1 - t) * step.startY + t * step.endY;
|
||||||
|
|
||||||
// Attacher le ballon si un joueur se rapproche suffisamment
|
// Si le joueur a le ballon "aimanté", on met à jour la position
|
||||||
const nearestPlayer = this.getNearestPlayerToBall();
|
// du ballon en même temps que celui du ballon
|
||||||
if (nearestPlayer && this.getDistance(this.ball.design, nearestPlayer.design) < this.magnetRadius) {
|
if (player.hasBall) {
|
||||||
//this.attachedPlayer = nearestPlayer;
|
this.updateBallPositionOnPlayer(player);
|
||||||
this.updateBallPositionOnPlayer(nearestPlayer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,8 +429,6 @@ export class FootballFieldComponent {
|
|||||||
isDragging: false,
|
isDragging: false,
|
||||||
isMoving: false,
|
isMoving: false,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
startX: 0,
|
|
||||||
startY: 0,
|
|
||||||
steps: [],
|
steps: [],
|
||||||
currentStepIndex: 0,
|
currentStepIndex: 0,
|
||||||
hasBall: false });
|
hasBall: false });
|
||||||
@@ -571,12 +573,26 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.selectedPlayer) {
|
if (!this.selectedPlayer) {
|
||||||
this.selectPlayer(x, y);
|
console.log("[Mouse Down|Animate] No player selected");
|
||||||
} else if (!this.isDrawingLine) {
|
//this.selectPlayer(x, y);
|
||||||
|
if (!this.isDrawingBallLine) {
|
||||||
|
if (this.isInsideCircle(this.ball.design, x, y)) {
|
||||||
|
this.startX = this.ball.design.x;
|
||||||
|
this.startY = this.ball.design.y;
|
||||||
|
this.isDrawingBallLine = true;
|
||||||
|
console.log("[Mouse Down|Animate] drawing ball line - Start:(",
|
||||||
|
this.startX,",",
|
||||||
|
this.startY,"), End:(",
|
||||||
|
this.endX,",",
|
||||||
|
this.endY,
|
||||||
|
")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!this.isDrawingPlayerLine) {
|
||||||
this.startX = this.selectedPlayer.design.x;
|
this.startX = this.selectedPlayer.design.x;
|
||||||
this.startY = this.selectedPlayer.design.y;
|
this.startY = this.selectedPlayer.design.y;
|
||||||
this.isDrawingLine = true;
|
this.isDrawingPlayerLine = true;
|
||||||
console.log("[Mouse Down|Animate] drawing line - Start:(",
|
console.log("[Mouse Down|Animate] drawing player line - Start:(",
|
||||||
this.startX,",",
|
this.startX,",",
|
||||||
this.startY,"), End:(",
|
this.startY,"), End:(",
|
||||||
this.endX,",",
|
this.endX,",",
|
||||||
@@ -605,11 +621,11 @@ export class FootballFieldComponent {
|
|||||||
const { x, y } = this.getMousePos(event);
|
const { x, y } = this.getMousePos(event);
|
||||||
if (this.interactionMode === 'animate') {
|
if (this.interactionMode === 'animate') {
|
||||||
console.log("[Mouse Up] Stop animating elements");
|
console.log("[Mouse Up] Stop animating elements");
|
||||||
if (this.isDrawingLine && this.selectedPlayer) {
|
if (this.isDrawingPlayerLine && this.selectedPlayer) {
|
||||||
console.log("[Mouse Up|Animate] Stop drawing vector");
|
console.log("[Mouse Up|Animate] Stop drawing player line");
|
||||||
this.endX = x;
|
this.endX = x;
|
||||||
this.endY = y;
|
this.endY = y;
|
||||||
this.isDrawingLine = false;
|
this.isDrawingPlayerLine = false;
|
||||||
// Ajouter l'étape dans la timeline du joueur
|
// Ajouter l'étape dans la timeline du joueur
|
||||||
let prevStartTime:number = 0;
|
let prevStartTime:number = 0;
|
||||||
if (this.selectedPlayer.steps && this.selectedPlayer.steps.length > 0) {
|
if (this.selectedPlayer.steps && this.selectedPlayer.steps.length > 0) {
|
||||||
@@ -627,16 +643,43 @@ export class FootballFieldComponent {
|
|||||||
endY: this.endY,
|
endY: this.endY,
|
||||||
duration: 1000 // 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.steps);
|
console.log("timeline player:", this.selectedPlayer.steps);
|
||||||
//this.selectedPlayer.currentStepIndex = 0; // Réinitialiser au début de la timeline
|
// Initialiser l'index à l'étape précédente
|
||||||
|
this.selectedPlayer.currentStepIndex = this.selectedPlayer.steps.length - 1;
|
||||||
|
this.startAnimation();
|
||||||
|
} else if (this.isDrawingBallLine) {
|
||||||
|
console.log("[Mouse Up|Animate] Stop drawing ball line");
|
||||||
|
this.endX = x;
|
||||||
|
this.endY = y;
|
||||||
|
this.isDrawingBallLine = false;
|
||||||
|
// Ajouter l'étape dans la timeline du ballon
|
||||||
|
let prevStartTime:number = 0;
|
||||||
|
if (this.ball.steps && this.ball.steps.length > 0) {
|
||||||
|
prevStartTime = this.ball.steps[this.ball.steps.length - 1].endTime;
|
||||||
|
} else {
|
||||||
|
prevStartTime = 0;
|
||||||
|
}
|
||||||
|
this.ball.steps.push({
|
||||||
|
startTime: prevStartTime,
|
||||||
|
endTime: prevStartTime + 1000,
|
||||||
|
startX: this.startX,
|
||||||
|
startY: this.startY,
|
||||||
|
endX: this.endX,
|
||||||
|
endY: this.endY,
|
||||||
|
duration: 1000 // Durée d'animation arbitraire, peut être ajustée
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("timeline ball:", this.ball.steps);
|
||||||
|
// Initialiser l'index à l'étape précédente
|
||||||
|
this.ball.currentStepIndex = this.ball.steps.length - 1;
|
||||||
this.startAnimation();
|
this.startAnimation();
|
||||||
}
|
}
|
||||||
} else if (this.interactionMode === 'move') {
|
} else if (this.interactionMode === 'move') {
|
||||||
console.log("[Mouse Up] Stop moving elements");
|
console.log("[Mouse Up] Stop moving elements");
|
||||||
this.stopDragging();
|
this.stopDragging();
|
||||||
|
|
||||||
// Si on déplace un joueur alors que celui-ci a une animation,
|
// Si on déplace un joueur alors que celui-ci a une timeline,
|
||||||
// on supprime toute sa timeline
|
// on supprime la supprime
|
||||||
for (const player of this.players) {
|
for (const player of this.players) {
|
||||||
if (this.isInsideCircle(player.design, x, y)) {
|
if (this.isInsideCircle(player.design, x, y)) {
|
||||||
// Sélectionner le joueur
|
// Sélectionner le joueur
|
||||||
@@ -703,11 +746,6 @@ export class FootballFieldComponent {
|
|||||||
this.updateBallPositionOnPlayer(nearestPlayer);
|
this.updateBallPositionOnPlayer(nearestPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Si le ballon est attaché au joueur deplacer le ballon avec lui en calculant
|
|
||||||
// // la tangente
|
|
||||||
// if (this.attachedToPlayer) {
|
|
||||||
// this.updateBallPositionOnTangent();
|
|
||||||
// }
|
|
||||||
this.drawField();
|
this.drawField();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -743,7 +781,6 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateBallPositionOnPlayer(player: Player) {
|
private updateBallPositionOnPlayer(player: Player) {
|
||||||
//const player = this.attachedPlayer;
|
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
|
|
||||||
const dx = this.ball.design.x - player.design.x;
|
const dx = this.ball.design.x - player.design.x;
|
||||||
@@ -759,8 +796,11 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
this.ball.design.x = player.design.x + (player.design.radius + this.ball.design.radius) * Math.cos(angle);
|
this.ball.design.x = player.design.x + (player.design.radius + this.ball.design.radius) * Math.cos(angle);
|
||||||
this.ball.design.y = player.design.y + (player.design.radius + this.ball.design.radius) * Math.sin(angle);
|
this.ball.design.y = player.design.y + (player.design.radius + this.ball.design.radius) * Math.sin(angle);
|
||||||
|
// Pour l'animation
|
||||||
|
this.ball.attachedToPlayer = player;
|
||||||
|
player.hasBall = true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
private selectPlayer(x: number, y: number) {
|
private selectPlayer(x: number, y: number) {
|
||||||
this.selectedPlayer = this.getNearestPlayer(x, y);
|
this.selectedPlayer = this.getNearestPlayer(x, y);
|
||||||
if (this.selectedPlayer) {
|
if (this.selectedPlayer) {
|
||||||
@@ -768,11 +808,12 @@ export class FootballFieldComponent {
|
|||||||
this.selectedPlayer.startY = this.selectedPlayer.design.y;
|
this.selectedPlayer.startY = this.selectedPlayer.design.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
private startAnimation() {
|
private startAnimation() {
|
||||||
if (this.selectedPlayer) {
|
if (this.selectedPlayer || this.ball.currentStepIndex < this.ball.steps.length) {
|
||||||
this.isAnimating = true;
|
this.isAnimating = true;
|
||||||
this.selectedPlayer.progress = 0; // Réinitialiser la progression
|
if (this.selectedPlayer) this.selectedPlayer.progress = 0; // Réinitialiser la progression
|
||||||
|
this.ball.progress = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,6 +915,9 @@ export class FootballFieldComponent {
|
|||||||
this.updatePlayerPosition(player);
|
this.updatePlayerPosition(player);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mise à jour de l'indicateur de timeline
|
||||||
|
this.updateTimeIndicator(0);
|
||||||
|
|
||||||
const currentTime = performance.now();
|
const currentTime = performance.now();
|
||||||
this.updateTimeIndicator(currentTime);
|
this.updateTimeIndicator(currentTime);
|
||||||
}
|
}
|
||||||
@@ -1038,7 +1082,7 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
getTotalTimelineDuration(): number {
|
getTotalTimelineDuration(): number {
|
||||||
// Calculer la durée totale de la timeline, par exemple basée sur la durée totale de l'animation
|
// Calculer la durée totale de la timeline, par exemple basée sur la durée totale de l'animation
|
||||||
return 10000; // Par exemple, 10 000 ms pour une timeline de 10 secondes
|
return 20000; // Par exemple, 10 000 ms pour une timeline de 10 secondes
|
||||||
}
|
}
|
||||||
|
|
||||||
playTimeline() {
|
playTimeline() {
|
||||||
|
|||||||
Reference in New Issue
Block a user