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);
}

附上效果圖

加載地球


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM