代码之家  ›  专栏  ›  技术社区  ›  Franckl

react、x3d自定义元素和事件侦听器

  •  0
  • Franckl  · 技术社区  · 8 年前

    我在React应用程序中使用X3DOM来显示外部X3D文件

    export class X3DComponent extends React.Component {
        constructor(props) {
            super(props);
    
            this.x3dLoaded = this.x3dLoaded.bind(this);
        }
    
        x3dLoaded(e){
            console.log('inside');
            console.log(e);
        }
    
        render() {
            return (
                <div>
                    <x3d id='x3dElement' is='x3d'>
                        <scene is="x3d">
                            <navigationInfo type='EXAMINE' is='x3d'/>
                            <viewpoint id="viewPoint" is="x3d"
                                       centerOfRotation='0 0 0 '
                                       position="-1.94639 1.79771 -2.89271"
                                       orientation="0.03886 0.99185 0.12133 3.7568"
                                       isActive="true"
                            />
                            <inline id="x3dInline" DEF='x3dInline' nameSpaceName="tanatloc" is="x3d" mapDEFToID="true"
                                    url={this.props.fileUrl}/>
                            <loadSensor is='x3d' DEF='InlineLoadSensor' isLoaded={this.x3dLoaded} timeOut='5'>
                                <inline is='x3d' USE='x3dInline' containerField='watchList'/>
                            </loadSensor>
                        </scene>
                    </x3d>
                </div>
            );
        }
    }
    

    我想听听loadSensor中isLoaded发出的事件。 根据X3D规范

    加载所有元素后,将生成isLoaded TRUE事件。( http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/networking.html#LoadSensor )

    如何使用React进行操作?此事件在componentDidMount之后发出。

    非常感谢。

    3 回复  |  直到 8 年前
        1
  •  1
  •   mistapink Tsyvarev    8 年前

    我不认为 loadSensor 已在X3DOM、c.f.中实现。 https://doc.x3dom.org/author/nodes.html . 但你可以用“简单” onload 内联文件上的事件:

    <inline id="x3dInline" DEF='x3dInline' nameSpaceName="tanatloc" is="x3d"
    mapDEFToID="true" url={this.props.fileUrl} onload={this.x3dLoaded} />
    

    您也可以退房 https://github.com/x3dom/x3dom/blob/7d8ad13c2d2c17d9fd317e27b9e121379a53407f/test/regression-suite/test/cases/inlineEvents/inlineEvents.html 更多示例。

        2
  •  1
  •   neo_seele    7 年前

    我遇到了和你一样的问题。我只是在 componentDidMount 来解决这个问题。

    componentDidMount() {
        const poller = () => {
            this.timer = setTimeout(() => {
                const loaded = document.querySelector('inline').getAttribute('load')
    
                if (loaded) {
                    // do sth
                } else {
                    poller()
                }
            }, 500)
        }
    
        poller()
    }
    
        3
  •  0
  •   Nicolas Mariano Obregon    5 年前

    这是我的方法。。。类似 @neo_seele's answer ,但使用rxjs

    EDIT添加了一些超时逻辑,以避免无限期等待

        import { interval, timer } from 'rxjs';
        import { takeUntil, takeWhile } from 'rxjs/operators';
    
        //reference to the <inline> element
        const refInline = useRef(null);
        const [error, setError] = useState("");
    
        useEffect(() => {
            window.x3dom && window.x3dom.reload();
            //check every 250ms if model is already loaded, when it does, it calls the complete callback
            //however if after 5s it hasn't loaded, it shows an error
            interval(250)
                .pipe(takeUntil(timer(5000)))
                .pipe(takeWhile(()=>!refInline.current.querySelectorAll("Shape").length))
                .subscribe({complete: ()=>{
                    if (!refInline.current.querySelectorAll("Shape").length){
                        setError(`Model could not be loaded, please check ${conf.url} format and try again.`);
                    } else {
                        // ... my logic
                    }
                }});
        }, [...dependencies]);