簡體   English   中英

react、x3d 自定義元素和事件監聽器

[英]react, x3d custom element and event listener

我在 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 之后發出。

謝謝!

我不認為loadSensor已經在 X3DOM 中實現,參見https://doc.x3dom.org/author/nodes.html 但是您可以onload聯文件上使用“簡單”的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以獲取更多示例。

我遇到了和你一樣的問題。 我只是在componentDidMount寫了一個簡單的輪詢來解決這個問題。

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

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

    poller()
}

這是我的方法...類似於@neo_seele 的答案,但使用 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]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM