three.jsで地球儀

f:id:haru-komugi:20140714180221j:plain
ちょいとthree.jsで地球儀を作ってみたのでメモ

CSS3フィルターも普通にかけられるっぽいです。

サンプルはこちら
http://moeten.info/js/20140714_threejsSphereTest/index3dTest.html

ソースコードはこちら

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title></title>
  <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r67/three.min.js"></script>
  <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
  <script>

    $(function(){

      //初期化
      function init() {

        //シーンの作成
        setScene();

        //ライトの作成
        setLight();

        //カメラの作成
        setCamera();

        //オブジェクトの作成
        makeObject();

        //レンダー
        render();

      }

      //シーンの作成
      var scene;
      var renderer;
      function setScene() {

        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({ alpha: true,antialias: true});
        renderer.setSize(window.innerWidth, window.innerHeight);
        $("#container").append( renderer.domElement);

      }

      //ライトの作成
      function setLight(){

        //環境光
        var alight = new THREE.AmbientLight(0x666666);
        scene.add(alight);

        //方向性ライト
        light = new THREE.DirectionalLight(0xE5FDFF);
        light.position.set( -500, 500, -500 );
        scene.add( light );

      }

      //カメラの作成
      var camera;
      var radius = 500;
      function setCamera() {

        camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
        scene.add(camera);
        camera.position.z = -radius;

      }

      //オブジェクトの作成
      var sphere;
      function makeObject() {

        //地球儀の作成
        var geometry = new THREE.SphereGeometry(150, 20, 20);
        var texture = THREE.ImageUtils.loadTexture("img/earthmap.jpg");
        var material = new THREE.MeshPhongMaterial({map: texture, color: 0xFFFFFF, specular: 0xFFFFFF, shininess: 50});
        sphere = new THREE.Mesh(geometry, material);
        scene.add(sphere);

      }

      //レンダー
      function render() {

        requestAnimationFrame(render);

        camera.lookAt(sphere.position);

        //地球儀を回転させる
        sphere.rotation.y += 0.01;

        renderer.render(scene, camera);

      }

      //CSSフィルターをかける
      $('input[type="range"]').change(function() {

        var range = this;
        var fx = range.id;
        var unit = range.dataset.unit || 'px';
        var value = range.value + unit;
        $('canvas').css('-webkit-filter', fx + '(' + value + ')');

      });

      init();

    });
  </script>
  <style>
    *{
      padding: 0;
      margin: 0;
    }
    body{
      overflow: hidden;
      background: #b5bdc8; /* Old browsers */
      background: -moz-radial-gradient(center, ellipse cover,  #b5bdc8 0%, #828c95 36%, #28343b 100%); /* FF3.6+ */
      background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#b5bdc8), color-stop(36%,#828c95), color-stop(100%,#28343b)); /* Chrome,Safari4+ */
      background: -webkit-radial-gradient(center, ellipse cover,  #b5bdc8 0%,#828c95 36%,#28343b 100%); /* Chrome10+,Safari5.1+ */
      background: -o-radial-gradient(center, ellipse cover,  #b5bdc8 0%,#828c95 36%,#28343b 100%); /* Opera 12+ */
      background: -ms-radial-gradient(center, ellipse cover,  #b5bdc8 0%,#828c95 36%,#28343b 100%); /* IE10+ */
      background: radial-gradient(ellipse at center,  #b5bdc8 0%,#828c95 36%,#28343b 100%); /* W3C */
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b5bdc8', endColorstr='#28343b',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
    }
    dl{
      background: #fff;
      position: absolute;
      top:10px;
      left: 10px;
      padding: 10px 14px;
      border-radius: 10px;
      box-shadow: 0 0 3px gray;
    }
    dt{
      width: 200px;
      float: left;
    }
    dd{
      margin-left: 200px;
    }
  </style>
</head>
<body>
<div id="container"></div>
<dl>
  <dt>blur()</dt><dd><input type="range" id="blur" value="0" min="0" max="10" data-unit="px"></dd>
  <dt>grayscale()</dt><dd><input type="range" id="grayscale" value="0" min="0" max="100" data-unit="%"></dd>
  <dt>sepia()</dt><dd><input type="range" id="sepia" value="0" min="0" max="100" data-unit="%"></dd>
  <dt>saturate()</dt><dd><input type="range" id="saturate" value="100" min="0" max="100" data-unit="%"></dd>
  <dt>hue-rotate()</dt><dd><input type="range" id="hue-rotate" value="0" min="0" max="360" data-unit="deg"></dd>
  <dt>invert()</dt><dd><input type="range" id="invert" value="0" min="0" max="100" data-unit="%"></dd>
  <dt>opacity()</dt><dd><input type="range" id="opacity" value="100" min="0" max="100" data-unit="%"></dd>
  <dt>brightness()</dt><dd><input type="range" id="brightness" value="100" min="0" max="100" data-unit="%"></dd>
  <dt>contrast()</dt><dd><input type="range" id="contrast" value="100" min="0" max="100" data-unit="%"></dd>
  <dt>drop-shadow()</dt><dd><input type="range" id="drop-shadow" value="0" min="0" max="10" data-unit="px 0px 10px #000"></dd>
</dl>
</body>
</html>

three.jsに慣れたら次はARですね。