css3d_youtube.html 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  6. <title>three.js css3d - youtube</title>
  7. <style>
  8. html, body {
  9. height: 100%;
  10. }
  11. body {
  12. background-color: #000000;
  13. margin: 0;
  14. font-family: Arial;
  15. overflow: hidden;
  16. }
  17. #search {
  18. position: absolute;
  19. bottom: 30px;
  20. width: 100%;
  21. text-align: center;
  22. }
  23. #search input {
  24. color: #ffffff;
  25. background-color: transparent;
  26. border: 1px solid #0080ff;
  27. padding: 10px;
  28. font-size: 20px;
  29. text-transform: uppercase;
  30. -webkit-border-radius: 0px; /* workaround for ios safari */
  31. }
  32. #search button {
  33. color: #0080ff;
  34. background-color: transparent;
  35. border: 1px solid #0080ff;
  36. padding: 10px;
  37. font-size: 20px;
  38. text-transform: uppercase;
  39. cursor: pointer;
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <script src="../build/three.min.js"></script>
  45. <script src="js/libs/tween.min.js"></script>
  46. <script src="js/renderers/CSS3DRenderer.js"></script>
  47. <div id="container"></div>
  48. <div id="search"><input id="query" type="text" value="cats"><button id="button">search</button></div>
  49. <script>
  50. var camera, scene, renderer;
  51. var player;
  52. var auto = true;
  53. var Element = function ( entry ) {
  54. var dom = document.createElement( 'div' );
  55. dom.style.width = '480px';
  56. dom.style.height = '360px';
  57. var image = document.createElement( 'img' );
  58. image.style.position = 'absolute';
  59. image.style.width = '480px';
  60. image.style.height = '360px';
  61. image.src = entry.media$group.media$thumbnail[ 2 ].url;
  62. dom.appendChild( image );
  63. var button = document.createElement( 'img' );
  64. button.style.position = 'absolute';
  65. button.style.left = ( ( 480 - 86 ) / 2 ) + 'px';
  66. button.style.top = ( ( 360 - 61 ) / 2 ) + 'px';
  67. button.style.visibility = 'hidden';
  68. button.style.WebkitFilter = 'grayscale()';
  69. button.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFYAAAA9CAYAAAA3ZZ5uAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wLBQ0uMbsnLZIAAAbXSURBVHja7ZxvbBvlHcc/z/maf4PGg9FtbaZeS2I1iUgP1q7QEmFpmxB7AYxXk/aCvETaC/Zy2qSpk7apL/YCTbCyoU0uUAGdRv8uVCorzsQGSRu4tFoahbYxpEkKayvHaRInvnt+e5HEzb92cez4bHRfyS/ufPbd8/H3vs/vZ99Zkac+erB5OxhhAG1oS4myZp5RYVFi5/PeSpSFwrrd84I4QDLH93RAksusjwM89PH5DgoglcvGZ+ymp8RQTytRliCWUsriyywhCTiiJKFQCaUmXtjRfXk0b7Bnv7211vUq2xSqDaVsAoGII0jMDE3F7gT5tmA/tJue0qiYgnBAczkzkzSQtoed3qMrBvt+y7ZnlTJiAb6VGFi3PXqu78D/Bft+y7ZnhQBqbhPVUrgLwP6rsXGza+IEp3/usWC62HsuXPh0bp05f4NMSGKgwhKwylXhTIgXgB8ucezp5sh2MJyAUR7O1cr67qxrs471kDZF4NW8slbpNuBXC8CKNmxRAZz8LKuiS8BqJBoYNm9FF2Rs+7b6x8CIB1wKIR39Qd/FDnOmyFU2gV0LlbQ2MAPW02Ip5UPAVlXB44/Dxk0zy8NDcOYMDA+XcScmVjZjtWD7URFU79zJzp//gtraWgBGR0cZGBhgsLMT3nyjLAGLYGfBimhbKL5jv7FnTxYqQG1tLbZtE4lE6N+1i5Hjx5n+x7vlBVjkFlitlC8t7Ncbm5ZdX1NTg23bNDc30//MM3wWj5P+66HyADzLUv1ty5bN2lAJP46h9bXXuW/XrhVt29/fT197O96Rw0iJAza0WKYnYkkZdAaRSIRIJMLlJ5+k7+23mTx+vGQBi4hlagiL+FNqrWavW7du5VvPP0//E0+QaG9n4sQJZGiotNIAwqaA7RNXRITVfKimadLU1IRlWfRGowydepfMyZPo0gFsm54mjPKLbH4vr6mpYceOHTQ0NHDu0T1cO3aMqXdOwuSkz1lA2NQitn/7L8wHWltbS2trK4OWRX80SrL9Habicf8AC7apfexkRaCQ+V5XV0ddXR399fVc2rObsTcPkTl/3pcz0dRI2D+wwlpMnA0NDWzatIlPGhsZPHWK1FuH0DduFHNoYVOD7df3L3qNwAJUV1fT0tJCfX09Zx94gKuxA0x1dhVv8tIiPkaBRkSv7fcR1VW0fv97DNTfz5lf/5Z0vKMoYzNmcs6vhxTtYVkWj+z9JcbGjUUZm6+O1SLoIs6eVckUjKYoxph9joK1y9jFutrZyennfkJmbKwo+/O53JI1z9jpVIre2Ks4v3+pqGPzNwq0Rmu9hi7tous3+7hxoa/oYzO1f4ZFa1kTsDevDOG8+AcuHj7q29jMSddzKkOGL22tlsI69ubQEM6L+30FCjDlacesMFTSrzSYiQKvAECHuXj4GD0vvVwSX21VGCo5O3mJj2BX79jp1Bi9rx2k99WDZMZuUkoytXgOGNFyAjudGuOz0+/Rte93JQcUIK11whStkn79MuNpjed5OQG9ePQEPfv/VJJA51SJSpifuy5fM82Sj4Le19+gZ/8rJQ10TtdcF/MejLhfTYKnPTzPvb1Dx8YYfO+f9Lz8Z8aHr1Iuugcjbn7iprnfqPblAEa6urnvwe1LZ/nhET4/+zHn/vgXxkfKB+icLrlpzEtpN7Glwp8D+M/BQ3yzdTdfjTRkgQ78/STnX4lRzrqUdhMK4Gd33SvrlH/XFmx4aMa1X3zUQ7krI8K+m9eVCTCudXK9EfLtJ5qr3eUPdE7jWidh7opuEUeLRAmUv0ScLNgJTydqlBFAKYAmPJ3Igp0UHB1c0F0QTQq3HDuQmXY2hkIBlQJoIDPtwLwb6H687m7ZYJgBmTx0Q3scyKTUrckLmBKJC8EElo9S4mXv7MyC/UJ7RzaoUNRUwV10q9V1rbOdjXGr/pqMXRMvoLNK/Vd7uFqOLAHbDaMj4sZcCcqDXOWKcEUysX+T/nQJWADPY29Cu8kAVW5KaDfpeeydv25BjTWIO3qvClVVoKJfCRqGFemyznAd77kPJN1xW7AAV8TtuAvDAuz1Adw7nv4JcbkmXtuHXnrJf8Is2xVcEffoelQ4KfrhdUpRHQBeAPS6aC5LJpny3B91ytRby213x9rqEaoekxB7K1DRShTzHVyBolIpalB8mUu0lGjGZi+DSolmAo0nxDI6/dNuyP1/t+ZrN1WbBSwxmN9AWCgsEbGVUuEaFKFF8AHuXrTsd7xMiTA1+3P/hGjmF5jjs8sewgQCQgJFQkQchUoqTXyatHMnoDmBXYm+w7rtIULhRfBBsbibK5nuTkQcpVQSIQEkAARJGlo5ChLzy6dc9T9S8wu+HzDbBQAAAABJRU5ErkJggg==';
  70. dom.appendChild( button );
  71. var blocker = document.createElement( 'div' );
  72. blocker.style.position = 'absolute';
  73. blocker.style.width = '480px';
  74. blocker.style.height = '360px';
  75. blocker.style.background = 'rgba(0,0,0,0.5)';
  76. blocker.style.cursor = 'pointer';
  77. dom.appendChild( blocker );
  78. var object = new THREE.CSS3DObject( dom );
  79. object.position.x = Math.random() * 4000 - 2000;
  80. // object.position.y = Math.random() * 2000 - 1000;
  81. object.position.y = 3000;
  82. object.position.z = Math.random() * - 5000;
  83. //
  84. image.addEventListener( 'load', function ( event ) {
  85. button.style.visibility = 'visible';
  86. new TWEEN.Tween( object.position )
  87. .to( { y: Math.random() * 2000 - 1000 }, 2000 )
  88. .easing( TWEEN.Easing.Exponential.Out )
  89. .start();
  90. }, false );
  91. dom.addEventListener( 'mouseover', function () {
  92. button.style.WebkitFilter = '';
  93. blocker.style.background = 'rgba(0,0,0,0)';
  94. }, false );
  95. dom.addEventListener( 'mouseout', function () {
  96. button.style.WebkitFilter = 'grayscale()';
  97. blocker.style.background = 'rgba(0,0,0,0.75)';
  98. }, false );
  99. dom.addEventListener( 'click', function ( event ) {
  100. event.stopPropagation();
  101. auto = false;
  102. if ( player !== undefined ) {
  103. player.parentNode.removeChild( player );
  104. player = undefined;
  105. }
  106. player = document.createElement( 'iframe' );
  107. player.style.position = 'absolute';
  108. player.style.width = '480px';
  109. player.style.height = '360px';
  110. player.style.border = '0px';
  111. player.src = 'http://www.youtube.com/embed/' + entry.id.$t.split( ':' ).pop() + '?rel=0&autoplay=1&controls=1&showinfo=0';
  112. this.appendChild( player );
  113. //
  114. var prev = object.position.z + 400;
  115. new TWEEN.Tween( camera.position )
  116. .to( { x: object.position.x, y: object.position.y - 25 }, 1500 )
  117. .easing( TWEEN.Easing.Exponential.Out )
  118. .start();
  119. new TWEEN.Tween( { value: prev } )
  120. .to( { value: 0 }, 2000 )
  121. .onUpdate( function () {
  122. move( this.value - prev );
  123. prev = this.value;
  124. } )
  125. .easing( TWEEN.Easing.Exponential.Out )
  126. .start();
  127. }, false );
  128. return object;
  129. };
  130. init();
  131. animate();
  132. function init() {
  133. camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 5000 );
  134. camera.position.y = - 25;
  135. scene = new THREE.Scene();
  136. renderer = new THREE.CSS3DRenderer();
  137. renderer.setSize( window.innerWidth, window.innerHeight );
  138. renderer.domElement.style.position = 'absolute';
  139. renderer.domElement.style.top = 0;
  140. document.getElementById( 'container' ).appendChild( renderer.domElement );
  141. //
  142. var query = document.getElementById( 'query' );
  143. query.addEventListener( 'keyup', function ( event ) {
  144. if ( event.keyCode === 13 ) {
  145. search( query.value );
  146. }
  147. }, false );
  148. var button = document.getElementById( 'button' );
  149. button.addEventListener( 'click', function ( event ) {
  150. search( query.value );
  151. }, false );
  152. if ( window.location.hash.length > 0 ) {
  153. query.value = window.location.hash.substr( 1 );
  154. }
  155. search( query.value );
  156. document.body.addEventListener( 'mousewheel', onMouseWheel, false );
  157. document.body.addEventListener( 'click', function ( event ) {
  158. auto = true;
  159. if ( player !== undefined ) {
  160. player.parentNode.removeChild( player );
  161. player = undefined;
  162. }
  163. new TWEEN.Tween( camera.position )
  164. .to( { x: 0, y: - 25 }, 1500 )
  165. .easing( TWEEN.Easing.Exponential.Out )
  166. .start();
  167. }, false );
  168. window.addEventListener( 'resize', onWindowResize, false );
  169. }
  170. function search( query ) {
  171. window.location.hash = query;
  172. for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
  173. ( function () {
  174. var object = scene.children[ i ];
  175. var delay = i * 15;
  176. new TWEEN.Tween( object.position )
  177. .to( { y: - 2000 }, 1000 )
  178. .delay( delay )
  179. .easing( TWEEN.Easing.Exponential.In )
  180. .onComplete( function () {
  181. scene.remove( object );
  182. } )
  183. .start();
  184. } )();
  185. }
  186. var request = new XMLHttpRequest();
  187. request.addEventListener( 'load', onData, false );
  188. request.open( 'GET', 'https://gdata.youtube.com/feeds/api/videos?v=2&alt=json&max-results=50&q=' + query, true );
  189. request.send( null );
  190. }
  191. function onData( event ) {
  192. var data = JSON.parse( event.target.responseText );
  193. var entries = data.feed.entry;
  194. // console.log( entries );
  195. for ( var i = 0; i < entries.length; i ++ ) {
  196. ( function ( data, time ) {
  197. setTimeout( function () {
  198. scene.add( new Element( data ) );
  199. }, time );
  200. } )( entries[ i ], i * 15 );
  201. }
  202. }
  203. function move( delta ) {
  204. for ( var i = 0; i < scene.children.length; i ++ ) {
  205. var object = scene.children[ i ];
  206. object.position.z += delta;
  207. if ( object.position.z > 0 ) {
  208. object.position.z -= 5000;
  209. } else if ( object.position.z < - 5000 ) {
  210. object.position.z += 5000;
  211. }
  212. }
  213. }
  214. function onMouseWheel( event ) {
  215. move( event.wheelDelta );
  216. }
  217. function onWindowResize() {
  218. camera.aspect = window.innerWidth / window.innerHeight;
  219. camera.updateProjectionMatrix();
  220. renderer.setSize( window.innerWidth, window.innerHeight );
  221. }
  222. function animate() {
  223. requestAnimationFrame( animate );
  224. TWEEN.update();
  225. if ( auto === true ) {
  226. move( 1 );
  227. }
  228. renderer.render( scene, camera );
  229. }
  230. </script>
  231. </body>
  232. </html>