From 98c6dff4bfa7440782b11e05ea689bb8e79d5158 Mon Sep 17 00:00:00 2001 From: vbenoit Date: Tue, 15 Oct 2024 07:47:57 +0000 Subject: [PATCH] debut de redimensionnement des blocs de la timeline --- .../football-field.component.css | 18 +++ .../football-field.component.html | 12 ++ .../football-field.component.ts | 112 +++++++++++++++++- 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/src/app/football-field/football-field.component.css b/src/app/football-field/football-field.component.css index 8d039fb..796e51c 100644 --- a/src/app/football-field/football-field.component.css +++ b/src/app/football-field/football-field.component.css @@ -140,6 +140,7 @@ canvas { height: 23px; background-color: hsla(240, 100%, 50%, 0.308); border: 2px solid black; + border-radius: 4px; cursor: move; font-family: Arial, Helvetica, sans-serif; font-size: 12px; @@ -153,4 +154,21 @@ canvas { height: 100%; /* La hauteur couvre toute la timeline */ background-color: hsl(0, 1%, 41%); /* Couleur du trait de temps */ left: 0; /* Point de départ du trait */ +} + +.handle-left, .handle-right { + position: absolute; + top: 0; + width: 20px; + height: 100%; + background-color: hsla(240, 100%, 50%, 0.507);; + cursor: ew-resize; +} + +.handle-left { + left: 0; +} + +.handle-right { + right: 0; } \ No newline at end of file diff --git a/src/app/football-field/football-field.component.html b/src/app/football-field/football-field.component.html index e30a99c..4a7d94e 100644 --- a/src/app/football-field/football-field.component.html +++ b/src/app/football-field/football-field.component.html @@ -72,6 +72,18 @@ [style.width]="calculateBlockWidth(stepPlayer)" (mousedown)="onTimelineBlockMouseDown($event, player, i)"> {{ i + 1 }} +
+ +
+
+ +
diff --git a/src/app/football-field/football-field.component.ts b/src/app/football-field/football-field.component.ts index a81c4c5..1dfd6f8 100644 --- a/src/app/football-field/football-field.component.ts +++ b/src/app/football-field/football-field.component.ts @@ -1,7 +1,8 @@ -import { Component, ViewChild, ElementRef, HostListener } from '@angular/core'; +import { Component, ViewChild, Renderer2, ElementRef, HostListener } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { C } from '@angular/cdk/keycodes'; +import { CdkPortal } from '@angular/cdk/portal'; interface TimelineStep { startTime: number; // Le temps de début en millisecondes @@ -107,6 +108,12 @@ export class FootballFieldComponent { private isPlaying: boolean = false; // Timestamp de début de l'animation private animationStartTime: number = 0; + private isResizingLeft: boolean = false; + private isResizingRight: boolean = false; + private currentBlock: HTMLElement | null = null; + private initialMouseX:number = 0; + private initialBlockLeft:number = 0; + private initialBlockWidth:number = 0; public playerCount: number = 8; // Nombre de joueurs par défaut public plotCount: number = 2; // Nombre de plots par défaut @@ -143,6 +150,8 @@ export class FootballFieldComponent { // un bloc sur la timeline. public dragOffsetX: number = 0; + constructor(private renderer: Renderer2, private el: ElementRef) {} + ngOnInit() { this.ctx = this.canvas.nativeElement.getContext('2d')!; this.drawField(); @@ -653,6 +662,7 @@ export class FootballFieldComponent { endY: this.endY, duration: 1000 // Durée d'animation arbitraire, peut être ajustée }); + console.log("timeline player:", this.selectedPlayer.steps); // Initialiser l'index à l'étape précédente this.selectedPlayer.currentStepIndex = this.selectedPlayer.steps.length - 1; @@ -700,7 +710,30 @@ export class FootballFieldComponent { } } } +/* + private addHandleListener() { + // Utiliser Renderer2 pour accéder aux éléments DOM en toute sécurité + const timelineBlocks = this.el.nativeElement.querySelectorAll('.timeline-block'); + console.log("timelineBlocks:", timelineBlocks); + timelineBlocks.forEach((block: HTMLElement) => { + console.log("PLOP1"); + const leftHandle = block.querySelector('.handle-left'); + const rightHandle = block.querySelector('.handle-right'); + // Attacher les événements de redimensionnement + if (leftHandle) { + this.renderer.listen(leftHandle, 'mousedown', (event: MouseEvent) => this.onResizeStart(event, 'left', block)); + } + if (rightHandle) { + this.renderer.listen(rightHandle, 'mousedown', (event: MouseEvent) => this.onResizeStart(event, 'right', block)); + } + }); + + // Attacher les événements pour le document entier + this.renderer.listen(document, 'mousemove', this.onMouseMove.bind(this)); + this.renderer.listen(document, 'mouseup', this.onMouseUp.bind(this)); + } +*/ // Commencer a déplacer un élément du canvas startDragging(x:number, y:number) { if (this.isInsideCircle(this.ball.design, x, y)) { @@ -938,6 +971,80 @@ export class FootballFieldComponent { /* GESTION DE LA TIMELINE */ + onHandleMouseMove(event: MouseEvent) { + console.log("[onHandleMouseMove]"); + if (!this.currentBlock) return; + + const deltaX = event.clientX - this.initialMouseX; + + if (this.isResizingLeft) { + const newLeft = this.initialBlockLeft + deltaX; + const newWidth = this.initialBlockWidth - deltaX; + if (newWidth > 10) { // Empêcher une largeur trop petite + this.currentBlock.style.left = `${newLeft}px`; + this.currentBlock.style.width = `${newWidth}px`; + this.updateTimelineData(); // Mettre à jour les données de la timeline + } + } else if (this.isResizingRight) { + const newWidth = this.initialBlockWidth + deltaX; + if (newWidth > 10) { // Empêcher une largeur trop petite + this.currentBlock.style.width = `${newWidth}px`; + this.updateTimelineData(); // Mettre à jour les données de la timeline + } + } + } + + onHandleMouseUp() { + console.log("[onHandleMouseUp]"); + this.isResizingLeft = false; + this.isResizingRight = false; + this.currentBlock = null; + } + + onHandleMouseDown(event: MouseEvent, direction: 'left' | 'right') { + console.log("[onHandleMouseDown]"); + // Empêche le comportement par défaut (sélection de texte) + event.preventDefault(); + //this.currentBlock = block; + // Position initiale de la souris + //this.initialMouseX = event.clientX; + // Position initiale du bloc + //this.initialBlockLeft = block.offsetLeft; + // Largeur initiale du bloc + //this.initialBlockWidth = block.offsetWidth; + //console.log("[onResizeStart] (",this.initialMouseX, " - ", this.currentBlock); + //if (direction === 'left') { + // this.isResizingLeft = true; + //} else if (direction === 'right') { + // this.isResizingRight = true; + //} + } + + updateTimelineData() { + if (!this.currentBlock) return; + + const blockId = this.currentBlock.id; + const blockLeft = this.currentBlock.offsetLeft; + const blockWidth = this.currentBlock.offsetWidth; + + // Conversion des positions en temps sur la timeline (ex: 1px = 10ms) + const startTime = blockLeft * 10; + const endTime = (blockLeft + blockWidth) * 10; + + // Mettre à jour les données du bloc (par exemple pour un joueur) + const timelineStep = this.getTimelineStepById(blockId); + if (timelineStep) { + timelineStep.startTime = startTime; + timelineStep.endTime = endTime; + } + } + + getTimelineStepById(blockId: string): TimelineStep | null { + // Trouver le bloc correspondant aux données + // Cette fonction est un exemple. Adapte-la selon la manière dont tu stockes tes données + return this.players.find(player => `block-${player.id}` === blockId)?.steps[0] || null; + } + getMousePosOnTimeline(event: MouseEvent): { x: number } { // Récupérer l'élément avec la classe 'timeline' const timelineElement = document.querySelector('.timeline') as HTMLElement; @@ -996,7 +1103,6 @@ export class FootballFieldComponent { } onTLBallMouseMove(event: MouseEvent) { - console.log("[onTLBallMouseMove]"); if (this.isTimelineDragging && this.draggedTimelineBall) { const { x } = this.getMousePosOnTimeline(event); @@ -1193,7 +1299,7 @@ export class FootballFieldComponent { getTotalTimelineDuration(): number { // Calculer la durée totale de la timeline, par exemple basée sur la durée totale de l'animation - return 20000; // Par exemple, 10 000 ms pour une timeline de 10 secondes + return 10000; // Par exemple, 10 000 ms pour une timeline de 10 secondes } playTimeline() {