反应,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 规范
An isLoaded TRUE event is generated when all of the elements have been loaded. (http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/networking.html#LoadSensor)
我如何使用 React 来做到这一点?此事件在 componentDidMount.
之后发出
谢谢!
我认为 loadSensor
没有在 X3DOM 中实现,c.f。 https://doc.x3dom.org/author/nodes.html。但是您可以在内联文件中使用 'simple' 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()
}
这是我的方法...类似于 ,但使用 rxjs
编辑添加了一些超时逻辑以避免无限期等待
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]);
我在 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 规范
An isLoaded TRUE event is generated when all of the elements have been loaded. (http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/networking.html#LoadSensor)
我如何使用 React 来做到这一点?此事件在 componentDidMount.
之后发出谢谢!
我认为 loadSensor
没有在 X3DOM 中实现,c.f。 https://doc.x3dom.org/author/nodes.html。但是您可以在内联文件中使用 'simple' 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()
}
这是我的方法...类似于
编辑添加了一些超时逻辑以避免无限期等待
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]);