Search code examples
javascriptangulardomcanvasngfor

How to use <canvas> generated with *ngFor in Angular


I am trying to create a list of div elements which contains canvas elements using *ngFor directive in my Angular app. After (click) event on a particular canvas I would like to update the array (which I iterate over with *ngFor) at the relevant index and draw a shape on that canvas.

I've tried to set a reference to every canvas via #elementRef in my *ngFor loop and pass the reference to my drawing function (myDrawingFunction(elementRef)), but after array updates the function cannot properly locate the clicked canvas to draw on.

Do you have any suggestions what is the best approach to achieve this?

Thank you have much for any help!


Solution

  • I would try using an index in your html as so then use elementRef and the specific id to retrieve the element and manipulate it you also need to imperatively make usage of trackBy your dom may be messed up after the update of your array:

    <div *ngFor="let a of arrayOfIndexes;index as i; trackBy:trackByFn">
      <canvas attr.id="canvas-{{i}}" (click)="myDrawingFunction(i)"></canvas>
    </div>
    

    and in your ts

    ...
    arrayOfIndexes = [0, 1, 2, 3, 4, 5, 6]
    ...
    constructor (private el:ElementRef){}
    ...
    trackByFn(index){
      return (index);
    }
    myDrawingFunction(index:number){
      //here you retrieve your element by id eg: '#canvas-2'
      let canvas = <HTMLCanvasElement>this.el.nativeElement.querySelector('#canvas-' + index);
      let ctx = canvas.getContext('2d') //just an example
      ...
    }
    
    ...
    

    StackBlitz demo

    REFERENCE

    ngForOf