我正在制作一个应用程序,观众可以使用dat.gui菜单来更新他们的Three.js动画。具体来说,我使用的是三维力图。
当用户进行更改时,我会执行以下操作:
- 将运行其动画的旧.json与渲染所选动画所需的新.json进行交换
- 运行一个名为
vertexControl
的函数,该函数会更改其新动画的节点(例如颜色更改(
简单示例:
const settings = {
num : 5,
}
const gui = new dat.GUI();
gui.add(settings, 'num', 1, 10).step(1).onChange( function update(n) {
Graph.jsonUrl('new_json'+ n.toString() +'.json'); //a built-in of 3d-force-graph to update the .json
vertexControl() //Graph is now updated, so change the vertices
}
问题:在用新的.json更新Graph
对象之前,vertexControl
会提前执行。因此,节点不会发生所需的更改。
我尝试过的三维力图有一个方法.refresh()
,但在我的情况下似乎没有任何作用。我还在StackOverflow上尝试了回调和其他解决方案,这些解决方案解决了";如何使函数2在函数1之后执行;它们似乎不起作用,这非常令人惊讶和奇怪。确实有效的是设置一个荒谬的setTimeout
,并猜测Graph
何时更新的毫秒数。然而,我试图做的是非常基本的,所以必须有一个合理的方法来做到这一点(对吗?(。
问题是Graph.jsonUrl()
必须异步加载该JSON,但vertexControl()
在JSON完成加载之前立即执行。我正在查看力图文档,遗憾的是,当JSON完成加载时,没有内置的方法来执行回调。您可能需要自己用THREE.FileLoader
加载JSON,以便在加载完成后调用自己的回调:
// FileLoader can help you load JSON files yourself
var fileLoader = new THREE.FileLoader();
const settings = {
num : 5,
}
const gui = new dat.GUI();
gui.add(settings, 'num', 1, 10).step(1).onChange( function update(n) {
fileLoader.load(
'new_json'+ n.toString() +'.json',
// Callback for when JSON file has finished loading
function(response) {
// Convert response text to JSON object
const newData = JSON.parse(response);
// Pass resulting object to Graph
Graph.graphData(newData);
// Now you can run VertexControl
vertexControl();
}
);
}
fileLoader.load
的第一个参数是文件路径,第二个参数是在文件加载完成后执行的回调函数。这样,您就可以先更新图形数据,然后再运行vertexControl
,而无需再等待。