简体   繁体   English

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

[英]react, x3d custom element and event listener

I am using X3DOM inside my React application to display an external X3D file我在 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>
        );
    }
}

I would like to listen to the event emitted by isLoaded in loadSensor.我想在 loadSensor 中监听 isLoaded 发出的事件。 According to X3D specs根据 X3D 规范

An isLoaded TRUE event is generated when all of the elements have been loaded.当所有元素都已加载时,将生成 isLoaded TRUE 事件。 ( http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/networking.html#LoadSensor ) ( http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/networking.html#LoadSensor )

How can I do it using React ?我如何使用 React 做到这一点? This event is emitted after componentDidMount.此事件在 componentDidMount 之后发出。

Thank you !谢谢!

I don't think loadSensor has been implemented in X3DOM, cf https://doc.x3dom.org/author/nodes.html .我不认为loadSensor已经在 X3DOM 中实现,参见https://doc.x3dom.org/author/nodes.html But you can use a 'simple' onload event on your inline file:但是您可以onload联文件上使用“简单”的onload事件:

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

You can also check out https://github.com/x3dom/x3dom/blob/7d8ad13c2d2c17d9fd317e27b9e121379a53407f/test/regression-suite/test/cases/inlineEvents/inlineEvents.html for more examples.您还可以查看https://github.com/x3dom/x3dom/blob/7d8ad13c2d2c17d9fd317e27b9e121379a53407f/test/regression-suite/test/cases/inlineEvents/inlineEvents.html以获取更多示例。

I met the same problem as you do.我遇到了和你一样的问题。 I just write a simple polling in componentDidMount to solve this problem.我只是在componentDidMount写了一个简单的轮询来解决这个问题。

componentDidMount() {
    const poller = () => {
        this.timer = setTimeout(() => {
            const loaded = document.querySelector('inline').getAttribute('load')

            if (loaded) {
                // do sth
            } else {
                poller()
            }
        }, 500)
    }

    poller()
}

Here's my approach... Similar to @neo_seele's answer , but using rxjs这是我的方法...类似于@neo_seele 的答案,但使用 rxjs

EDIT added some timeout logic to avoid waiting indefinitely 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]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM