トップへ(mam-mam.net/)

Javascriptで地球を3D表示 ~Webサイトで3Dコンテンツ(Three.js)

検索:

地球の3D表示(Three.js[r145]を使用)

マウス左ドラッグで回転、右ドラッグでカメラの移動、ホイールで拡大縮小できます。
スワイプで回転、画面に2本指を触れてなぞるとカメラの移動、ピンチイン/アウトで拡大縮小です。


NASAで無償提供している画像を利用しました。
地球の画像データはこちらで配布されています。
https://visibleearth.nasa.gov/images/57752/blue-marble-land-surface-shallow-water-and-shaded-topography
雲の画像データはこちらで配布されているものを透明に加工して使いました。
https://visibleearth.nasa.gov/images/57747/blue-marble-clouds

ソースコード

<canvas id="can" style="width: 100%; height: auto; max-width:calc(100vw - 32px);max-height:calc(100vw - 32px);cursor:pointer;" width="1000" height="600"></canvas>

<script>
//X:→  Y:↑ Z:手前、反時計回り

var camera,spot;
var imageFiles=["./imgs/earth.jpg","./imgs/cloud.png"];
var mesh=[];

async function loadImage(src){
  return new Promise(function(resolve,reject){
    let img=new Image();
    img.onload=function(){resolve(img);}
    img.onerror=function(e){reject(e);}
    img.src=src;
  });
}

window.addEventListener( 'DOMContentLoaded', async function(){
  var images=[];
  var material=[];
  var texture=[];

  //シーンを作成
  scene = new THREE.Scene();

  //カメラを作って設定
  var width  = document.getElementById("can").getAttribute("width");
  var height = document.getElementById("can").getAttribute("height");
  //            視野角,アスペクト比,近距離,遠距離
  camera = new THREE.PerspectiveCamera( 60, width/height, 0.01, 100 );
  camera.position.set(0,0,3);
  camera.lookAt(new THREE.Vector3(0, 0, 0));

  //レンダラーをDOM上に設置する
  renderer = new THREE.WebGLRenderer({'canvas':document.getElementById('can') , antialias: true});//アンチエイリアスをtureにする
  renderer.setSize( width, height );
  renderer.shadowMap.enabled = true;//影可能
  renderer.shadowMapSoft = true;
  renderer.shadowMap.type = THREE.PCFShadowMap;

  document.getElementById('can').style.width="100%";
  document.getElementById('can').style.height="auto";


  //■背景色の設定
  //renderer.setClearColor(0x88ccff, 1);
  renderer.setClearColor(0x000000, 1);

  //光源------------------------------------------------
  //環境光(すべての物体にすべての方向から与える光)これがないと光の当たらない部分は真っ黒になる
  var AmbientLight=new THREE.AmbientLight(0xffffff,0.3);
  scene.add( AmbientLight );


  //画像のロード
  images=await Promise.all(imageFiles.map(loadImage));
  //テクスチャのロード
  for(let i=0;i<imageFiles.length;i++){
    texture[i]=new THREE.TextureLoader().load(imageFiles[i]);
    material[i]=new THREE.MeshLambertMaterial({
      color: 0xffffff, //色
      map:texture[i],
      side:THREE.DoubleSide, //THREE.DoubleSide, THREE.FrontSide, THREE.BackSide
      transparent:true,
      opacity:1.0,
    });
  }
  material[1].opacity=1;
  
  let sphereGeometry=new THREE.SphereGeometry(1,64,32,0,Math.PI*2);
  mesh[0]=new THREE.Mesh(sphereGeometry,material[0]);
  mesh[0].rotation.z=23.43/180*Math.PI;
  mesh[0].rotation.y=Math.PI/2;
  scene.add(mesh[0]);
  mesh[1]=new THREE.Mesh(sphereGeometry,material[1]);
  mesh[1].scale.set(1.01,1.01,1.01);
  scene.add(mesh[1]);


  
  //スポットライト            色,     強さ,距離(distance),角度(angle),半影[0-1],減衰[1,1.5]
  spot=new THREE.SpotLight(0xffffff, 4, 20,Math.PI*0.5, 0.8, 1.2);
  spot.position.set(0,4,8);
  spot.target.position.set(0,0,0);
  spot.castShadow=true;//影を表示可能に
  spot.shadow.mapSize.width = 4096;	//影をきれいにする
  spot.shadow.mapSize.height = 4096;	//影をきれいにする
  spot.shadow.radius=8;
  scene.add(spot);
  scene.add(spot.target);


  //オービットコントロールの作成(マウスの左右ボタンドラッグ、ホイール等でカメラが動くようになる)
  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.target.set(0,0,0);
  controls.update();


  renderLoop();
});

function renderLoop () {
  mesh[0].rotation.y+=Math.PI/360/4;
  mesh[1].rotation.y+=Math.PI/360/4*1.2;
  //mesh[1].rotation.x+=Math.PI/360/4;
  renderer.render( scene, camera );
  setTimeout(renderLoop,33);
}
</script>