Search code examples
angulartypescriptaframe

Problems with a script in Angular and typescript using A-Frame


I have a problem in angular with a script for a piece of HTML code that uses A-Frame to make 3D objects and interact with it. The problem is that you can give play with sound as an attribute of a-frame but when the script is tried or from the typescript it does not work and everything has been tried. I hope they can help me

<script>
AFRAME.registerComponent('play', {
  init: function () {
    console.log("entro al script play");
    var variable = document.querySelector('#yellow');
    this.variable.addEventListener('click' , function(){
      variable.components.sound.playSound();
    });
  }
});
AFRAME.registerComponent('stop', {
  init: function () {
    console.log("entro al script stop");
    var variable = document.querySelector('#yellow');
    this.variable.addEventListener('click' , function(){
      variable.components.sound.stopSound();
    });
  }
});
<a-box id="yellow" color="yellow" position="0 0 -5" sound="src:#bichota">
  <!-- Play -->
  <a-sphere color="green" radius="0.25" position="-1 1 0" play></a-sphere>
  <!-- Stop -->
  <a-sphere color="red" radius="0.25" position="1 1 0" stop></a-sphere>
</a-box>

In typescript I get this error "Property 'components' does not exist on type 'Element'"

var entity= document.querySelector('#yellow') ;
if(entity != null){
  console.log("enity" , entity);
  entity.components.sound.playSound();
}

Solution

  • To use aframe in Angular, it is better to follow the angular practice instead of involving DOM operations directly.

    For full demonstration, you can clone my demo project on Github.

    app.component.html

    <a-scene>
        <a-assets>
          <audio id="bichota" src="../assets/test.mp3" preload="auto"></audio>
        </a-assets>
    
        <a-box id="yellow" color="yellow" position="0 0 -5" sound="src:#bichota" #yellowBox>
          <a-sphere cursor="rayOrigin: mouse" color="green" radius="0.25" position="-1 1 0" (click)="playSound()"></a-sphere>
          <a-sphere cursor="rayOrigin: mouse" color="red" radius="0.25" position="1 1 0"  (click)="stopSound()"></a-sphere>
        </a-box>
    </a-scene>
    
    • #yellowBox - for angular to reference it later on in the component logic
    • cursor="rayOrigin: mouse" - for enabling element clicking by mouse. there is a need to specify cursor in the a-frame element. For details, you can read the doc.
    • (click)="xxxx()" - for binding click event

    app.component.ts

    export class AppComponent {
      // refer to #yellowBox in the html
      @ViewChild('yellowBox') yellowBox!: ElementRef;
      
      playSound() {
        console.log("play")
        this.yellowBox.nativeElement.components.sound.playSound();
      }
    
      stopSound() {
        console.log("stop")
        this.yellowBox.nativeElement.components.sound.stopSound();
      }
    }