HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/pwa.sports-crowd.com/src/app/pages/dorsal/dorsal.page.ts
import { Component, OnInit, AfterViewInit, ViewChild, ViewChildren, QueryList } from "@angular/core";
import { ActionSheetController, IonSlides, Platform, ToastController } from "@ionic/angular";
import { DorsalService } from "../../services/dorsal.service";
import { CityService } from "../../services/city.service";
import { ImageService } from "../../services/image.service";
import { TranslateService } from "@ngx-translate/core";

@Component({
  selector: "app-dorsal",
  templateUrl: "./dorsal.page.html",
  styleUrls: ["./dorsal.page.scss"],
})
export class DorsalPage implements AfterViewInit, OnInit {

  MAX_SURNAME_CHARACTERS: number = 8

  @ViewChild(IonSlides) slideDorsal: IonSlides;

  @ViewChildren("canvasSlide") canvasList: QueryList<any>

  canvasElement: any;
  saveX: number;
  saveY: number;
  currentShirt: string
  currentDorsal: any
  dorsalList: any[] = []
  dorsalThenth: number = 0
  dorsalDigit: number = 1

  drawing = false;

  selectedColor = "#000";
  lineWidth = 5;

  texto = {
    nombre: "",
    numero: "",
  };
  // tslint:disable-next-line:max-line-length
  constructor(
    private plt: Platform,
    private toastCtrl: ToastController,
    private imageService: ImageService,
    private actionSheetCtrl: ActionSheetController,
    private dorsalService: DorsalService,
    private cityService: CityService,
    public translateService: TranslateService
  ) { }

  async ngOnInit() {
    await this.dorsalService.getListDorsal()
    if (!this.cityService._urlGallery) {
      this.cityService.getInfoHost();
    }
    this.dorsalList = this.dorsalService._dorsalList
  }

  ngAfterViewInit() {
    this.canvasList.changes.subscribe(() => {
      this.drawInitialDorsal()
    })
  }

  drawInitialDorsal() {
    if (this.canvasList.length > 0) {
      for (let canvasSlide of this.canvasList.toArray()) {
        this.canvasElement = canvasSlide.nativeElement
        canvasSlide.nativeElement.width = 300;
        canvasSlide.nativeElement.height = 300;
      }
      this.calculateDorsalNumberRedraw()
    }
  }

  selectColor(color) {
    this.selectedColor = color;
  }

  startDrawing(ev) {
    console.log("start: ", ev);
    this.drawing = true;
    const canvasPosition = this.canvasElement.getBoundingClientRect();
    console.log(canvasPosition);

    this.saveX = ev.pageX - canvasPosition.x;
    this.saveY = ev.pageY - canvasPosition.y;
  }

  endDrawing() {
    console.log("end");
    this.drawing = false;
  }

  moved(ev) {
    if (!this.drawing) {
      return;
    }
    console.log("move: ", ev);
    const canvasPosition = this.canvasElement.getBoundingClientRect();
    let ctx = this.canvasElement.getContext("2d");

    let currentX = ev.touches[0].pageX - canvasPosition.x;
    let currentY = ev.touches[0].pageY - canvasPosition.y;

    ctx.lineJoin = "round";
    ctx.strokeStyle = this.selectedColor;
    ctx.lineWidth = this.lineWidth;

    ctx.beginPath();
    ctx.moveTo(this.saveX, this.saveY);
    ctx.lineTo(currentX, currentY);
    ctx.closePath();

    ctx.stroke();

    this.saveX = currentX;
    this.saveY = currentY;
  }

  async drawCanvases() {
    if (this.texto.nombre.length > this.MAX_SURNAME_CHARACTERS) {
      this.texto.nombre = this.texto.nombre.slice(0, this.MAX_SURNAME_CHARACTERS)
    }
    let index = 0
    for (let canvasSlide of this.canvasList.toArray()) {
      this.canvasElement = canvasSlide.nativeElement
      this.currentDorsal = this.dorsalList[index]
      this.currentShirt = this.dorsalList[index].image
      await this.TextCanvas()
      index++
    }
  }

