circle.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. $(function() {
  2. //测试 路径属性
  3. var o = document.getElementsByTagName("body")[0];
  4. var num = 30; //控制数量
  5. var w = window.innerWidth;
  6. var h = o.offsetHeight;
  7. var max = 30;
  8. var _x = 0;
  9. var _y = 0;
  10. var _z = 550;
  11. var dtr = function(d) {
  12. return d * Math.PI / 180;
  13. };
  14. var rnd = function() {
  15. return Math.sin(Math.floor(Math.random() * 360) * Math.PI / 180);
  16. };
  17. var dist = function(p1, p2, p3) {
  18. return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2) + Math.pow(p2.z - p1.z, 2));
  19. };
  20. var cam = {
  21. obj: {
  22. x: _x,
  23. y: _y,
  24. z: _z
  25. },
  26. dest: {
  27. x: 0,
  28. y: 0,
  29. z: 1
  30. },
  31. dist: {
  32. x: 0,
  33. y: 0,
  34. z: 200
  35. },
  36. ang: {
  37. cplane: 0,
  38. splane: 0,
  39. ctheta: 0,
  40. stheta: 0
  41. },
  42. zoom: 1,
  43. disp: {
  44. x: w / 2,
  45. y: h / 2,
  46. z: 0
  47. },
  48. upd: function() {
  49. cam.dist.x = cam.dest.x - cam.obj.x;
  50. cam.dist.y = cam.dest.y - cam.obj.y;
  51. cam.dist.z = cam.dest.z - cam.obj.z;
  52. cam.ang.cplane = -cam.dist.z / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
  53. cam.ang.splane = cam.dist.x / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
  54. cam.ang.ctheta = Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z) / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
  55. cam.ang.stheta = -cam.dist.y / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
  56. }
  57. };
  58. var trans = {
  59. parts: {
  60. sz: function(p, sz) {
  61. return {
  62. x: p.x * sz.x,
  63. y: p.y * sz.y,
  64. z: p.z * sz.z
  65. };
  66. },
  67. rot: {
  68. x: function(p, rot) {
  69. return {
  70. // x: p.x,
  71. // y: p.y * Math.cos(dtr(rot.x)) - p.z * Math.sin(dtr(rot.x)),
  72. // z: p.y * Math.sin(dtr(rot.x)) + p.z * Math.cos(dtr(rot.x))
  73. x: p.x,
  74. y: p.y,
  75. z: p.y,
  76. };
  77. },
  78. y: function(p, rot) {
  79. return {
  80. x: p.x * Math.cos(dtr(rot.y)) + p.z * Math.sin(dtr(rot.y)),
  81. y: p.y,
  82. z: -p.x * Math.sin(dtr(rot.y)) + p.z * Math.cos(dtr(rot.y))
  83. };
  84. },
  85. z: function(p, rot) {
  86. return {
  87. x: p.x * Math.cos(dtr(rot.z)) - p.y * Math.sin(dtr(rot.z)),
  88. y: p.x * Math.sin(dtr(rot.z)) + p.y * Math.cos(dtr(rot.z)),
  89. z: p.z
  90. };
  91. }
  92. },
  93. pos: function(p, pos) {
  94. return {
  95. x: p.x + pos.x,
  96. y: p.y + pos.y,
  97. z: p.z + pos.z
  98. };
  99. }
  100. },
  101. pov: {
  102. plane: function(p) {
  103. return {
  104. x: p.x * cam.ang.cplane + p.z * cam.ang.splane,
  105. y: p.y,
  106. z: p.x * -cam.ang.splane + p.z * cam.ang.cplane
  107. };
  108. },
  109. theta: function(p) {
  110. return {
  111. x: p.x,
  112. y: p.y * cam.ang.ctheta - p.z * cam.ang.stheta,
  113. z: p.y * cam.ang.stheta + p.z * cam.ang.ctheta
  114. };
  115. },
  116. set: function(p) {
  117. return {
  118. x: p.x - cam.obj.x,
  119. y: p.y - cam.obj.y,
  120. z: p.z - cam.obj.z
  121. };
  122. }
  123. },
  124. persp: function(p) {
  125. return {
  126. x: p.x * cam.dist.z / p.z * cam.zoom,
  127. y: p.y * cam.dist.z / p.z * cam.zoom,
  128. z: p.z * cam.zoom,
  129. p: cam.dist.z / p.z
  130. };
  131. },
  132. disp: function(p, disp) {
  133. return {
  134. x: p.x + disp.x,
  135. y: -p.y + disp.y,
  136. z: p.z + disp.z,
  137. p: p.p
  138. };
  139. },
  140. steps: function(_obj_, sz, rot, pos, disp) {
  141. var _args = trans.parts.sz(_obj_, sz);
  142. _args = trans.parts.rot.x(_args, rot);
  143. _args = trans.parts.rot.y(_args, rot);
  144. _args = trans.parts.rot.z(_args, rot);
  145. _args = trans.parts.pos(_args, pos);
  146. _args = trans.pov.plane(_args);
  147. _args = trans.pov.theta(_args);
  148. _args = trans.pov.set(_args);
  149. _args = trans.persp(_args);
  150. _args = trans.disp(_args, disp);
  151. return _args;
  152. }
  153. };
  154. (function() {
  155. "use strict";
  156. var threeD = function(param) {
  157. this.transIn = {};
  158. this.transOut = {};
  159. this.transIn.vtx = (param.vtx);
  160. this.transIn.sz = (param.sz);
  161. this.transIn.rot = (param.rot);
  162. this.transIn.pos = (param.pos);
  163. };
  164. threeD.prototype.vupd = function() {
  165. this.transOut = trans.steps(
  166. this.transIn.vtx,
  167. this.transIn.sz,
  168. this.transIn.rot,
  169. this.transIn.pos,
  170. cam.disp
  171. );
  172. };
  173. var Build = function() {
  174. this.vel = 0.04;
  175. this.lim = 360;
  176. this.diff = 500;
  177. this.initPos = 100;
  178. this.toX = _x;
  179. this.toY = _y;
  180. this.go();
  181. };
  182. Build.prototype.go = function() {
  183. this.canvas = document.getElementById("canvas");
  184. this.canvas.width = window.innerWidth;
  185. this.canvas.height = o.offsetHeight;
  186. this.$circle = canvas.getContext("2d");
  187. this.$circle.globalCompositeOperation = 'source-over';
  188. this.varr = [];
  189. this.dist = [];
  190. this.calc = [];
  191. for (var i = 0, len = num; i < len; i++) {
  192. this.add();
  193. }
  194. this.rotObj = {
  195. x: 0,
  196. y: 0,
  197. z: 0
  198. };
  199. this.objSz = {
  200. x: w / 5,
  201. y: h / 5,
  202. z: w / 5
  203. };
  204. };
  205. Build.prototype.add = function() {
  206. this.varr.push(new threeD({
  207. vtx: {
  208. x: rnd(),
  209. y: rnd(),
  210. z: rnd()
  211. },
  212. sz: {
  213. x: 0,
  214. y: 0,
  215. z: 0
  216. },
  217. rot: {
  218. x: 20,
  219. y: -20,
  220. z: 0
  221. },
  222. pos: {
  223. x: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
  224. // y: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
  225. // z: this.diff * Math.sin(360 * Math.random() * Math.PI / 180)
  226. }
  227. }));
  228. this.calc.push({
  229. x: 360 * Math.random(),
  230. y: 360 * Math.random(),
  231. z: 360 * Math.random()
  232. });
  233. };
  234. Build.prototype.upd = function() {
  235. cam.obj.x += (this.toX - cam.obj.x) * 0.06;
  236. cam.obj.y += (this.toY - cam.obj.y) * 0.06;
  237. };
  238. Build.prototype.draw = function() {
  239. this.$circle.clearRect(0, 0, this.canvas.width, this.canvas.height);
  240. cam.upd();
  241. this.rotObj.x += 0.2;
  242. this.rotObj.y += 0.2;
  243. this.rotObj.z += 0.2;
  244. for (var i = 0; i < this.varr.length; i++) {
  245. for (var val in this.calc[i]) {
  246. if (this.calc[i].hasOwnProperty(val)) {
  247. this.calc[i][val] += this.vel;
  248. if (this.calc[i][val] > this.lim) this.calc[i][val] = 0;
  249. }
  250. }
  251. this.varr[i].transIn.pos = {
  252. x: this.diff * Math.cos(this.calc[i].x * Math.PI / 180),
  253. y: this.diff * Math.sin(this.calc[i].y * Math.PI / 180),
  254. z: this.diff * Math.sin(this.calc[i].z * Math.PI / 180)
  255. };
  256. this.varr[i].transIn.rot = this.rotObj;
  257. this.varr[i].transIn.sz = this.objSz;
  258. this.varr[i].vupd();
  259. if (this.varr[i].transOut.p < 0) continue;
  260. var g = this.$circle.createRadialGradient(this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p, this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p * 2);
  261. this.$circle.globalCompositeOperation = 'lighter';
  262. // g.addColorStop(1, 'hsla(255, 255%, 255%, 0.5)'); //最中间的小点
  263. // g.addColorStop(.5, 'hsla(' + (i + 2) + ',85%, 40%,1)');
  264. // g.addColorStop(1, 'hsla(' + (i) + ',85%, 50%,.3)'); //使用i的话,会不同的颜色
  265. // g.addColorStop(1, 'hsla(' + 273 + ',53%, 81%,.3)');
  266. g.addColorStop(1, 'hsla(' + 207 + ',73%, 44%,.3)');
  267. this.$circle.fillStyle = g;
  268. this.$circle.beginPath();
  269. this.$circle.arc(this.varr[i].transOut.x * 2, this.varr[i].transOut.y, this.varr[i].transOut.p * 30, 0, Math.PI * 2, false); //控制外边的阴影部分
  270. this.$circle.fill();
  271. this.$circle.closePath();
  272. }
  273. };
  274. Build.prototype.anim = function() {
  275. window.requestAnimationFrame = (function() {
  276. return window.requestAnimationFrame ||
  277. function(callback, element) {
  278. window.setTimeout(callback, 1000 / 60);
  279. };
  280. })();
  281. var anim = function() {
  282. this.upd();
  283. this.draw();
  284. window.requestAnimationFrame(anim);
  285. }.bind(this);
  286. window.requestAnimationFrame(anim);
  287. };
  288. Build.prototype.run = function() {
  289. this.anim();
  290. // window.addEventListener('mousemove', function(e) {
  291. // this.toX = (e.clientX - this.canvas.width / 2) * -0.8;
  292. // this.toY = (e.clientY - this.canvas.height / 2) * 0.8;
  293. // }.bind(this));
  294. // window.addEventListener('touchmove', function(e) {
  295. // e.preventDefault();
  296. // this.toX = (e.touches[0].clientX - this.canvas.width / 2) * -0.8;
  297. // this.toY = (e.touches[0].clientY - this.canvas.height / 2) * 0.8;
  298. // }.bind(this));
  299. // window.addEventListener('mousedown', function(e) {
  300. // for (var i = 0; i < 100; i++) {
  301. // this.add();
  302. // }
  303. // }.bind(this));
  304. // window.addEventListener('touchstart', function(e) {
  305. // e.preventDefault();
  306. // for (var i = 0; i < 100; i++) {
  307. // this.add();
  308. // }
  309. // }.bind(this));
  310. };
  311. var app = new Build();
  312. app.run();
  313. })();
  314. window.addEventListener('resize', function() {
  315. canvas.width = w = window.innerWidth;
  316. canvas.height = h = window.innerHeight;
  317. }, false)
  318. });