A-Frame 在 运行 次更改图像

A-Frame change image on run time

我想在从服务器或简单网址加载资产后加载图像。

这是我来自 https://youmustfight.github.io/aframe-asset-lazy-load/no-component 的 index.html。

var assets = $("a-assets");
var sphere1 = $('.sphere-1');
var sphere1 = $('.sphere-2');

// Example Sphere 1
setTimeout(function() {
  // Append Img Element to Assets - Immediately starting load of content
  assets.prepend('<img id="example-sphere-1" src="background.png">');
  //assets.prepend('<img id="example-sphere-1" src="../background.png">');
  // Upon Image Load being Done - Update Skybox Entity
  $('#example-sphere-1').on('load', function() {
    $('a-entity.sphere-1').attr("material", "src: #example-sphere-1");
  });
});

function getPokemonAtIndex(pokeIndex) {
  var pokeSprite;
  var baseURL = "https://pokeapi.co/api/v2/";
  var pURL = baseURL + "pokemon/" + pokeIndex.toString();

  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var myObj = JSON.parse(this.responseText);
      pokeSprite = myObj.sprites.front_default;
    }
  };
  xmlhttp.open("GET", pURL, true);
  xmlhttp.send();
  return pokeSprite;
}

setTimeout(function() {
  assets.prepend('<img id="example-sphere-1" src="getPokemonAtIndex(800)">');
  $('#example-sphere-2').on('load', function() {
    $('a-entity.sphere-2').attr("material", "src: #example-sphere-2");
  });
}, 1550);
<html>

<head>
  <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
  <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.js"></script>
</head>

<body>
  <a-assets></a-assets>
  <a-scene>
    <a-assets>
    </a-assets>
    <!-- <a-image position="-150 0 -1500" rotation="0 0 0" height="1000" width="1000" src="../background.png"></a-image> -->
    <a-entity class="sphere-1" geometry="primitive: sphere;
                  radius: 200;
                  segments-width: 64;
                  segments-height: 64;" material="" scale="-1 1 1" rotation="0 -105 0" position="-400 0 -700"></a-entity>
    <a-entity class="sphere-2" geometry="primitive: sphere;
                  radius: 200;
                  segments-width: 64;
                  segments-height: 64;" material="" scale="-1 1 1" rotation="0 -105 0" position="300 0 -700"></a-entity>
  </a-scene>
  <script src="example.js"></script>
</body>

</html>

getPokemonAtIndex function 从 id 为 800 的口袋妖怪中检索精灵的地址。控制台日志显示了该地址。我应该使用 fileLoader/imageLoader 还是其他的?

有人知道该怎么做吗?

<a-assets> 应该用于预加载。您可以像这样简单地使用图像 URL 作为 material 来源 (element.setAttribute("material", "src", URL)):

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
  AFRAME.registerComponent("foo", {
    init: function() {
      // switch the material source whenever a new sprite is ready
      this.el.addEventListener("sprite-ready", e => {
        this.el.setAttribute("material", "src", this.pokeSrc)
      })

      // iterate through the pokedex
      var i = 1;
      setInterval(e => {
        this.requestPokemonAtIndex(i++);
        if (i > 150) i = 1;
      }, 750)
    },
    // request an image, emit an event when the resource is ready
    requestPokemonAtIndex: function(pokeIndex) {
      var self = this;
      var baseURL = "https://pokeapi.co/api/v2/";
      var pURL = baseURL + "pokemon/" + pokeIndex.toString();

      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          var myObj = JSON.parse(this.responseText);
          let pokeSprite = myObj.sprites.front_default;
          self.pokeSrc = pokeSprite;
          self.el.emit("sprite-ready")
        }
      };
      xmlhttp.open("GET", pURL, true);
      xmlhttp.send();
    }
  })
</script>
<a-scene>
  <a-box position="0 1 -3" rotation="0 45 0" foo></a-box>
  <a-sky color="#ECECEC"></a-sky>
</a-scene>

您也可以使用 THREE.ImageLoader,但您必须深入了解底层 three.js 层:

// load the image
const image = new THREE.ImageLoader().load(URL);
// grab the mesh
const mesh = element.getObject3D("mesh")
// grab the material reference
const material = mesh.material;
// use the loaded image
material.map = image;
// reset the material
material.needsUpdate = true;