ラベル HTML の投稿を表示しています。 すべての投稿を表示
ラベル HTML の投稿を表示しています。 すべての投稿を表示

2015年6月9日火曜日

Cardboard実験サイト2.3 / HTML (div構成 / Photo1 - ステレオ写真)

概要
あらかじめ作ったステレオ写真を表示します。
これはステレオ写真をハコスコで見られるようにしようと作ったもので、画面分割は行っていません。

画面レイアウト設定
index.htmlで画面レイアウトのためのタグ構造を作り、画面サイズに応じてcardboard.jsでレイアウト設定を行います

タグ構造 
bodyタグ内は次のようにdivを数階層積み重ねたものです。
javascript、cssはdivのidを使用するので、idはこのとおりにしておきます。

  <body onload="init();" ontouchmove="blockMove(event)" >
    <div id="container">
      <div id="outerBox" class="photo" onclick="changeImage()">
      </div>
    </div>
  </body>

javascript
index.html


      function init() {
          //divの配置
          Config.setContainerSize();
          //最初の画像表示
          changeImage();
      }

      //画像名配列
      var arr = new Array("image1.jpg", ""image2.png", ...);
      var ix = -1;

      //clickまたはtouchstartイベントで呼ばれ、画像を切り替える。
      function changeImage() {
          //右画面で次へ進み、左が画面で前に戻る。
          if (event.pageX == null) 
              ix = 0;
          else
              ix += (event.pageX > (Config.winW / 2) ? 1 : -1);
          if (ix >= arr.length)
              ix = 0;
          else if (ix < 0)
              ix = arr.length - 1;
          //divのbackgroundImageにセット。
          with(document.getElementById("outerBox").style) {
              backgroundImage = "url(Images/" + arr[ix] + ")";
              backgroundSize = "100%";
          }
      }

      //スワイプされても画面を動かさないようにする。
      function blockMove(event) {
        if (Config.isIOS) event.preventDefault();
      }

Config.setContainerSize();
  デバイス横位置の大きさに合わせて画面をリサイズ、イベント設定を行なう。
  また、デフォルトで次のclickまたはtouchstartイベントハンドラをセットする。
  左画面ダブルクリック 上の階層に戻る
  右画面ダブルクリック location.reload();
  シングルクリック   Config.onclickにfunctionが設定されていればそれを実行、
                                   さもなければなにもしない。

 イベントハンドラが不要な場合はsetContainerSizeを呼ぶ前に次の行を追加。
 Config.addClickEvent = false;

 Photo1ではdivにonclickイベントハンドラを設定することで上記設定を置き換えている。

Cardboard実験サイト 2.2 / HTML (iframe構成)

概要
iPhoneを横位置にしたときに画面を二分割し、視差のあるイメージを表示します。
iframeを使用しています。

二画面が各々独立したwindowとなり、translateの結果divからはみ出した部分はクリッピングされます。

一方、独立したwindowのためタイマーイベントのループも別々タイミングで行われるため、単純にループ内で定数を足すような方法では、時間経過とともに同期のズレが発生します。Dateの時刻を利用することで左右のズレを避けることができます。

javascriptはcardboard.jsとcardboard−iframe.jsをインポートします。cardboard−iframe.jsはcardboard.jsへのfunctionを追加と一部置き換えを行います。これらは
画面レイアウト設定と、左右の画面に対する処理を一括して行う機能を提供し、また
タイマーイベントで描画関数を呼び出します。

画面レイアウト設定
index.htmlで画面レイアウトのためのタグ構造を作り、画面サイズに応じてcardboard−iframe.jsでレイアウト設定を行います

タグ構造 (iframe使用)
bodyタグ内は次のようにdivを数階層積み重ねたものです。
javascript、cssはdivのidを使用するので、idはこのとおりにしておきます。

index.html
    <body onload="init();">
        <div id="container">
            <div id="outerBox">
                <div id="boxL">
                    <iframe id="ifL" name="ifL" src="Part.html"></iframe>
                </div>
                <div id="boxR">
                    <iframe id="ifR" name="ifR" src="Part.html"></iframe>
                </div>
            </div>
        </div>
    </body>

Part.html (iframeのsrc)
    <body onload="init();">
        <div id="container">
            <div id="outerBox">
                <div id="canvas"></div>
            </div>
        </div>
    </body>


js/cssインポート
        <link rel="stylesheet" type="text/css" href="../../css/cardboard.css" />
        <script src="../../js/cardboard.js"></script>
        <script src="../../js/cardboard-iframe.js"></script>
        <script src="../../js/gyro.js"></script>

cardboard.jsの後にcardboard-iframe.jsを追加。

javascript
index.html
    //body.onloadで呼び出し、初期化を実行。
    var gyro = null;
    var startTime = new Date().getTime();
    function init() {
        //cardboad.jsのGyroオブジェクト生成。
         gyro = new Gyro();
         //div, iframeの配置。
         Config.setFrames();
    }

Part.html (ifarmeのsrc)

             //onloadイベント
             function init() {
             //iframe内のdiv配置。
             Config.setFrameCanvas(window.name);
             //iframeのサイズがjavascriptで決定できず表示位置がズレるので位置を調整。
             Config.body.scrollLeft = 0;
             //視点設定(イタリックは実際の値で置き換え)
             Config.setParspective(Config.side=="L"?-4:4, parsY, parsZ);
             //描画オブジェクト追加。
             var obj = Canvas.add(Part);
             //パラメータ設定。paramはkey/valueのArray。JSONなら{key1:value1, key2:value2, ...}。 
             obj.setParam(param);
             //タイマーイベントスタート。
             Canvas.start();
        }

Cube2.js
    //cardboard-iframe.jsのCanvas.add(func)実行中に呼ばれる。
    Cube2 = function(parentDiv, side) {
        //HTMLに配置したCubeのdivをコピーする。
        this.div = document.getElementById("divFaces").cloneNode(true);
        this.div.className = "o3d";
        this.div.style.display = "block";
        //parentDivに追加。
        parentDiv.appendChild(this.div);
    }

    //cube.htmlのaddCube(param)から呼ばれる。
    Cube2.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"];
    }

    //Canvasのタイマーイベントで呼ばれる。
    Cube2.prototype.move = function() {
        //index.htmlのonloadが実行されるまではgyroがnull。
        if (parent.gyro == null) return;
        //Dateの時刻を利用してアニメ用の変数を設定。
        var f = new Date().getTime() / 50;
        this.rx = f * 0.8;
        this.ry = f * 0.9;
        this.rz = f;
        //gyroから値を取得。
        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) ";
    }

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

