diff --git a/package-lock.json b/package-lock.json
index 67ab09a..6fdb1a0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@angular/animations": "^18.2.0",
+ "@angular/cdk": "^18.2.6",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
@@ -351,6 +352,23 @@
}
}
},
+ "node_modules/@angular/cdk": {
+ "version": "18.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.6.tgz",
+ "integrity": "sha512-Gfq/iv4zhlKYpdQkDaBRwxI71NHNUHM1Cs1XhnZ0/oFct5HXvSv1RHRGTKqBJLLACaAPzZKXJ/UglLoyO5CNiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "optionalDependencies": {
+ "parse5": "^7.1.2"
+ },
+ "peerDependencies": {
+ "@angular/common": "^18.0.0 || ^19.0.0",
+ "@angular/core": "^18.0.0 || ^19.0.0",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
"node_modules/@angular/cli": {
"version": "18.2.6",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.6.tgz",
@@ -6601,7 +6619,7 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "dev": true,
+ "devOptional": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
@@ -10772,7 +10790,7 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"entities": "^4.4.0"
diff --git a/package.json b/package.json
index 0e6f455..b2409a3 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
{
"name": "football-drawing",
- "version": "0.0.0",
+ "version": "0.1.0",
"scripts": {
"ng": "ng",
- "start": "ng serve",
+ "start": "ng serve --host 0.0.0.0 --disable-host-check",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
@@ -11,6 +11,7 @@
"private": true,
"dependencies": {
"@angular/animations": "^18.2.0",
+ "@angular/cdk": "^18.2.6",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 36093e1..a64bc90 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,336 +1,2 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Hello, {{ title }}
-
Congratulations! Your app is running. đ
-
-
-
-
- @for (item of [
- { title: 'Explore the Docs', link: 'https://angular.dev' },
- { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
- { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
- { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
- { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
- ]; track item.title) {
-
- {{ item.title }}
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index e90a6bf..2ea4a9d 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
+import { FootballFieldComponent } from './football-field/football-field.component';
@Component({
selector: 'app-root',
standalone: true,
- imports: [RouterOutlet],
+ imports: [RouterOutlet, FootballFieldComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
new file mode 100644
index 0000000..3d42796
--- /dev/null
+++ b/src/app/app.module.ts
@@ -0,0 +1,9 @@
+import { NgModule } from '@angular/core';
+import { FootballFieldComponent } from './football-field/football-field.component';
+
+@NgModule({
+ declarations: [
+ FootballFieldComponent
+ ],
+})
+export class AppModule {}
diff --git a/src/app/football-field/football-field.component.css b/src/app/football-field/football-field.component.css
new file mode 100644
index 0000000..12c7f85
--- /dev/null
+++ b/src/app/football-field/football-field.component.css
@@ -0,0 +1,63 @@
+.football-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 20px;
+}
+
+.toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 620px; /* largeur égale au canvas pour aligner */
+ margin-bottom: 10px;
+}
+
+canvas {
+ border: 2px solid #000000; /* Bordure noire pour le canvas */
+ margin-top: 10px;
+}
+
+.color-palette {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 10px;
+}
+
+.shape-selector {
+ display: flex;
+ align-items: center;
+ margin-right: 10px;
+}
+
+.color-box {
+ width: 30px;
+ height: 30px;
+ margin: 0 5px;
+ border-radius: 50%;
+ border: 2px solid transparent;
+ cursor: pointer;
+ transition: border 0.2s;
+}
+
+.color-box.selected {
+ border: 2px solid #000000;
+}
+
+.controls {
+ margin-top: 15px;
+}
+
+.clear-button {
+ padding: 10px 20px;
+ background-color: #ff4d4d; /* Rouge vif */
+ color: white;
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+ border-radius: 5px;
+}
+
+.clear-button:hover {
+ background-color: #ff1a1a; /* couleur plus foncée au survol */
+}
diff --git a/src/app/football-field/football-field.component.html b/src/app/football-field/football-field.component.html
new file mode 100644
index 0000000..bca802b
--- /dev/null
+++ b/src/app/football-field/football-field.component.html
@@ -0,0 +1,33 @@
+
+
diff --git a/src/app/football-field/football-field.component.spec.ts b/src/app/football-field/football-field.component.spec.ts
new file mode 100644
index 0000000..7b49806
--- /dev/null
+++ b/src/app/football-field/football-field.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FootballFieldComponent } from './football-field.component';
+
+describe('FootballFieldComponent', () => {
+ let component: FootballFieldComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [FootballFieldComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(FootballFieldComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/football-field/football-field.component.ts b/src/app/football-field/football-field.component.ts
new file mode 100644
index 0000000..446b7a8
--- /dev/null
+++ b/src/app/football-field/football-field.component.ts
@@ -0,0 +1,213 @@
+import { Component, ViewChild, ElementRef, HostListener } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+@Component({
+ selector: 'app-football-field',
+ standalone: true,
+ imports: [
+ CommonModule,
+ FormsModule
+ ],
+ templateUrl: './football-field.component.html',
+ styleUrl: './football-field.component.css'
+})
+export class FootballFieldComponent {
+ @ViewChild('canvas', { static: true }) canvas!: ElementRef;
+ private ctx!: CanvasRenderingContext2D;
+ private drawing = false;
+ private lastX = 0;
+ private lastY = 0;
+ private startX = 0;
+ private startY = 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
+
+ ngOnInit() {
+ this.ctx = this.canvas.nativeElement.getContext('2d')!;
+ this.drawField();
+ }
+
+ // Dessine le terrain de football
+ private drawField() {
+ const ctx = this.ctx;
+ const canvas = this.canvas.nativeElement;
+
+ // Efface le canvas
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ // Dessine le terrain vert
+ ctx.fillStyle = '#3ba047'; // Vert pelouse
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+ // Bordures blanches du terrain
+ ctx.strokeStyle = '#ffffff'; // Blanc
+ ctx.lineWidth = 3;
+
+ // Ligne de touche extérieure
+ ctx.strokeRect(10, 10, canvas.width - 20, canvas.height - 20);
+
+ // Ligne médiane
+ ctx.beginPath();
+ ctx.moveTo(canvas.width / 2, 10);
+ ctx.lineTo(canvas.width / 2, canvas.height - 10);
+ ctx.stroke();
+
+ // Cercle central
+ ctx.beginPath();
+ ctx.arc(canvas.width / 2, canvas.height / 2, 70, 0, Math.PI * 2);
+ ctx.stroke();
+
+ // Point central
+ ctx.fillStyle = '#ffffff'; // Blanc
+ ctx.beginPath();
+ ctx.arc(canvas.width / 2, canvas.height / 2, 5, 0, Math.PI * 2);
+ ctx.fill();
+
+ // Points de penalty
+ ctx.beginPath();
+ ctx.arc(90, canvas.height / 2, 3, 0, Math.PI * 2); // Point gauche
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(canvas.width - 90, canvas.height / 2, 3, 0, Math.PI * 2); // Point droit
+ ctx.fill();
+
+ // Surfaces de réparation
+ ctx.strokeRect(10, canvas.height / 2 - 150, 120, 300); // Surface gauche
+ ctx.strokeRect(canvas.width - 130, canvas.height / 2 - 150, 120, 300); // Surface droite
+
+ // Surface de but
+ ctx.strokeRect(10, canvas.height / 2 - 75, 50, 150); // Surface gauche
+ ctx.strokeRect(canvas.width - 60, canvas.height / 2 - 75, 50, 150); // Surface droite
+
+ // Corners
+ ctx.beginPath();
+ ctx.arc(10, 10, 20, 0, Math.PI / 2);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(canvas.width - 10, 10 , 20, Math.PI / 2, Math.PI );
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(canvas.width - 10, canvas.height - 10, 20, Math.PI, -Math.PI /2 );
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(10, canvas.height - 10 , 20, Math.PI * 3/2, Math.PI * 2 );
+ ctx.stroke();
+ }
+
+ // Réinitialise le dessin sans effacer le terrain
+ clearCanvas() {
+ this.drawField();
+ }
+
+ // Change la couleur sélectionnée
+ setColor(color: string) {
+ this.selectedColor = color;
+ }
+
+ // Commence à dessiner quand la souris est enfoncée
+ startDrawing(event: MouseEvent) {
+ this.drawing = true;
+ const { x, y } = this.getMousePos(event);
+ this.startX = x;
+ this.startY = y;
+ this.lastX = x;
+ this.lastY = y;
+ }
+
+// // Dessine en suivant la souris
+// draw(event: MouseEvent) {
+// if (!this.drawing) return;
+//
+// const { x, y } = this.getMousePos(event);
+// this.ctx.strokeStyle = this.selectedColor; // Utilise la couleur selectionnée
+// this.ctx.lineWidth = 2;
+// this.ctx.beginPath();
+// this.ctx.moveTo(this.lastX, this.lastY);
+// this.ctx.lineTo(x, y);
+// this.ctx.stroke();
+//
+// this.lastX = x;
+// this.lastY = y;
+// }
+ // Dessiner en fonction de la forme sélectionnée
+ draw(event: MouseEvent) {
+ if (!this.drawing) return;
+
+ const { x, y } = this.getMousePos(event);
+ const ctx = this.ctx;
+
+ // Effacer ce qui a été dessiné pendant le déplacement
+ //this.drawField();
+
+ // Si aucune forme n'est sélectionnée, on dessine librement
+ if (this.selectedShape === 'none') {
+ ctx.strokeStyle = this.selectedColor;
+ ctx.lineWidth = 5;
+ ctx.beginPath();
+ ctx.moveTo(this.lastX, this.lastY);
+ ctx.lineTo(x, y);
+ ctx.stroke();
+ } else {
+ // Sauvegarder le contexte pour ne pas effacer le terrain
+ ctx.save();
+ ctx.strokeStyle = this.selectedColor;
+ ctx.lineWidth = 5;
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+
+ switch (this.selectedShape) {
+ case 'rectangle':
+ ctx.strokeRect(this.startX, this.startY, x - this.startX, y - this.startY);
+ break;
+ case 'circle':
+ const radius = Math.sqrt((x - this.startX) ** 2 + (y - this.startY) ** 2);
+ ctx.beginPath();
+ ctx.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
+ ctx.stroke();
+ break;
+ case 'line':
+ ctx.beginPath();
+ ctx.moveTo(this.startX, this.startY);
+ ctx.lineTo(x, y);
+ ctx.stroke();
+ break;
+ }
+
+ ctx.restore();
+ }
+
+ this.lastX = x;
+ this.lastY = y;
+ }
+
+
+ // ArrĂȘte de dessiner quand la souris est relĂąchĂ©e
+ stopDrawing() {
+ this.drawing = false;
+ }
+
+ // Obtient la position de la souris sur le canvas
+ private getMousePos(event: MouseEvent) {
+ const rect = this.canvas.nativeElement.getBoundingClientRect();
+ return {
+ x: event.clientX - rect.left,
+ y: event.clientY - rect.top,
+ };
+ }
+
+ // Méthode pour effacer le canvas et redessiner le terrain
+ clearDrawings() {
+ this.ctx.clearRect(0,
+ 0,
+ this.canvas.nativeElement.width,
+ this.canvas.nativeElement.height);
+ this.drawField(); // Redessine le terrain de football
+ }
+}
diff --git a/src/main.ts b/src/main.ts
index 35b00f3..ca05026 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -2,5 +2,7 @@ import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
+// import { AppModule } from './app/app.module';
+
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));