THREE.js 如何在刷新前保存场景并在页面刷新完成后加载它?

THREE.js How to save a scene before refresh and load it once the page is done with refresh?

我有一个 web 应用程序,用户可以在其中向场景添加对象、四处移动、更改旋转等。但是,我有一个下拉菜单,它决定了整个页面上要遵循的各种单位系统参数。下拉菜单在更改时应通过页面刷新。这会导致整个场景被重置。有什么方法可以在三个js中保存场景然后重新加载到之前的状态吗?

您要实现的目标的一个很好的例子是 three.js editor itself.You can find its source on github

它的作用是将编辑器的状态(即配置、camerascene 对象)存储到 local storageindexedDB(您可以生活也只有一个),然后当页面初始化时,它会检查场景的 state 是否设置在 indexedDB 中,然后从那里加载它。

您可能需要阅读代码本身,但我将在此处解释主要逻辑。


1。页面加载时从本地存储加载场景

你可以发现在index.html有这段代码的时候

  editor.storage.init( function () {
    editor.storage.get( function ( state ) {
        if ( state !== undefined ) {
            editor.fromJSON( state );
        }
        var selected = editor.config.getKey( 'selected' );
        if ( selected !== undefined ) {
            editor.selectByUuid( selected );
        }
    } );

所以这会检查是否有数据进入 /js/Editor.js 中的 fromJSON 函数,它基本上将 camerascene 等设置为任何值存储在indexedDB中。具体代码见

   fromJSON: function ( json ) {

        var loader = new THREE.ObjectLoader();

        // backwards

        if ( json.scene === undefined ) {

            var scene = loader.parse( json );

            this.setScene( scene );

            return;

        }

        // TODO: Clean this up somehow

        var camera = loader.parse( json.camera );

        this.camera.position.copy( camera.position );
        this.camera.rotation.copy( camera.rotation );
        this.camera.aspect = camera.aspect;
        this.camera.near = camera.near;
        this.camera.far = camera.far;

        this.setScene( loader.parse( json.scene ) );
        this.scripts = json.scripts;

    }

要检查它是如何从本地 storage/IndexedDB 准确加载的,您可以检查位于 JS 文件夹本身的 Config.jsStorage.js 文件。


2nd定期将数据存入IndexedDB

再次在 index.html 中,您可以找到以下代码并在 IndexedDB 中更新模型 此行为可以在事件或超时时触发,甚至可以通过调用这段代码手动触发editor.storage.set( editor.toJSON() );.

var saveState = function ( scene ) {
    if ( editor.config.getKey( 'autosave' ) === false ) {
        return;
    }
    clearTimeout( timeout );
    timeout = setTimeout( function () {
        editor.signals.savingStarted.dispatch();
        timeout = setTimeout( function () {
            editor.storage.set( editor.toJSON() );
            editor.signals.savingFinished.dispatch();
        }, 100 );
    }, 1000 );
};

希望你能利用这个例子来实现你的目标。