2015年6月6日土曜日

Cardboard実験サイト 4.2 Gyro / Cube1 (div構成)

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

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


HTML/Cube1のdivを組み合わせて作る立方体を中央に置き、Gyroと連動してCubeを回転させます。感覚的には頭の動きに合わせて視点が動くような感じです。


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>


index.htmlのjavascript
js/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
//Cubeのコンストラクタを継承
Cube1 = function(parentDiv, side, div) {
            Cube.apply(this, arguments);
        }

        //Cubeのプロトタイプを継承
        Cube1.prototype = new Cube();

        //Canvasのタイマイベントから呼ばれる。アニメ描画。
        Cube1.prototype.move = function() {
            var ry = gyro.ox*2;
            var rx = gyro.oy*2;
            this.div.style.webkitTransform = "translateX(100px) "
                + "translateY(100px) "
                + "rotateX("+ rx + "deg) "
                + "rotateY("+ ry + "deg) ";
        }

2015年5月12日火曜日

Cardboard実験サイト 6 / gyro.jsに含まれる関数、変数


デモサイト

ダウンロード

rotationRate(移動量)
rx = event.rotationRate.beta
ry = event.rotationRate.gamma
rz = event.rotationRate.alpha

acceleration(移動速度)
ax = event.acceleration.x
ay = event.acceleration.y
az = event.acceleration.z

orientation(初期状態に対する向き)
ox = event.alpha
oy = event.gamma

oz = event.beta

orientation(デバイスの向き)
"PU” portrait upside up
"PD” portrait upside down
"LL" landscape left
"LR" landscape right

