three.js小白的学习之路。
介绍
在浏览和three.js有关的一个博客网站时,突然发现一个比较有意思的话题,就是将场景保存成JSON文件,然后导入到另外一个场景中。
使用的方法是scene.toJSON()方法,将scene场景内的所有信息转成json字符串的形式保存,在浏览器下载成一个json文件,或者干脆保存到localStorage中。然后通过读取文件的方法,将json字符串在转换成对应的场景信息,覆盖当前的scene即可。
基础使用
搭建了一个基础的场景,里面放了几个物体,充一充门面:
添加了几个按钮,分别用于保存当前scene到json,一个input输入框,用于选择json文件:
<template><div id="canvas" ref="canvasRef" /><button id="export" @click="exportScene">保存scene</button><button id="clear" @click="clearScene">清空scene</button><div id="import"><input type="file" name="file" id="importBtn" @change="importScene" /></div>
</template>
// 导出JSON文件的方法
const exportFileJSON = (data: any, filename = "scene.json") => {if (typeof data === "object") {data = JSON.stringify(data, null, 4);}const blob = new Blob([data], { type: "text/json" });const e = new MouseEvent("click");const a = document.createElement("a");a.download = filename;a.href = window.URL.createObjectURL(blob);a.dataset.downloadurl = ["text/json", a.download, a.href].join(":");a.dispatchEvent(e);
};// 导入JSON文件的方法
const importFileJSON = (ev: any) => {return new Promise((resolve, reject) => {const fileDom = ev.target;const file = fileDom.files[0];// 执行后清空input的值,防止下次选择同一个文件不会触发onchange事件ev.target.value = "";const reader = new FileReader();reader.readAsText(file);reader.onload = () => {const resultData = reader.result as any;const importData = JSON.parse(resultData);resolve(importData);};});
};
const exportScene = () => {const json = scene.toJSON();const output = JSON.stringify(json);// localStorage.setItem("scene", output);exportFileJSON(output, "scene.json");
};const importScene = (event) => {// const json = localStorage.getItem("scene");importFileJSON(event).then((json) => {if (json) scene = new Three.ObjectLoader().parse(json);});
};const clearScene = () => {scene = new Three.Scene();
};
通过调用scene的toJSON方法加上Blob流和a链接的方式下载,保存成一个json文件。之后清空scene场景,也就是重新赋值。最后通过FileReader读取对应的文件,解析之后,直接赋值给scene即可。
此外,经过实测,发现这个也会将scene的灯光信息保存下来,因此大胆推测,会将所有通过add等方法添加到场景中的模型也好,灯光也好都保存一份,也就是scene的全部信息。
疑问
目前有一个问题,就是如果我仅想针对scene中的某几个物体进行保存,又改如何实现?
因为将整个场景全搬到另一个场景,意义上感觉不是很大。但是如果能将部分scene保存,并且在另外一个已有scene的基础上加载保存的部分scene,还不影响现有的scene,实现二者共存,这个还是挺有意义的。
求大佬解答!我自己也会慢慢探索,有消息我一定会回来的~