Home > database >  getBoundingClientRect is not a function on Angular 11 - Three.js
getBoundingClientRect is not a function on Angular 11 - Three.js

Time:11-02

I try several time to solve this issue but I have not been able to find a solution, I hope that someone could help me. I'm trying to provide information about the size of the images on my webpage to implement the scroll later, this is my code:

  ngAfterViewInit() {
    let images = [{...document.querySelectorAll('img')}];
    this.addImages(images);
  }

 addImages(images) {
    this.imageStore = images.map(img => {
      let bounds = img.getBoundingClientRect();
      console.log(bounds);

      let geometry = new THREE.PlaneBufferGeometry(bounds.width, bounds.height, 1, 1);
      let material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
      let mesh = new THREE.Mesh(geometry, material)
      this.scene.add(mesh);

      return {
        img: img,
        mesh: mesh,
        top: bounds.top,
        left: bounds.left,
        width: bounds.width,
        height: bounds.height
      }
    })
  }

That code should return the sizes of the images on my HTML page, but I got the error

CodePudding user response:

  ngAfterViewInit() {
    const images = Array.from(document.querySelectorAll('img'));

    const imgObj = images.map((img) => {
      const bounds = img.getBoundingClientRect();
      return {
        img,
        name: img.name,
        top: bounds.top,
        bottom: bounds.bottom,
        left: bounds.left,
        width: bounds.width,
        height: bounds.height,
      };
    });

    console.log('Applying...');
    console.log({ imgObj });
  }

https://stackblitz.com/edit/angular-ivy-yeu1hx?file=src/app/app.component.ts

CodePudding user response:

I think that the problem is that you need wait to the images are loaded.

if your images are in an array (some like)

  images=["https://picsum.photos/200/300?random=1",
          "https://picsum.photos/200/300?random=2"]

You show it in a *ngFor, use the event (load)

<ng-container *ngFor="let img of images">
<img #mimg [src]="img" (load)="pushData(mimg)">
</ng-container>

  array:any[]=[]
  pushData(el:any)
  {
   this.array.push(el.getBoundingClientRect())
   if (this.array.length==this.images.length)
   {
       console.log("all images loaded")
       ..do something..
   }
  }

Update as we don't know the order the images are loaded, we can force passing the index

<ng-container *ngFor="let img of images;let i=index">
<img #mimg [src]="img" (load)="pushData(mimg,i)">
</ng-container>
  pushData(el:any,index:number)
  {
   this.array[index]={
     ...el.getBoundingClientRect(),
     img:el
   }
   if (!this.array.find(x=>!x))
   {
          console.log("all images loaded")
   }
  }
  • Related