例:
//Gyroオブジェクト生成
var gyro = new Gyro();
//x方向の相対位置
var ox  = gyro.ox;
//x方向の移動速度
var ax  = gyro.ax;

//x方向の移動量
var rx  = gyro.rx;

gyro.jsソース


devicemotion、devicemotionイベントハンドラを設定し、イベントからGyroscopeの情報を取得して変数にセットする。
accelerationの値からデバイスの縦、横位置を推測して変数にセットする。

Gyro = function() {
    try {
        if (event == null
            || typeof window.DeviceMotionEvent == "undefined"
            || typeof window.DeviceOrientationEvent == "undefined") {
            throw("Gyro not available.");
        }
        this.rx = this.ry = this.rz = this.ax = this.ay = this.az = 0;
        this.orientation = "";
        var gyro = this;
        window.ondevicemotion = function(event) {
            gyro.rx = event.rotationRate.beta;
            gyro.ry = event.rotationRate.gamma;
            gyro.rz = event.rotationRate.alpha;
            gyro.ax = event.acceleration.x;
            gyro.ay = event.acceleration.y;
            gyro.az = event.acceleration.z;
            gyro.orientation = "PU";
            if (gyro.ax < -5) gyro.orientation = "LL";
            else if (gyro.ax > 5) gyro.orientation = "LR";
            else if (gyro.ay > 5) gyro.orientation = "PD";
        }
        window. ondevicemotion = function(event) {
            gyro.ox = event.alpha;
            gyro.oy = event.gamma;
            gyro.oz = event.beta;
        }
    } catch(e) { alert(e); }

Cardboard実験サイト 5 / cardboard.jsに含まれる関数、変数

デモサイト

ダウンロード

Config
画面レイアウト、イベントハンドラ設定を行う。
コーディングを容易にするため、よく使用するオブジェクトを変数にセットする。

関数

Config.setBoxSizes()
ContainerとouterBox、およびboxL、boxRのサイズを設定する。
3DでboxL、boxRがある場合に用いる。

Config.setContainerSize()
ContainerとouterBoxのサイズを設定する。
2DでboxL、boxRがない場合に用いる。

変数

Config.conatiner
Config.outerBox
Config.boxL
Config.boxR
Config.ifL
Config.ifR
divのidに対応する変数
document.getElementIdで取得したオブジェクト。HTMLに該当のidのdivがない場合はnull。

Config.isIOS
iOSまたはAndroidの場合にtrue。
もともとiOSに対応するために設けた変数だが、Androidでも動作するのでその場合もtureに設定するようにした。

Config.winW
Config.winH
画面サイズに関する変数
ただし、isIOS==falseの場合はiPhone6のサイズ(667x375)を設定。

Config.centerX
Config.centerY
boxL、boxRの中心の位置

Config.addClickEvent
イベント設定制御
デフォルト値はtrueで、outerBoxにtouchstartまたはclickイベントハンドラをセットする。
デフォルトではダブルタップ(またはクリック)時は左画面の場合は上の階層に戻り、右画面の場合はreloadを行う。
ただしiframeを使用する構成などでイベントが渡ってこない場合は実行されない。
イベントハンドラが不要な場合はsetBoxSizesまたはsetContainerSizeを呼ぶ前にこの変数の値をfalseにセットする。

Config.onclick
シングルタップ(またはクリック)時はデフォルトでは何も行わない。
この変数にfunctionをセットしておくと、それを実行する。

------------------------------------------------------------

Canvas
描画エリアにオブジェクト追加。
タイマーイベントでアニメ描画。

関数

Canvas.add(func)
描画を行うオブジェクト(function)を追加する。
func : Partsのサブクラス。
左右の画面の各々にnew func(..)でオブジェクトを生成し、それをひとつにまとめLRPairオブジェクトを生成して返す。

Canvas.remove(obj)
Canvasに登路されたオブジェクトを削除する。
objはCanvas.addが返したLRPairオブジェクト。

Canvas.clear()
Canvasに登録されたオブジェクトを全て削除する。

Canvas.start()
アニメーションを開始する。

変数

Canvas.interval
アニメーション実行間隔(msec)。直前の描画開始から少なくともこのミリ秒が経過してから次の描画を開始する。
描画にかかった時間がこれ以上の場合はすぐに次の描画を開始する。
デフォルト値=50msec。

------------------------------------------------------------


LRPair
 左右二つの描画エリアをまとめて扱う。
 Canvas.addで追加されたfuncのオブジェクトを左右各々生成し、保持する。

setParam(param)
 保持している左右のオブジェクトの各々にパラメータをセットする。
 param: key-valueペアの配列。{key : value, ... }
 パラメータの扱いはPartsオブジェクトに依存。

move() 
 保持している左右のオブジェクトの各々のmove関数を呼ぶ。

プロパティー

innerText
 保持している左右のオブジェクトの各々が配置されているdivのinnerTextの値の設定。
 取得の場合は左側のdivのinnerText(通常は左右同じ値)。

------------------------------------------------------------

Parts
 Canvas.addの引数につかうクラス。実際の描画はサブクラスに実装する。

関数

setParam(param)
パラメータ設定。
param: Paramオブジェクト

applyParam()
setParamで設定されたパラメータをオブジェクトに反映する。
実際のロジックはサブクラスで実装する。

move()
タイマーイベントで呼ばれ、描画を実行する。
実際の描画はサブクラスに実装する。

------------------------------------------------------------

Param
 key−value辞書

Param.val(key)
 オブジェクトが保持するkey−value辞書からkeyに対応するvalueを返す。

------------------------------------------------------------

Objectへのプロパティー追加

param
 オブジェクトのdictの値の設定、取得。

------------------------------------------------------------

その他

画面がスワイプで動かないようにするため、touchmoveイベントをキャンセルする。

<body ontouchmove="blockMove(event)">

function blockMove(event) {
if (Config.isIOS) event.preventDefault();
}


Cardboard実験サイト 4.1 Gyro / Panorama

概要

Gyroscopeのデータを取得して、デバイスの移動に応じて画面を動かすサンプルです。
360°のパノラマ写真をGyro連動で回転させます。

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

画面レイアウト設定
タグ構造 
HTML/Photo1とほぼ同じですが、styleを変更するためにclassを設定しています。
msgDivは使い方、写真タイトルを表示するエリアです。
    <body onload="init();">
        <div id="container" class="picFrame">
            <div id="outerBox" class="pic">
                <div id="msgDiv"></div>
            </div>
        </div>
    </body>

index.htmlのjavascript
js/cssインポート
        <script src="../../js/cardboard.js"></script>
        <script src="../../js/gyro.js"></script>
        <link rel="stylesheet" type="text/css" href="../../css/cardboard.css" />
        <link rel="stylesheet" type="text/css" href="Panorama.css" />

javascript
        var gyro = null;            
        function init() {
             //デバイス横位置の大きさに合わせて左右の画面をリサイズ、イベント設定を行う。
             Config.setContainerSize();
             //イベントハンドラ設定
             Config.onclick = changeImage;
             //最初の画像を表示
             changeImage();
             //Gyroオブジェクト生成
             gyro = new Gyro();
             //タイマーイベントスタート
             setTimeout(move, 33);
        }

        var posX = 0;

        function move() {
            //絶えず値が変動するので、細かすぎる動きは無視する。
            //gyroからデバイスの位置を取得
         //gyro.ox:  device orientation alpha 
            if (Math.abs(posX - gyro.ox) > 0.1) {
                posX = gyro.ox + offsetX;
                var x = (imgWidth * posX / 360).toFixed(1);
                Config.outerBox.style.backgroundPosition = x + "px";
            }
            setTimeout(move, 33);
        }

        //ダブルタップで画面チェンジ。
function changeImage(event) { with(Config.outerBox.style) { backgroundImage = "url("+ imgUrl +")"; backgroundOrigin = "0px 0px"; } //画像サイズ取得のためにimgに画像をセット。 var img = document.createElement("img"); img.addEventListener("load", imgLoaded); } var imgWidth = 0; var offsetX = 0; //img.onloadイベントハンドラ。imgから画像サイズを取得、初期表示位置(offsetX)をセット。 function imgLoaded(event) {
                var srcElm = event.srcElement;
                imgWidth = Math.round(srcElm.width * (document.body.clientHeight / srcElm.height));
                offsetX = (event.srcElement.width - Config.outerBox.clientWidth) / 2;
                event.srcElement.removeEventListener("load");
        }

2015年5月11日月曜日

Cardboard実験サイト 3 / Threeサンプルの構成


デモサイト

ソースコードダウンロード

概要

WebGLをjavascriptライブラリThree.jsで作られたHTMLを二分割画面で再生することで3Dアニメーション化するサンプルです。

画面レイアウト設定

タグ構造 

Three.jsを使うjavascriptを自分で作る場合(Cube1、Sphere1)
HTMLサンプルと同じです。

  <body onload="init();">
    <div id="container">
      <div id="outerBox">
        <div id="boxR">
          <div id="canvasR"></div>
        </div>
        <div id="boxL">
          <div id="canvasL"></div>
        </div>
      </div>
    </div>
  </body>

Three.orgのexampleなど、既存のjavascriptを利用する場合
HTMLサンプルとほぼ同じですが、Canvasのdiv代わりにiframeを使い、Three.jsのHTMLを読み込みます。
javascript、cssはdivのidを使用するので、idはこのとおりにしておきます。

  <body onload="init();">
    <div id="container">
      <div id="outerBox">
        <div id="boxL">
          <iframe id="ifL" src="webgl_animation_cloth.html"></iframe>
        </div>
        <div id="boxR">
          <iframe id="ifR" src="webgl_animation_cloth.html"></iframe>
        </div>
      </div>
    </div>
  </body>

index.htmlのjavascript

Three.jsを使うjavascriptを自分で作る場合(Cube1、Sphere1)
ja、cssインポート

    <script src="../build/three.min.js"></script>
    <script src="../../js/cardboard.js"></script>
    <script src="Cube.js"></script>
    <link href="../../css/cardboard.css" rel="stylesheet" type="text/css"></link>

javascript

    //body.onloadで呼び出し、初期化を実行。
    function init() {
        Config.setBoxSizes();
        Canvas.add(Cube);
        Canvas.start(msec);
    }

Three.orgのexampleなど、既存のjavascriptを利用する場合
js, cssインポート

    <script src="../../js/cardboard.js"></script>
    <link href="../../css/cardboard.css" rel="stylesheet" type="text/css"></link>

javascript
//body.onloadで呼び出し、初期化を実行。 function init() {   //デバイス横位置の大きさに合わせて左右の画面をリサイズ、イベント設定を行う。 Config.setBoxSizes();   //視差を設定 Config.ifL.contentWindow.param = new Param({"cameraX":0}); Config.ifR.contentWindow.param = new Param({"cameraX":0.05}); }

既存のjavascriptの場合、リンクのパス、アニメ同期に関わる部分の変更が必要。
描画、アニメ同期は元のjavascriptで行うので、ここではCanvas.startは呼ばない。

Three.orgのexampleの変更箇所
exampleによって変更箇所が異なるが、以下のような箇所を変更する。

      //画面サイズ設定
      var boxH, boxW;
      function init() {
          boxH = parent.Config.winH;
          boxW = Math.floor(parent.Config.winW / 2);
          ....
          //Cameraの領域設定
          //camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 10000 );
          camera = new THREE.PerspectiveCamera( 30, boxW / boxH, 1, 10000 );
          ....
          //texture相対パス変更
          //var clothTexture = THREE.ImageUtils.loadTexture( 'textures/patterns/circuit_pattern.png' );
          var clothTexture = THREE.ImageUtils.loadTexture( '../examples/textures/patterns/circuit_pattern.png' );
          ....
          //models相対パス変更
           //loader.load( "models/animated/horse.js", function ( geometry ) {
    loader.load( "../examples/models/animated/horse.js", function ( geometry ) {
      }

      //canvas_particles_waves.htmlの場合のグローバル変数
      var count, mouseX;

      function render() {
          //Dateを使用している場合は左右の同期が取れるが、マウス位置やループ毎の加算のような場合は変更が必要。
         count = Date.now() / 500; //マウス位置をDateでせって
         mouseX = mouseY = 0;
          //cameraの位置に視差を設定
          if ( rotate ) {
              //初期亜k時に設定したパラメータでx方向位置を調整
              var x = (typeof param == "undefined" ? 0 : param.cameraX);
              //camera.position.x = Math.cos( timer ) * 1500;
              camera.position.x = Math.cos( timer ) * 1500 + x;
              ..... 
          }
      }

リンクのパス
<script src="../examples/js/Cloth.js"></script>など
このサンプルでは同じになるように配置してあるが、異なる場合は構成に応じて変更。

2015年5月8日金曜日

Cardboard実験サイト2.1 / HTML (div構成)

概要

iPhoneを横位置にしたときに画面を二分割し、視差のあるイメージを表示します。
共通のjavascript(cardboard.js)は画面レイアウト設定と、左右の画面に対する処理を一括して行う機能を提供します。
タイマーイベントで描画関数を呼び、オブジェクトを移動させ、アニメを作ります。

このサンプルではdivだけで画面を構成しています。同一window内にあるため変数を共有でき、アニメ描画のためのループも左右で同じタイミングで行えます。

残念ながら、translate、rotateの結果divからはみ出してもクリッピングしてくれません。
クリッッピングが必要な場合はCardboard実験サイト2.2 / HTML (iframe構成)をご覧ください。

画面レイアウト設定
タグ構造 

bodyタグ内は次のようにdivを数階層積み重ねたものです。
javascript、cssはdivのidを使用するので、idはこのとおりにしておきます。

  <body onload="init();" ontouchmove="blockMove(event)" >
    <div id="container">
      <div id="outerBox">
        <div id="boxR">
          <div id="canvasR"></div>
        </div>
        <div id="boxL">
          <div id="canvasL"></div>
        </div>
      </div>
    </div>
  </body>

index.htmlのjavascript
js/cssインポート

    <script src="../../js/cardboard.js"></script>
    <script src="../js/Plate.js"></script>
    <script src="Plate1.js"></script>
    <link rel="stylesheet" type="text/css" href="../../css/cardboard.css" />

javascript
index.html

    //body.onloadで呼び出し、初期化を実行。
    function init() {
        Config.setBoxSizes();
        Config.setParspective(parsXd, parsYd, parsZ);
        var obj = Canvas.add(Part);
        obj.setParam({key:val, ... });
        Canvas.start();
    }
      function blockMove(event) {
          event.preventDefault();
      }

Plate1の場合
index.html

    function init() {
          Config.setBoxSizes();
          Config.setParspective(4, 0, 100);

          var tx = Config.centerX - 50;
          var ty = Config.centerY - 35;

          var p1 = Canvas.add(Plate1);
          p1.setParam({"tx":tx, "ty":ty, "tz":50, "rx":0, "ry":0, "rz":0, "c":"#ddf" });

          var p2 = Canvas.add(Plate1);
          p2.setParam({"tx":(tx-10), "ty":(ty-10), "tz":40, "rx":50, "ry":50, "rz":50, "c":"#dfd" });

          var p3 = Canvas.add(Plate1);
          p3.setParam({"tx":(tx+10), "ty":(ty+10), "tz":30, "rx":-50, "ry":-50, "rz":-50, "c":"#fdd" });

          Canvas.start();
      }

Plate1.js

    Plate1 = function(parentDiv, side, div) {
          //Plateのコンストラクタを継承。PlateはPartを継承。
          Plate.apply(this,arguments);
          this.div.innerText = "\n 3D Sample \n ";
          this.div.style.border = "solid 1px black";
    }
     //Plataのprototypeを継承
    Plate1.prototype = new Plate();
    //パラメータを変数にセット。
    Plate1.prototype.setParam = function(param) {
        this.Param = param;
        this.tx = param["tx"];
        this.ty = param["ty"];
        this.tz0 = this.tz = param["tz"];
        this.rx = param["rx"];
        this.ry = param["ry"];
        this.rz = param["rz"];
        this.div.style.backgroundColor = param["c"];
    }
    //Canvasのタイマイベントで呼ばれる。
    Plate1.prototype.move = function() {
        this.rx += 1;
        this.ry += 0.5;
        this.rz += 1;
        if (this.tz > -150)
            this.tz -= 2;
        else
             this.tz = this.Param["tz"];;
        this.div.style.webkitTransform = "translateX(" + this.tx + "px) "
                                                              + "translateY(" + this.ty + "px) "
                                                              + "translateZ(" + this.tz + "px) "
                                                              + "rotateX("+ this.rx + "deg) "
                                                              + "rotateY("+ this.ry + "deg) "
                                                              + "rotateZ("+ this.rz + "deg) ";
    }

canva.jsの関数

Config.setBoxSizes();
Config.setFrames();
Config.setFrameCanvas(window.name);
  デバイス横位置の大きさに合わせて左右の画面をリサイズ、イベント設定を行う。

Config.setParspective(parsXd, parsYd, parsZ);
  視点、視差を設定。
  parsXd 画面中心からの左右距離(px)。
                左画面はマイナス、右画面はプラスし、視差を作る。
  parsYd 画面中心からの上下距離(px)      
  parsZ   画面からの遠近距離。

var obj = Canvas.add(Part);
    Canvasにオブジェクトを追加。
  Part Parts(後述)のサブクラス。
  
  obj.setParam(param);
    param objが使用するパラメータを設定。
                例: {"tx":tx, "ty":ty, "tz":50, "rx":0, "ry":0, "rz":0, "c":"#ddf" }
                     パラメータのキー定義、値の適用はPartが実装。

 Canvas.start();
  タイマーイベントスタート。
  デフォルトは50msecの間隔でイベント実行。
  描画に50msec以上かかる場合は、描画完了後に次のイベントを実行。

  Part.prototype.move();
    タイマーイベントで呼ばれるfunction。
    デフォルトでは何も行わないので、各Partsで実行する。

2015年4月2日木曜日

Cardboard実験サイト


Google / Cardboard仕様のハコスコを購入したので、これで見る3D画像をHTMLで作ってみました。

せっかくなので、iPhoneで見られる(多分Androidも可)Webサイトにしました。
Cardboard

Android端末でも動作可能ですが、あまりチェックしていません。動作不良の場合も、若干の修正で対応可能なはずです。

デスクトップのSafari/ChromeでもGyroscopeを使うもの以外は動作しますので、お試しください。

このサイトについての解説をブログの載せていきます。
以下、上記サイトのトップページです。
Cardboard
段ボール製3Dゴーグルで見る3DアニメをHTMLで作ろう、という実験サイトです。
ゴーグルがなくても立体視は可能です。
フリーの映像も多く出回っていますが、自分でも作ってみませんか?
このサイトと連動してブログに説明を載せていきます。
楽しみ方
  • 画面操作について

  • 3D画像を見る方法
HTML HTML5のrotate/transleteを利用した3Dアニメ、写真
Three.js WebGLを利用するJavaScriptライブラリのThree.jsを使った3Dアニメ。
Gyro iOS/Android端末のGyroと連動する360°のパノラマ写真ビューワ。今のところ3Dではありません。

リンク Cardboardで見る動画関連リンク
ダウン
ロード
このサイトのjavascript等のダウンロード。
  • iOS8のiPhoneが主対象です。Android端末でも動作可能ですが、あまりチェックしていません。
  • PC/MacではChromeで動作します。IEでも動作可能でが、あまりチェックしていません。
  • Safari/Macの場合はWebGLの有効化により、動作可能になります。
  • Three.jsを利用する場合はライセンスに従ってください。基本的に自由に利用できますが、再利用物にオリジナルのライセンスを同梱してください。Exampleなどには個別にライセンスが含まれるものもあります。
  • このサイトに含まれるその他のリソースについてはオリジナルのライセンス、または明記されていない場合は上記ライセンスを適用するものとします。