首页 > 解决方案 > A-Frame:如何在运行时动态定义 mixin?

问题描述

A-Frame Mixins进入<a-assets>element,必须在渲染场景之前定义。这对于预加载/缓存图像、视频等很有意义,但似乎应该有一种方法可以动态创建和使用 mixin。

只是<a-assets>在运行时添加 mixin 似乎不起作用。在运行时添加图像资源的建议是内联图像源并直接设置在材质上。是否有一些类似的方法可以在运行时定义/更改 mixin?还是我只需要在应用了 mixin 的所有对象上设置相关属性(注意还要考虑到 mixin 链中稍后由其他 mixin 设置的属性或直接在对象本身上设置的属性)

编辑:看起来aframe-asset-on-demand-component旨在为图像/视频资产执行此操作。不清楚是否适用于 mixins,但它也没有在一年内更新。这是(半)官方推荐的解决方案吗?

标签: aframe

解决方案


抱歉,如果我误解了您的问题,但我似乎能够在运行时将 mixins 添加到资产标签中。基本版本意味着编写如下组件;

 // add assets at run time
 AFRAME.registerComponent('addasset', {

        init: function () {          
          var assets = document.getElementsByTagName('a-assets')[0]
          var mixin = document.createElement('a-mixin')
          mixin.setAttribute('id', 'makeitred')
          mixin.setAttribute('material', 'color: red')
          assets.appendChild(mixin)
        },

 });

然后将该组件附加到场景中,如下所示;

<a-scene addasset>
  <a-assets>
  </a-assets>
  <a-cylinder 
    mixin="makeitred" 
    position="0 0.5 -3">
  </a-cylinder>
</a-scene>

这是一个工作故障


为了演示如何在场景运行后添加它,这里使用相同组件的一个版本,setTimeout用于演示稍后如何添加 mixin。

// add assets at run time, delayed
      AFRAME.registerComponent('addasset', {

        init: function () {  
          setTimeout(function(){ 
            var assets = document.getElementsByTagName('a-assets')[0]
            var mixin = document.createElement('a-mixin')
            var cylinder = document.getElementsByTagName('a-cylinder')[0]
            mixin.setAttribute('id', 'makeitred')
            mixin.setAttribute('material', 'color: red')
            assets.appendChild(mixin)
            cylinder.setAttribute('mixin', 'makeitred')
          }, 2000);

        },

      });

然后是稍后将添加 mixin 属性的 HTML

<a-scene addasset>
      <a-assets>
      </a-assets>
      <a-cylinder 
        position="0 0.5 -3">
      </a-cylinder>
</a-scene>

这是一个小故障


为了探索,这里是相同的设置,但由示例事件触发。首先是相同的组件,但有一个事件监听器

// add assets at run time, triggered by event
      AFRAME.registerComponent('addasset', {

        init: function () {  

          document.addEventListener("testevent", function(){
              var assets = document.getElementsByTagName('a-assets')[0]
              var mixin = document.createElement('a-mixin')
              var cylinder = document.getElementsByTagName('a-cylinder')[0]
              mixin.setAttribute('id', 'makeitred')
              mixin.setAttribute('material', 'color: red')
              assets.appendChild(mixin)
              cylinder.setAttribute('mixin', 'makeitred')
          });

        },

      });

然后是一个组件,它发出一个事件进行测试

 // test event to trigger adding of mixin
  AFRAME.registerComponent('testevent', {

    init: function () {  

      var self = this.el

      setTimeout(function(){ 
        self.emit("testevent") 
      }, 3000);

    },

  });

然后是 HTML,和以前一样,但包括一个发出事件的测试实体

<a-scene addasset>
      <a-assets>
      </a-assets>
      <a-cylinder 
        position="0 0.5 -3">
      </a-cylinder>
      <a-entity 
        testevent>
      </a-entity>
</a-scene>

这是一个小故障

因此,您可以将它们混合起来,将 mixin 添加到资产但延迟/触发事件添加属性,或者将 mixin 添加到具有属性的资产但延迟/触发事件在目标元素上设置该属性。

我希望这会有所帮助


推荐阅读