  async TextCanvas() {
    await this.setShirt(this.currentShirt)
    let ctx = this.canvasElement.getContext("2d");
    let ctx2 = this.canvasElement.getContext("2d");
    let posNombre = 85;
    let posNumero = 130;

    let name = this.texto.nombre.toUpperCase()
    if (!name || name.length == 0) {
      name = "?"
    }

    ctx.beginPath();
    ctx.fillStyle = this.currentDorsal.text_color;
    ctx.font = "bold 25px arial";
    ctx.textAlign = "center";
    ctx.fillText(name, this.canvasElement.width / 2, posNombre + this.currentDorsal.offset);
    ctx.closePath();

    ctx2.beginPath();
    ctx2.strokeStyle = this.currentDorsal.text_color;
    ctx2.font = "bold 50px arial";
    ctx2.textAlign = "center";
    ctx2.fillText(this.texto.numero, this.canvasElement.width / 2, posNumero + (this.currentDorsal.offset_number ? this.currentDorsal.offset_number : 0));
    ctx2.closePath();
  }

  deleteCanvas() {
    let ctx = this.canvasElement.getContext("2d");
    ctx.clearRect(0, 0, this.canvasElement.width, this.canvasElement.height);
  }

  async setShirt(url_asset: string) {
    this.deleteCanvas();
    this.currentShirt = url_asset;
    let background = new Image();
    background.crossOrigin = "*";
    background.src = this.cityService._urlGallery + 'dorsal/' + url_asset;
    let ctx = this.canvasElement.getContext("2d");
    return new Promise<void>((resolve, reject) => {
      background.onload = () => {
        ctx.drawImage(background, 0, 0, this.canvasElement.width, this.canvasElement.height);
        resolve()
      };
    })
  }

  async exportCanvasImage() {
    let index = await this.slideDorsal.getActiveIndex()
    this.canvasElement = this.canvasList.toArray()[index].nativeElement
    await this.imageService.exportCanvasImage(this.canvasElement, this.translateService.instant("SUCCESS_DOWNLOAD"))
  }

  onClick() {
    this.presentActionSheet();
  }

  async presentActionSheet() {
    const actionSheet = await this.actionSheetCtrl.create({
      header: "Set Dorsal",
      cssClass: "my-custom-class",
      buttons: [
        {
          text: "Home",
          icon: "shirt-outline",
          handler: () => {
            this.setShirt("./assets/img/dorsal/256 RojaAzul.png");
          },
        },
        {
          text: "Away",
          icon: "shirt-outline",
          handler: () => {
            this.setShirt("./assets/img/dorsal/256 Amarilla.png");
          },
        },
        {
          text: "106 años",
          icon: "shirt-outline",
          handler: () => {
            this.setShirt("./assets/img/dorsal/256 Blanca.png");
          },
        },
        {
          text: "Tercera equipación",
          icon: "shirt-outline",
          handler: () => {
            this.setShirt("./assets/img/dorsal/256 Negra.png");
          },
        },
        {
          text: "Cancel",
          icon: "close",
          role: "cancel",
          handler: () => {
            console.log("Cancel clicked");
          },
        },
      ],
    });
    await actionSheet.present();
  }

  upDorsalNumber() {
    if (this.dorsalDigit < 9) {
      this.dorsalDigit++
      this.calculateDorsalNumberRedraw()
    }
  }

  downDorsalNumber() {
    if (this.dorsalDigit > 0) {
      this.dorsalDigit--
      this.calculateDorsalNumberRedraw()
    }
  }

  upDorsalTenth() {
    if (this.dorsalThenth < 9) {
      this.dorsalThenth++
      this.calculateDorsalNumberRedraw()
    }
  }

  downDorsalTenth() {
    if (this.dorsalThenth > 0) {
      this.dorsalThenth--
      this.calculateDorsalNumberRedraw()
    }
  }

  isDownloadDisabled() {
    return !this.texto.nombre || this.texto.nombre.length == 0 || this.canvasList.length == 0
  }

  private calculateDorsalNumberRedraw() {
    this.texto.numero = "" + (this.dorsalDigit + (this.dorsalThenth * 10))
    this.drawCanvases()
  }
}