【问题标题】:A-Frame: How to define a mixin dynamically at runtime?A-Frame:如何在运行时动态定义 mixin?
【发布时间】:2018-11-04 10:47:19
【问题描述】:

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

仅在运行时将 mixin 添加到 <a-assets> 似乎不起作用。 recommendation for adding image assets at runtime is to inline the image source and set it on the material directly。是否有一些类似的方法可以在运行时定义/更改 mixin?还是我只需要在应用了 mixin 的所有对象上设置相关属性(注意还要考虑到其他 mixin 稍后在 mixin 链中设置的属性或直接在对象本身上设置的属性)

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

【问题讨论】:

    标签: aframe


    【解决方案1】:

    抱歉,如果我误解了您的问题,但我似乎能够在运行时将 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>
    

    Here is a working glitch


    为了演示如何在场景运行后添加它,这里使用了带有 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>
    

    Here is a glitch of that


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

    // 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>
    

    And here is a glitch for that

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

    希望对你有帮助

    【讨论】:

    • 感谢您的详尽回答!不知道为什么动态添加 mixin 对我不起作用,但你根本没有误解——这正是我想要做的。
    • 没问题,很高兴为您提供帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    相关资源
    最近更新 更多