デモページ アニメーション開始は右上のボタン ※ リロードするとアニメーション前の初期状態に戻ります ▼ 飛翔画像 以前、v57 頃の時に作成した平面の『蝶』の画像を飛翔させるデモです。バージョンがかなり変わって前のままでは動作しなくなったものを少し修正してさらに使いやすくかつ解りやすくしました。『飛翔』そのもののコードは、Three.js 内で今も使われているもので昔から全く変わっていません。この部分は、boid.js として外部ファイルとして取り出してあります。 ただ、Canvas のレンダリング部分(CanvasRenderer.js)は v73 では外部ファイルとなって Three.js 本体からは外されていました。また、さらに実行の為に Projector.js というファイルも必要になっていました。 HTML 部分
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <link rel="shortcut icon" href="http://winofsql.jp/WinOfSql.ico"> <script src="three.min73.js"></script> <script src="CanvasRenderer.js"></script> <script src="Projector.js"></script> <script src="boid.js"></script> </head> <body style="margin:0"> <div style="position:absolute;width:98%"> <input type="button" value="アニメーション開始" style="position:relative;float:right;" onclick="window.animate();this.style.display='none'" title="ページをリロード(再表示)するとアニメーションは止まります"> </div> <div id="container"></div> <script src="birds73.js"></script> </body> </html>
Three.js 実行環境部分(birds73.js)
// ************************************************* // Three.js の環境設定 // ************************************************* var SCREEN_WIDTH = window.innerWidth * 0.98; var SCREEN_HEIGHT = window.innerHeight * 0.98; var SCREEN_WIDTH_HALF = SCREEN_WIDTH / 2; var SCREEN_HEIGHT_HALF = SCREEN_HEIGHT / 2; var camera, scene, renderer, birds, bird; var boid, boids; var stats; // お決まりの初期処理とアニメーション開始 init(); // animate 内の render が実行されても、init の処理が完了していないと描画されません // なので、アニメーション無しの1回限りの描画は、setTimeout か、画像の最終イベント内で実行します //animate(); function init() { camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 ); camera.position.z = 450; scene = new THREE.Scene(); birds = []; boids = []; // 背景画像・人物画像用ラッパー var parent = new THREE.Object3D(); // ************************************************* // 背景画像の読み込み // ************************************************* var image = new Image() image.onload = function () { var texture = new THREE.Texture( this ); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({map: texture, overdraw: true}); // 平面 var mesh = new THREE.Mesh(new THREE.PlaneGeometry(1200, 1200, 1, 1), material); // 画面奥 mesh.position.z = -400; // 大きさ調整 mesh.scale.x = 1.5; mesh.scale.y = 1.5; // 回転 mesh.rotation.x = 0; mesh.rotation.y = 0; // ラッパーに平面追加 parent.add( mesh ); // ************************************************* // 人物画像の読み込み // ************************************************* var image = new Image() image.onload = function () { var texture = new THREE.Texture( this ); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({map: texture, overdraw: true}); // 平面 var mesh = new THREE.Mesh(new THREE.PlaneGeometry(778, 623, 1, 1), material); // 画面前 mesh.position.z = 300; // 表示位置調整 mesh.position.x = 80; mesh.position.y = -42; // 大きさ調整 mesh.scale.x = 0.3; mesh.scale.y = 0.3; // 回転 mesh.rotation.x = 0; mesh.rotation.y = 0; // ラッパーに平面追加 parent.add( mesh ); // シーンにラッパー(画像2枚)追加 scene.add(parent); // ************************************************* // 飛翔画像の読み込み // ************************************************* var image = new Image() image.onload = function () { texture = new THREE.Texture( this ); texture.needsUpdate = true; material = new THREE.MeshBasicMaterial({map: texture, overdraw: true}); material.side = 2 // 200の飛翔物体 for ( var i = 0; i < 200; i ++ ) { boid = boids[ i ] = new Boid(); boid.position.x = Math.random() * 400 - 200; boid.position.y = Math.random() * 400 - 200; boid.position.z = Math.random() * 400 - 200; boid.velocity.x = Math.random() * 2 - 1; boid.velocity.y = Math.random() * 2 - 1; boid.velocity.z = Math.random() * 2 - 1; boid.setAvoidWalls( true ); boid.setWorldSize( 500, 500, 400 ); // 飛翔画像を貼り付けたマテリアルを平面に適用 birds[ i ] = new THREE.Mesh( new THREE.PlaneGeometry(30, 30, 2, 1), material ); // オリジナルの特殊処理 bird = birds[ i ] bird.phase = Math.floor( Math.random() * 62.83 ); // 飛翔物体単位でシーンに追加 scene.add( bird ); } // 初回表示 render(); }; // 飛翔画像 image.src = "002.png"; }; // 人物画像 image.src = "girl.png"; } // 背景画像 image.src = "moon.jpg"; renderer = new THREE.CanvasRenderer(); renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.body.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth * 0.98, window.innerHeight * 0.98 ); render(); } // マウスによる、飛翔物体の反応処理 function onDocumentMouseMove( event ) { var vector = new THREE.Vector3( event.clientX - SCREEN_WIDTH_HALF, - event.clientY + SCREEN_HEIGHT_HALF, 0 ); for ( var i = 0, il = boids.length; i < il; i++ ) { boid = boids[ i ]; vector.z = boid.position.z; boid.repulse( vector ); } } // Three.js のお決まりの処理 function animate() { requestAnimationFrame( animate ); render(); } function render() { // 飛翔物体の処理 for ( var i = 0, il = birds.length; i < il; i++ ) { boid = boids[ i ]; boid.run( boids ); bird = birds[ i ]; // 旧版では無かった処理 bird.position.copy( boids[ i ].position ); // 飛翔物体の飛翔用の傾け処理 bird.rotation.y = Math.atan2( - boid.velocity.z, boid.velocity.x ); bird.rotation.z = Math.asin( boid.velocity.y / boid.velocity.length() ); // 画像を x 軸で90度回転して、横に寝かせる bird.rotation.x = (180 * Math.PI / 180)/2; // オリジナルの特殊処理 bird.phase = ( bird.phase + ( Math.max( 0, bird.rotation.z ) + 0.1 ) ) % 62.83; // 平面画像のはばたき処理 bird.geometry.vertices[ 0 ].z = Math.sin( bird.phase ) * 15; bird.geometry.vertices[ 2 ].z = Math.sin( bird.phase ) * 15; // 0 1 2 // 3 4 5 // セグメントが 2x1 なので、0番と 2番を動かすと、羽の先が動きます。 // 羽全体を動かすのであれば、3番と5番も同時に値を変更してもいいです } renderer.render( scene, camera ); }
birds73.js も殆どは Three.js のサンプルと変わりませんが、Three.js では鳥に見立てた頂点を持つオブジェクトが使用されています。こちらでは、平面を 2 セグメントに分けて、頂点を6つ持ったオブジェクトの 0 番と 2番を 動かせて『飛翔』させています。 ※ 詳細は、ソースコード内のコメントに書かれてあります 画像の配置 画像は全て canvas 内に配置しているので、Google Chrome や Firefox ならばそのまま保存して、その時の画像を取得する事ができます。月画像は奥に、人物画像は手前にありますが、飛翔物体がかなり手前に来た場合は人物を突き抜けるのはご愛嬌です。 画像のロードは 3種類あるので 3段階で行っています。背景 => 前景 => 飛翔画像と、各画像がロードされてから次の画像の処理へと移っています Window サイズ変更時 全て Canvas 内なので Window サイズにあわせて表示は縮小されますが、アニメーションはそのまま実行されます。もともとは、IFRAME 内で表示する事を想定しており、お好きなサイズでページに埋め込む事ができます。
|
【JavaScript ライブラリの最新記事】
- clipboard.js を使用してテキストをコピーする際に clipboard.js が必要とするパーツと意味
- clipboard.js のコピーさせるテキストを自由にダイナミックに渡す方法は、Advanced Usage の text です。
- JavaScript の内部コード文字列を SHIFT_JIS としてダウンロードさせる方法
- 自サイト(logical error を含む)で使用している SyntaxHighlighter のツールバーの問題点をごっそり自前で修正・カスタマイズしました。( その2 / ソースをクリップボード..
- 自サイト(logical error を含む)で使用している SyntaxHighlighter のツールバーの問題点をごっそり自前で修正・カスタマイズしました。( その1 / ソースの表示 )
- ブラウザ上のテキストデータを名前を付けて保存できる FileSaver.js を使って、テーブルのデータを Excel で開ける事を想定した CSV にして PC に保存
- JavaScript のみで、SHIFT_JIS や EUC-JP を UrlEncode に近い Escapeする Escape Codec Library
- JavaScript でクリップボードに文字列をコピーする Clipboard.js の使用方法と注意事項
- Lightbox2 ライブラリの今時の使い方
- Google Visualization API って apikey いらなくなった? / ライブラリロード方法が変わってました
- Lightbox2 で data-title にボタンを埋め込んで、クリックしたら 画像のファイル名を取り出して Lightbox2 を閉じるギャラリーのデモ
- EASELJS を使用した画像の分割と分割されたエリア毎のアニメーション / createjs.Ticker の reset と init はうまく動きませんでした
- EASELJS を使用した画像の縮小とトリミングと角丸マスク / 画像は new Image でイベント処理して画像サイズを取得します
- クリスマスに備えて、『雪を降らす snowstorm.js』のカスタマイズ / ダウンロードも何も必要ありません。jQuery も必要ありません
- JavaScript : 誰でもすぐ使える Google 円グラフ(2) : データを Google ドキュメントから取得する
- JavaScript : 誰でもすぐ使える Google 円グラフ
- カラーピッカーのライブラリなのですが、ちょっと雑な作りだったので、修正してリリースです。
- google.load で Yahoo UI のメニューを使う