实现效果:
源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<!--head中添加script的引用库js文件-->
<script type="text/javascript" charset="utf-8" src="js\three.js"></script>
<script type="text/javascript" charset="utf-8" src="js\stats.js"></script>
<script type="text/javascript" charset="utf-8" src="js\dat.gui.js"></script>
<script type="text/javascript" charset="utf-8" src="js\OrbitControls.js"></script>
<script type="text/javascript" charset="utf-8" src="js\jquery-3.4.1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js\zxx.color_exchange.js"></script>
</head>
<body>
<div>
<input type="file" id="files" style="display: none" onchange="fileImport();">
</div>
<!--body中添加主要编译运行的scirpt代码-->
<script type="text/javascript">
//全局变量
var camera;
var scene;
var renderer;
var jsonSource;
//【主函数】定义函数
function init() {
//【】初始化帧数统计
var stats = initStats();
//【1】要素-场景、相机、渲染器、轴
//场景
scene = new THREE.Scene();
//相机
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000000);//创建一个透视相机 可视角度45度 浏览器的全屏的宽高 水平视锥 最近1 最远2000
camera.position.z = 550;//相机的位置z正半轴250
//渲染器
renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true });//打开抗锯齿,使用 logarithmicDepthBuffer 缓冲
renderer.setClearColor(new THREE.Color("rgb(230, 255, 255)"), 1);//背景
renderer.setPixelRatio(window.devicePixelRatio);//根据设备设置像素比,避免HiDPI设备上绘图模糊
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;//打开阴影渲染
renderer.sortObjects = true;//定义渲染器是否应对对象进行排序默认是true.false:物体的渲染顺序将会由他们添加到场景中的顺序所决定,适合大部分场景。
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
//【 】输出
//相机点位
camera.position.set(-3000, 4000, 3000);
camera.lookAt(scene.position);
//添加渲染输出到HTML元素
document.body.appendChild(renderer.domElement);
//【】相机控制
//1.轨道控制器
var clock = new THREE.Clock();
var orbitControls = new THREE.OrbitControls(camera, renderer.domElement);
orbitControls.minDistance = 0.1; //设置滚轮最近
orbitControls.maxDistance = 10000000; //设置滚轮最远
orbitControls.autoRotate = false;//自动旋转
orbitControls.zoomSpeed = 2;
//【】GUI交互控制
var controls = new function () {
this.导入文件 = function () { $("#files").click() };//点击导入按钮,使files触发点击事件,然后完成读取文件的操作
this.开始漫游 = function () { };
this.跳起高度 = 200;
this.MoveSpeed = 500;
this.无障碍 = true;
this.结束漫游 = function () { };
this.使用说明 = function () { alert("使用说明"); };
};
//可视化界面GUI对象,添加控制对象的速度属性
var gui = new dat.GUI();
gui.add(controls, '使用说明');
gui.add(controls, '导入文件');
var folder = gui.addFolder('漫游');
folder.add(controls, '开始漫游');
folder.add(controls, '结束漫游');
folder.add(controls, '跳起高度', 0, 500);
folder.add(controls, 'MoveSpeed', 0, 1000);
folder.add(controls, '无障碍');
renderScene();
//【函数】引入requestAnimationFrame()方法,让场景动起来
function renderScene() {
//帧数显示刷新
stats.update();
//相机控制刷新
//trackballControls.update(clock.getDelta());
orbitControls.update();
requestAnimationFrame(renderScene);//动画循环渲染起来
renderer.render(scene, camera);//渲染
}
}
//【函数】导入文件
function fileImport() {
//获取读取我文件的File对象
var selectedFile = document.getElementById('files').files[0];
var name = selectedFile.name; //读取选中文件的文件名
var size = selectedFile.size; //读取选中文件的大小
console.log("文件名:" + name + "大小:" + size);
var reader = new FileReader(); //这是核心,读取操作就是由它完成.
reader.readAsText(selectedFile); //读取文件的内容,也可以读取文件的URL
reader.onload = function () {
//当读取完成后回调这个函数,然后此时文件的内容存储到了result中,直接操作即可
jsonSource = this.result;
var strJson = JSON.parse(jsonSource);//对象
for (let i = 0; i < Object.keys(strJson).length; i++) {
if (Object.keys(strJson)[i] == "models") {
var obj = strJson[Object.keys(strJson)[i]];//数组
for (var j = 0; j < obj.length; j++) {
var geometrys = obj[j].geometrys;
for (var k = 0; k < geometrys.length; k++) {
var vertex = geometrys[k].vertex.split("|");
var face = geometrys[k].face.split("|");
//geometry
var geometry = new THREE.Geometry();
for (m = 0; m < vertex.length; m++) {
var ss = vertex[m].split(",");
geometry.vertices.push(new THREE.Vector3(parseFloat(ss[0]), parseFloat(ss[1]), parseFloat(ss[2])));
};
for (m = 0; m < face.length; m++) {
var ss = face[m].split(",");
geometry.faces.push(new THREE.Face3(parseInt(ss[0]), parseInt(ss[1]), parseInt(ss[2])));
};
//color
var Reds = parseInt(geometrys[k].RGB.red);
var Greens = parseInt(geometrys[k].RGB.green);
var Blues = parseInt(geometrys[k].RGB.blue);
var RGBs = "RGB(" + Reds + "," + Greens + "," + Blues + ")";
var RGBss = RGBs.colorHex();
//opacity
var transparencys = parseFloat((100 - geometrys[k].transparency) / 100);
//transparent
var trans = false;
if (transparencys != 0) { trans = true };
//material
var material = new THREE.MeshBasicMaterial({ color: RGBss, opacity: transparencys, transparent: trans, depthTest: true, depthWrite: true });
//Edges边线
var cubeEdges = new THREE.EdgesGeometry(geometry, 85);
var edgesMtl = new THREE.LineBasicMaterial({ color: 000000 });
var cubeLine = new THREE.LineSegments(cubeEdges, edgesMtl);
//mesh
var mesh = new THREE.Mesh(geometry, material);
mesh.add(cubeLine);
mesh.geometry.computeBoundingSphere();
mesh.geometry.computeFaceNormals();
mesh.geometry.computeVertexNormals();
mesh.rotation.x = -0.5 * Math.PI;//需要转90度为水平状态
scene.add(mesh);
}
}
}
};
}
}
//【函数】初始化帧数统计模块
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: mss
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
return stats;
}
//【函数】监听函数
function onRisize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();//更新项目整体坐标
renderer.setSize(window.innerWidth, window.innerHeight);//将输出canvas的大小调整为(width, height)并考虑设备像素比
}
//调用主函数
window.onload = init;
//监听事件
window.addEventListener('resize', onRisize, false);
</script>
</body>
</html>