2015年6月7日日曜日

Cardboard実験サイト 4.3 Gyro / Cube2 (iframe構成)

概要
Gyroscopeのデータを取得して、デバイスの移動に応じて画面を動かすサンプルです。

このサンプルでは左右の画面をiframeで構成し、視差を付けて3D画像を描画します。

iframeを使用することで、左右の画面各々でクリッピングが行われるようになります。
一方、各々が独立したwindowのためタイマイベントも別々にループし、アニメ描画時に単純にループ毎に定数を足すような演算では時間が経つにつれ描画にズレが生じます。
それを避けるため、ここでは親window(index.html)から時間経過(msec())を取得し、それに基づいてアニメ描画を行っています。

HTML/Cube1のdivを組み合わせて作る立方体を複数配置し、Gyroと連動して視点を移動させます。感覚的には頭の動きに合わせて自分の周りを眺めるような感じです。座標の中心から視点を離す必要があるため、空間の中心からは少しズレがでます。

iOS/Androidで基本的に同じ使い方ができますが、Androidでのテストは行っていません。動作不良の場合は若干の修正で対応できるはずです。


画面レイアウト設定

タグ構造 
<body onload="init();" ontouchmove="blockMove(event)">
    <!-- HTMLL/Cube1と同じ -->
    <div id="container">
      <div id="outerBox">
        <div id="boxR" onclick="restart()">
          <div id="canvasR"></div>
        </div>
        <div id="boxL" onclick="back()">
          <div id="canvasL"></div>
        </div>
      </div>
    </div>
    <!-- Cubeを組み立てる6面のdiv -->
    <div id="divFaces" style="display:none">
        <div id="cube">
            <div class="face" id="f1">One</div>
            <div class="face" id="f2">Two</div>
            <div class="face" id="f3">Three</div>
            <div class="face" id="f4">Four</div>
            <div class="face" id="f5">Five</div>
            <div class="face" id="f6">Six</div>
        </div>
    </div>
</body>

is/cssインポート
        <script src="../../js/cardboard.js"></script>
        <script src="../../js/gyro.js"></script>
        <script src="../../HTML/js/Cube.js"></script>
        <script src="Cube1.js"></script>
        <link rel="stylesheet" type="text/css" href="../../css/cardboard.css" />
        <link rel="stylesheet" type="text/css" href="Cube1.css" />

javascript
index.html
        var gyro = null;
        function init() {
              //Gyroオブジェクト生成
              gyro = new Gyro();
              //デバイス横位置の大きさに合わせて左右の画面をリサイズ、イベント設定を行う。
              Config.setBoxSizes();
              //視点の設定
              Config.setParspective(4, 0, 500);
             //Cubeオブジェクト追加
              var c1 = Canvas.add(Cube1);
              //タイマーイベントスタート
              Canvas.start(50);
        }
        //スワイプで画面が動かないようにする。
        function blockMove(event) {
              if (Config.isIOS) event.preventDefault();
        }

Cube1.js
    //コンストラクタ
    Cube1 = function(parentDiv, side) {
        if (parentDiv == null) return;
        this.div = document.getElementById("divFaces").cloneNode(true);
        if (this.div == null) throw 'Missing <div id="divFaces">';
        this.div.className = "o3d";
        this.div.style.display = "block";
        parentDiv.appendChild(this.div);
    }

   //パラメータ設定
    Cube1.prototype.setParam = function(param) {
        this.ty = -70;
        this.rx = this.ry = this.rz = this.tx = this.ty = this.tz = 0;
        this.dx = param["dx"] == null ? 0 : param["dx"];
        this.dy = param["dy"] == null ? 0 : param["dy"];
        this.r = param["r"] == null ? 0 : param["r"];
        this.rand = param["rand"] == null ? 0 : param["rand"];
    }

    //Canvasのタイマーイベントから呼ばれる。アニメ描画。
    Cube1.prototype.move = function() {
        if (parent.gyro == null) return;
        var f = parent.msec() / 10000;
        this.rx += f * 0.8;   //+ this.rand;
        this.ry += f * 0.9; // + this.rand;
        this.rz += f;   // + this.rand;
        
        var gx = (parent.gyro.ox + this.dx) * Math.PI / 180;
        var gy = (Math.abs(parent.gyro.oy) + 90) * Math.PI / 180;
        
        var tx = this.r * Math.sin(gx) + Config.centerX;;
        var tz = this.r * Math.cos(gx) * Math.cos(gy);
        var ty = tz * Math.sin(gy);
        var tt = ty;
        ty -= this.r * Math.sin(this.dy * Math.PI / 180)
        this.div.style.webkitTransform = "translateX(" + tx + "px) "
            + "translateY(" + ty + "px) "
            + "translateZ(" + tz + "px) "
            + "rotateX("+ this.rx + "deg) "
            + "rotateY("+ this.ry + "deg) ";
    }

0 件のコメント: