zhiqim_webgl_three.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
  3. *
  4. * 指定登记&发行网站: https://www.zhiqim.com/ 欢迎加盟知启蒙,[编程有你,知启蒙一路随行]。
  5. *
  6. * 本文采用《知启蒙登记发行许可证》,除非符合许可证,否则不可使用该文件!
  7. * 1、您可以免费使用、修改、合并、出版发行和分发,再授权软件、软件副本及衍生软件;
  8. * 2、您用于商业用途时,必须在原作者指定的登记网站,按原作者要求进行登记;
  9. * 3、您在使用、修改、合并、出版发行和分发时,必须包含版权声明、许可声明,及保留原作者的著作权、商标和专利等知识产权;
  10. * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时,必须在原作者指定的发行网站进行发行和分发;
  11. * 5、您可以在以下链接获取一个完整的许可证副本。
  12. *
  13. * 许可证链接:http://zhiqim.org/licenses/zhiqim_register_publish_license.htm
  14. *
  15. * 除非法律需要或书面同意,软件由原始码方式提供,无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
  16. */
  17. +(function(Z)
  18. {
  19. //BEGIN
  20. /**
  21. * WebGL+three.js 3D动画,当前有波浪和光线球两种
  22. */
  23. Z.WebGLThree = Z.Class.newInstance();
  24. Z.WebGLThree.prototype =
  25. {
  26. defaults:
  27. {
  28. //常量
  29. SEPARATION: 125,
  30. AMOUNTX: 35,
  31. AMOUNTY: 35,
  32. //传入参数
  33. threePath: null,
  34. target: null,
  35. //内部对象
  36. camera: null,
  37. scene: null,
  38. renderer: null,
  39. particles_ware: [],
  40. particles_globe: [],
  41. //运行时
  42. count: 0,
  43. mouseX: 0,
  44. mouseY: 0,
  45. windowHalfX: window.innerWidth / 2,
  46. windowHalfY: window.innerHeight / 2,
  47. rotation_speed: .002,
  48. timeout: null
  49. },
  50. execute: function()
  51. {
  52. if (Z.B.mobile || Z.B.msieVer <= 9)
  53. {//移动端和IE9以下不支持
  54. return;
  55. }
  56. if (this.threePath == null || this.target == null)
  57. {//两个参数必须
  58. return;
  59. }
  60. if (Z.Types.isString(this.target))
  61. this.target = Z("#"+this.target);
  62. else if (Z.Types.isElement(this.target))
  63. this.target = Z(this.target);
  64. else
  65. return;
  66. //先加载three.js,再初始化init
  67. Z.loads(this.threePath, Z.bind(this.initWebGL, this));
  68. },
  69. initWebGL: function()
  70. {
  71. var animationType = Math.floor(2 * Math.random());
  72. if (animationType == 0)
  73. {//波浪
  74. this.initWave();
  75. this.animateWave();
  76. }
  77. else
  78. {//光球
  79. this.initGlobe();
  80. this.animateGlobe();
  81. }
  82. //增加事件处理
  83. Z(document).mousemove(this.onDocumentMouseMove, this)
  84. .on("touchstart", this.onDocumentTouchStart, this)
  85. .on("touchmove", this.onDocumentTouchMove, this);
  86. Z(window).resize(this.onWindowResize, this);
  87. },
  88. /******************************************************************************************/
  89. //光球
  90. /******************************************************************************************/
  91. initGlobe: function initGlobe()
  92. {
  93. this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1e4),
  94. this.camera.position.z = 500,
  95. this.scene = new THREE.Scene;
  96. for (var t = 2 * Math.PI, i = function (e) {e.beginPath(), e.arc(0, 0, 25, 0, t, true), e.fill()}, t = 2 * Math.PI, n = 0; 500 > n; n++)
  97. {
  98. var o = new THREE.SpriteCanvasMaterial({color: 16777215,
  99. transparent: true,
  100. program: function (e) {e.beginPath(), e.arc(0, 0, .5, 0, t, true), e.fill()}});
  101. var particle = new THREE.Sprite(o);
  102. particle.position.x = 2 * Math.random() - 1;
  103. particle.position.y = 2 * Math.random() - 1;
  104. particle.position.z = 2 * Math.random() - 1;
  105. particle.position.normalize();
  106. particle.position.multiplyScalar(10 * Math.random() + 450);
  107. particle.scale.multiplyScalar(4 + 2 * Math.random());
  108. particle.material.opacity = .1;
  109. this.scene.add(particle);
  110. this.particles_globe.push(particle);
  111. }
  112. for (var n = 0; 500 > n; n++)
  113. {
  114. var s = new THREE.Geometry;
  115. var r = new THREE.Vector3(2 * Math.random() - 1, 2 * Math.random() - 1, 2 * Math.random() - 1);
  116. r.normalize();
  117. r.multiplyScalar(450);
  118. s.vertices.push(r);
  119. var a = r.clone();
  120. a.multiplyScalar(.3 * Math.random() + 1), s.vertices.push(a);
  121. var l = new THREE.Line(s, new THREE.LineBasicMaterial({color: 16777215, opacity: .3}));
  122. this.scene.add(l)
  123. }
  124. this.renderer = new THREE.CanvasRenderer({alpha: true});
  125. this.renderer.setClearColor(0, 0);
  126. this.renderer.setSize(window.innerWidth, window.innerHeight);
  127. this.target.append(this.renderer.domElement)
  128. },
  129. animateGlobe: function()
  130. {
  131. requestAnimationFrame(Z.bind(this.animateGlobe, this));
  132. this.renderGlobe();
  133. },
  134. renderGlobe: function()
  135. {
  136. var e = Z("body:hover"), t = this.camera.position.x, i = this.camera.position.y, n = this.camera.position.z;
  137. if (e.length != 0 && this.timeout != null)
  138. {
  139. this.camera.position.x += .05 * (this.mouseX - this.camera.position.x);
  140. }
  141. else
  142. {
  143. this.camera.position.x = t * Math.cos(this.rotation_speed) - n * Math.sin(this.rotation_speed);
  144. this.camera.position.z = n * Math.cos(this.rotation_speed) + t * Math.sin(this.rotation_speed);
  145. }
  146. this.camera.position.y += .05 * (-this.mouseY + 200 - this.camera.position.y);
  147. this.camera.lookAt(this.scene.position);
  148. Z(document).mousemove(function () {
  149. this.timeout !== null && clearTimeout(this.timeout), this.timeout = setTimeout(function () {this.timeout = null}, 600)
  150. });
  151. for (var o = 0; o < this.particles_globe.length; o++)
  152. {
  153. var particle = this.particles_globe[o++];
  154. temp = 50 * Math.sin(.3 * (o + this.count)) + .5 * Math.sin(.5 * (o + this.count));
  155. opacity = Math.abs(temp) / 50 + .1;
  156. opacity > 1 && (opacity = 1);
  157. particle.material.opacity = opacity;
  158. }
  159. this.renderer.render(this.scene, this.camera);
  160. this.count += .1;
  161. },
  162. /******************************************************************************************/
  163. //波浪
  164. /******************************************************************************************/
  165. initWave: function()
  166. {
  167. this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1e4);
  168. this.camera.position.z = 1e3;
  169. this.camera.position.y = 100;
  170. this.camera.position.y = 1e3;
  171. this.scene = new THREE.Scene;
  172. for (var t = 2 * Math.PI, i = 0, n = 0; this.AMOUNTX > n; n++)for (var o = 0; this.AMOUNTY > o; o++)
  173. {
  174. var s = new THREE.SpriteCanvasMaterial({color: 16777215,
  175. transparent: true,
  176. program: function (e) {e.beginPath(), e.arc(0, 0, .5, 0, t, true), e.fill()}});
  177. var particle = this.particles_ware[i++] = new THREE.Sprite(s);
  178. particle.position.x = n * this.SEPARATION - this.AMOUNTX * this.SEPARATION / 2;
  179. particle.position.z = o * this.SEPARATION - this.AMOUNTY * this.SEPARATION / 2;
  180. this.scene.add(particle), particle.material.opacity = .4;
  181. }
  182. this.renderer = new THREE.CanvasRenderer({alpha: true});
  183. this.renderer.setClearColor(0, 0);
  184. this.renderer.setSize(window.innerWidth, window.innerHeight);
  185. this.target.append(this.renderer.domElement);
  186. },
  187. animateWave: function()
  188. {
  189. requestAnimationFrame(Z.bind(this.animateWave, this));
  190. this.renderWave();
  191. },
  192. renderWave: function()
  193. {
  194. this.camera.position.x += .01 * (this.mouseX - this.camera.position.x),
  195. this.camera.position.y += .005 * (this.mouseY - this.camera.position.y),
  196. this.camera.lookAt(this.scene.position);
  197. for (var e = 0, t = 0; this.AMOUNTX > t; t++)
  198. {
  199. for (var i = 0; this.AMOUNTY > i; i++)
  200. {
  201. var particle = this.particles_ware[e++];
  202. particle.position.y = 50 * Math.sin(.3 * (t + this.count)) + 50 * Math.sin(.5 * (i + this.count));
  203. particle.scale.x = particle.scale.y = 4 * (Math.sin(.3 * (t + this.count)) + 1) + 4 * (Math.sin(.5 * (i + this.count)) + 1);
  204. opacity = Math.abs(particle.position.y) / 100;
  205. opacity < .5 && (opacity = .5);
  206. opacity > 1 && (opacity = 1);
  207. particle.material.opacity = opacity;
  208. }
  209. }
  210. this.renderer.render(this.scene, this.camera);
  211. this.count += .03
  212. },
  213. /******************************************************************************************/
  214. //事件处理
  215. /******************************************************************************************/
  216. onWindowResize: function()
  217. {//缩放
  218. this.windowHalfX = window.innerWidth / 2,
  219. this.windowHalfY = window.innerHeight / 2,
  220. this.camera.aspect = window.innerWidth / window.innerHeight,
  221. this.camera.updateProjectionMatrix(),
  222. this.renderer.setSize(window.innerWidth, window.innerHeight);
  223. },
  224. onDocumentMouseMove: function(e)
  225. {//鼠标移动
  226. this.mouseX = e.clientX - this.windowHalfX, this.mouseY = e.clientY + 150;
  227. },
  228. onDocumentTouchStart: function(e)
  229. {//iOS触摸开始
  230. 1 === e.touches.length && (e.preventDefault(), this.mouseX = e.touches[0].pageX - this.windowHalfX, this.mouseY = -e.touches[0].pageY);
  231. },
  232. onDocumentTouchMove: function(e)
  233. {//iOS触摸移动
  234. 1 === e.touches.length && (e.preventDefault(), this.mouseX = e.touches[0].pageX - this.windowHalfX, this.mouseY = -e.touches[0].pageY);
  235. }
  236. };
  237. //END
  238. })(zhiqim);