zoukankan      html  css  js  c++  java
  • ThreeJS 制作地球

    环境

    • ThreeJS 107版本
    • three.min.js
    • OrbitControls.js
    • 深空背景图片 大小4036*1808
    • 地球贴图 大小2048*1024 边幅以东西经180度为界限

    说明

    原本我们GIS使用的是cesiumJS开发的三维,但如果仅仅作为前端,大屏展示三维地球效果,cesiumJS显得过于厚重。故非强GIS功能,我们探索了ThreeJS。

    解决方案

    1. 获取地球容器
    //获取地球容器
    dom = document.getElementById('divEarth');
    dom.style.width = '100%';
    dom.style.height = '100%';
    
    1. 添加深空背景
    var _imgSky = "assets/images/earth_bg.jpg";
    dom.style.background = "url(" + _imgSky + ") no-repeat center center";
    dom.style.backgroundColor = "#00000000";
    
    1. 初始化场景,并设置场景光线
    // 初始化场景
    scene = new THREE.Scene();
    // 设置光线
    scene.add(new THREE.HemisphereLight('#ffffff', '#ffffff', 1));
    
    1. 设置相机
    // 初始化相机
    camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000);
    // 设置相机位置
    camera.position.set(0, 0, 200);
    
    1. 初始化渲染
    renderer = new THREE.WebGLRenderer({
    alpha: true, //是否透明
    antialias: true //抗锯齿
    });
    renderer.autoClear = false;
    // 设置窗口尺寸
    renderer.setSize(dom.clientWidth, dom.clientHeight);
    dom.appendChild(renderer.domElement);
    
    1. 初始化轨道控制器
      这里需要先引入js包(OrbitControls.js)
    // 初始化控制器
    orbitcontrols = new THREE.OrbitControls(camera, renderer.domElement);
    // 使动画循环使用时阻尼或自转 意思是否有惯性
    orbitcontrols.enableDamping = true;
    
    1. 创建地球对象
    // 定义地球材质
    var earthTexture = THREE.ImageUtils.loadTexture("assets/images/starry_sky_bg.jpg", {}, function () {
    renderer.render(scene, camera);
    });
    // 创建地球
    earthBall = new THREE.Mesh(new THREE.SphereGeometry(30, 50, 50), new THREE.MeshBasicMaterial({
    map: earthTexture
    }));
    earthBall.layers.set(0);
    //添加到场景
    scene.add(earthBall);
    
    1. 最后加上渲染
    render();
    // 执行函数
    function render() {
    if (handle) {
    cancelAnimationFrame(handle);
    }
    renderer.clearDepth();
    //自转,自转速度(正数自西向东转,负数为逆向)
    scene.rotation.y += 0.01;
    renderer.render(scene, camera);
    orbitcontrols.update();
    handle = requestAnimationFrame(render);
    }
    

    附上接口源码

    var ThreeJSEarth = function (_domID, _earthOptions) {
    var scene, renderer, camera, orbitcontrols;
    var earthBall;//地球实体
    var dom, handle;//容器,定时器动画句柄
    
    /**
    * 初始化地球,对象创建时自动调用
    */
    (function init() {
    //获取地球容器
    dom = document.getElementById(_domID);
    dom.style.width = '100%';
    dom.style.height = '100%';
    var _imgSky = _earthOptions.imgSky ? _earthOptions.imgSky : "";
    dom.style.background = "url(" + _imgSky + ") no-repeat center center";
    dom.style.backgroundColor = "#00000000";
    
    // 初始化场景
    scene = new THREE.Scene();
    // 初始化相机
    camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000);
    // 设置相机位置
    camera.position.set(0, 0, _earthOptions.cameraZ ? _earthOptions.cameraZ : 200);
    renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true
    });
    renderer.autoClear = false;
    // 设置窗口尺寸
    renderer.setSize(dom.clientWidth, dom.clientHeight);
    // 初始化控制器
    orbitcontrols = new THREE.OrbitControls(camera, renderer.domElement);
    // 使动画循环使用时阻尼或自转 意思是否有惯性
    orbitcontrols.enableDamping = true;
    //动态阻尼系数 就是鼠标拖拽旋转灵敏度
    // orbitcontrols.dampingFactor = 0.2;
    dom.appendChild(renderer.domElement);
    // 设置光线
    scene.add(new THREE.HemisphereLight('#ffffff', '#ffffff', 1));
    // 定义地球材质
    var earthTexture = THREE.ImageUtils.loadTexture(_earthOptions.imgEarth ? _earthOptions.imgEarth : "404.jpg", {}, function () {
    renderer.render(scene, camera);
    });
    // 创建地球
    earthBall = new THREE.Mesh(new THREE.SphereGeometry(_earthOptions.earthBallSize, 50, 50), new THREE.MeshBasicMaterial({
    map: earthTexture
    }));
    earthBall.layers.set(0);
    scene.add(earthBall);
    // this.renderEarthByRender();
    render();
    })();
    // 执行函数
    function render() {
    if (handle) {
    cancelAnimationFrame(handle);
    }
    renderer.clearDepth();
    //自转
    scene.rotation.y += _earthOptions.autorotationSpeed ? _earthOptions.autorotationSpeed : 0;
    renderer.render(scene, camera);
    orbitcontrols.update();
    handle = requestAnimationFrame(render);
    }
    // 窗口resize事件
    window.onresize = function () {
    // 重新初始化尺寸
    camera.aspect = dom.clientWidth / dom.clientHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(dom.clientWidth, dom.clientHeight)
    }
    }
    

    调用方式

    //初始化
    function initThree() {
    var earthOptions = {
    //imgEarth: 'assets/images/earth_bg.jpg',//地球贴图
    imgEarth: 'http://10.19.151.238/earth_bg.jpg',//地球贴图
    imgSky: 'assets/images/starry_sky_bg.jpg',//深空背景
    autorotationSpeed: 0,//自转速度(正数自西向东转,负数为逆向)
    cameraZ: 200,//摄像头高度,
    earthBallSize: 30//地球大小
    };
    encEarth = new EncEarth("three-frame", earthOptions);
    }
    

    附上效果图

    加载地球

  • 相关阅读:
    风险分解结构
    WBS 工作分解结构
    react函数式组件(非路由组件)实现路由跳转
    react使用antd组件递归实现左侧菜单导航树
    React4.0以上如何获取当前的路由地址呢
    浅谈react传入路由参数---withRouter组件
    react项目实现维持登录与自动登录
    async和await应用步骤分析+优化异常处理
    跨域场景&&跨域处理方案
    vscode react中标签自动补全 vscode jsx语法自动补全html标签
  • 原文地址:https://www.cnblogs.com/giser-s/p/12928560.html
Copyright © 2011-2022 走看看