首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AFrame更新每个对象的material.offset

AFrame更新每个对象的material.offset
EN

Stack Overflow用户
提问于 2021-01-24 15:35:20
回答 1查看 416关注 0票数 0

我制作了一个AFrame组件来创建热点,当我用光标将它悬停时,我想要更改hotspot的material.offset.y。所以我首先尝试使用AFrame动画属性,但是很明显,我们不能用动画访问这个属性。

因此,我在hotspot JS对象中添加了一个eventListener,并更改了getObject3D('mesh').material.map.offset.y,但是当我将其悬停时,它会更新所有热点纹理,并且不知道为什么.我检查了这是否指向一个特定的热点,它是!所以我不明白为什么所有的纹理都在更新。

以下是代码:

代码语言:javascript
复制
<a-scene light="defaultLightsEnabled: false">
            <a-assets>
                <!-- Loading Scenes -->
                <img src="./assets/scene/scene.jpg"             id="scene_spherical" />

                <!-- Loading Icons -->
                <img src="./assets/icons/close.png"             id="icon_close" />
                <img src="./assets/icons/hotspot_sprite.png"    id="icon_hotspot" />
                <img src="./assets/icons/powered.png"           id="icon_powered" />
                <img src="./assets/icons/store.png"             id="icon_store" />

                <!-- Loading Mixins -->
                <a-mixin id="mixin_hotspot"
                         geometry="primitive: circle; radius: 0.25"
                         material="shader: flat; src: #icon_hotspot; transparent: true; repeat: 1 0.5; offset: 0 0.5;"
                ></a-mixin>
            </a-assets>

            <a-hotspot position="-6.33 0.30 -1.46" product="terrazzo_kaza_d" class="" id="hotspot_terrazzo_kaza_d"></a-hotspot>
            <a-hotspot position="5.43 -0.03 -6.21" product="meuble_tv" class="" id="hotspot_meuble_tv"></a-hotspot>
            <a-hotspot position="3.34 -0.81 -7.77" product="tapis_lake" class="" id="hotspot_tapis_lake"></a-hotspot>
            <a-hotspot position="5.30 1.22 -0.81" product="isole_escalier" class="" id="hotspot_isole_escalier"></a-hotspot>
            <a-hotspot position="-3.74 1.10 7.27" product="papier_peint" class="" id="hotspot_papier_peint"></a-hotspot>
            <a-hotspot position="3.09 -0.69 7.35" product="shooting_sol" class="" id="hotspot_shooting_sol"></a-hotspot>
            <a-hotspot position="-6.98 1.86 0.60" product="isole_cuisine" class="" id="hotspot_isole_cuisine"></a-hotspot>
            <a-hotspot position="-0.38 -0.32 5.98" product="isole_table_rectangulaire" class="" id="hotspot_isole_table_rectangulaire"></a-hotspot>
            <a-hotspot position="2.66 1.76 -8.15" product="isole_voilage" class="" id="hotspot_isole_voilage"></a-hotspot>
            <a-hotspot position="-1.13 -0.34 -7.41" product="isole_canape2" class="" id="hotspot_isole_canape2"></a-hotspot>

            <a-sky src="#scene_spherical"></a-sky>
            <a-camera wasd-controls="enabled: false;" cursor="rayOrigin: mouse"></a-camera>
        </a-scene>
代码语言:javascript
复制
import loadProduct from '../libs/shop'

AFRAME.registerPrimitive('a-hotspot', {
    defaultComponents: {
        'hotspot-popup': {}
    },

    mappings: {
        product: 'hotspot-popup.product',
    }
})

AFRAME.registerComponent('hotspot-popup', {
    schema: {
        // variables
        product: {type: 'string'}
    },

    init: function() {
        this.el.setAttribute('mixin', 'mixin_hotspot')

        this.setHover()
        this.setClick()
    },

    setHover() {

        this.el.addEventListener('mouseenter', () => {
            let material = this.el.getObject3D('mesh').material
            if (material.map) {
                material.map.offset.y = 0
                material.map.offset.x = 0
            }
        })
        this.el.addEventListener('mouseleave', () => {
            let material = this.el.getObject3D('mesh').material
            if (material.map) {
                material.map.offset.y = 0.5
                material.map.offset.x = 0
            }
        })
    },

    tick: function () {
        let cursorRotation = document.querySelector('a-camera').getAttribute('rotation')
        this.el.setAttribute('rotation', cursorRotation)
    },

    setClick: function () {
        this.el.addEventListener('click', () => {
            console.log('load', this.data.product)
            loadProduct(this.data.product)
        });
    }
})

因此,如果有人知道如何防止这种行为,请不要犹豫地评论这篇文章。

谢谢你,纳瓦莱克斯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-24 16:53:09

所有图像都被赋予相同偏移量的原因是,由于性能原因,a-frame重新使用纹理。

使用这样的设置:

代码语言:javascript
复制
<a-box material="src: #image"></a-box>
<a-sphere material="src: #image"></a-sphere >

如果同时记录这两个element.getObject3D("mesh").material.map.uuid,它们将是相同的(小提琴)。更新一个会影响另一个。

如果您在material中给它们一个初始偏移量(但是每个对象的偏移量不同):

代码语言:javascript
复制
<a-box material="src: #image; offset: 0 0.5"></a-box>
<a-sphere material="src: #image"></a-sphere >

a-frame将创建THREE.Texture()的另一个实例(小提琴)。

否则,您可以创建一个component,它将纹理替换为副本:

代码语言:javascript
复制
this.el.addEventListener("materialtextureloaded", e => {
  // grab the object
  let obj = this.el.getObject3D("mesh")
  // grab the texture
  let map = obj.material.map
  // create a new one
  const texture = new THREE.TextureLoader().load(map.image.src);
  // without wrapping, it will just "stretch" instead of "repeating"
  texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
  // assign the new texture
  obj.material.map = texture;
  // update the material
  obj.material.needsUpdate = true
})

这给我们带来了像这样的东西(包括动画、包装等)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65872503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档