Advertisement
floxster

MatrixCodeHTML

May 30th, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.58 KB | None | 0 0
  1. /*
  2.  
  3. Matrix code rain
  4.  
  5. Demo write up here: http://neilcarpenter.com/labs/matrix-rain
  6.  
  7. Uses matrix font: http://www.dafont.com/matrix-code-nfi.font
  8. and stats.js: https://github.com/mrdoob/stats.js/
  9.  
  10. If FPS is super low, try making browser window narrower - crap, I know, will work on it!
  11.  
  12. */
  13.  
  14.  
  15. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  16. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  17.  
  18. // requestAnimationFrame polyfill by Erik Möller
  19. // fixes from Paul Irish and Tino Zijdel
  20.  
  21. (function() {
  22. var lastTime = 0;
  23. var vendors = ['ms', 'moz', 'webkit', 'o'];
  24. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  25. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  26. window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  27. || window[vendors[x]+'CancelRequestAnimationFrame'];
  28. }
  29.  
  30. if (!window.requestAnimationFrame)
  31. window.requestAnimationFrame = function(callback, element) {
  32. var currTime = new Date().getTime();
  33. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  34. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  35. timeToCall);
  36. lastTime = currTime + timeToCall;
  37. return id;
  38. };
  39.  
  40. if (!window.cancelAnimationFrame)
  41. window.cancelAnimationFrame = function(id) {
  42. clearTimeout(id);
  43. };
  44. }());
  45.  
  46. // stats
  47. var stats = new Stats();
  48. stats.setMode(0);
  49. stats.domElement.style.position = 'absolute';
  50. stats.domElement.style.left = '0px';
  51. stats.domElement.style.top = '0px';
  52. document.body.appendChild( stats.domElement );
  53.  
  54.  
  55. var M = {
  56.  
  57. settings: {
  58. COL_WIDTH: 20,
  59. COL_HEIGHT: 25,
  60. VELOCITY_PARAMS: {
  61. min: 4,
  62. max: 8
  63. },
  64. CODE_LENGTH_PARAMS: {
  65. min: 20,
  66. max: 40
  67. }
  68. },
  69.  
  70. animation: null,
  71.  
  72. c: null,
  73. ctx: null,
  74.  
  75. lineC: null,
  76. ctx2: null,
  77.  
  78. WIDTH: window.innerWidth,
  79. HEIGHT: window.innerHeight,
  80.  
  81. COLUMNS: null,
  82. canvii: [],
  83.  
  84. // font from here http://www.dafont.com/matrix-code-nfi.font
  85. font: '30px matrix-code',
  86. letters: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '$', '+', '-', '*', '/', '=', '%', '"', '\'', '#', '&', '_', '(', ')', ',', '.', ';', ':', '?', '!', '\\', '|', '{', '}', '<', '>', '[', ']', '^', '~'],
  87.  
  88. codes: [],
  89.  
  90. createCodeLoop: null,
  91. codesCounter: 0,
  92.  
  93. init: function () {
  94. M.c = document.getElementById( 'canvas' );
  95. M.ctx = M.c.getContext( '2d' );
  96. M.c.width = M.WIDTH;
  97. M.c.height = M.HEIGHT;
  98.  
  99. M.ctx.shadowBlur = 0;
  100. M.ctx.fillStyle = '#000';
  101. M.ctx.fillRect(0, 0, M.WIDTH, M.HEIGHT);
  102. M.ctx.font = M.font;
  103.  
  104. M.COLUMNS = Math.ceil(M.WIDTH / M.settings.COL_WIDTH);
  105.  
  106. for (var i = 0; i < M.COLUMNS; i++) {
  107. M.codes[i] = [];
  108. M.codes[i][0] = {
  109. 'open': true,
  110. 'position': {'x': 0, 'y': 0},
  111. 'strength': 0
  112. };
  113. }
  114.  
  115. M.loop();
  116.  
  117. M.createLines();
  118.  
  119. M.createCode();
  120.  
  121. // not doing this, kills CPU
  122. // M.swapCharacters();
  123.  
  124. window.onresize = function () {
  125. window.cancelAnimationFrame(M.animation);
  126. M.animation = null;
  127. M.ctx.clearRect(0, 0, M.WIDTH, M.HEIGHT);
  128. M.codesCounter = 0;
  129.  
  130. M.ctx2.clearRect(0, 0, M.WIDTH, M.HEIGHT);
  131.  
  132. M.WIDTH = window.innerWidth;
  133. M.HEIGHT = window.innerHeight;
  134. M.init();
  135. };
  136. },
  137.  
  138. loop: function () {
  139. M.animation = requestAnimationFrame( function(){ M.loop(); } );
  140. M.draw();
  141.  
  142. stats.update();
  143. },
  144.  
  145. // this used to be used straight after createCode, without using createCanvii - it allowed
  146. // the characters within the code streams to be easily changable, but caused huge perf issues
  147. // OLDdraw: function() {
  148.  
  149. // var codesLen = M.codes.length;
  150. // var codeLen;
  151. // var x;
  152. // var y;
  153. // var text;
  154. // var velocity;
  155. // var columnIndex;
  156. // var strength;
  157. // var fadeStrength;
  158.  
  159. // M.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
  160. // M.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
  161. // M.ctx.fillRect(0, 0, M.WIDTH, M.HEIGHT);
  162.  
  163. // M.ctx.globalCompositeOperation = 'source-over';
  164.  
  165. // for (var i = 0; i < codesLen; i++) {
  166.  
  167. // velocity = M.codes[i][0].velocity;
  168. // M.codes[i][0].position.y += velocity;
  169.  
  170. // y = M.codes[i][0].position.y;
  171. // x = M.codes[i][0].position.x;
  172. // codeLength = M.codes[i].length;
  173. // strength = M.codes[i][0].strength;
  174.  
  175. // for (var j = 1; j < codeLength; j++) {
  176. // text = M.codes[i][j];
  177.  
  178. // if (j < 5) {
  179. // M.ctx.shadowColor = 'hsl(104, 79%, 74%)';
  180. // M.ctx.shadowOffsetX = 0;
  181. // M.ctx.shadowOffsetY = 0;
  182. // M.ctx.shadowBlur = 10;
  183. // M.ctx.fillStyle = 'hsla(104, 79%, ' + (100 - (j * 5)) + '%, ' + strength + ')';
  184. // } else if (j > (codeLength - 4)) {
  185. // fadeStrength = j / codeLength;
  186. // fadeStrength = 1 - fadeStrength;
  187.  
  188. // M.ctx.shadowOffsetX = 0;
  189. // M.ctx.shadowOffsetY = 0;
  190. // M.ctx.shadowBlur = 0;
  191. // M.ctx.fillStyle = 'hsla(104, 79%, 74%, ' + (fadeStrength + 0.3) + ')';
  192. // } else {
  193. // M.ctx.shadowOffsetX = 0;
  194. // M.ctx.shadowOffsetY = 0;
  195. // M.ctx.shadowBlur = 0;
  196. // M.ctx.fillStyle = 'hsla(104, 79%, 74%, ' + strength + ')';
  197. // }
  198.  
  199. // // M.ctx.fillStyle = 'hsl(104, 79%, ' + (M.codes[i][0].strength * 74) + '%)';
  200. // M.ctx.fillText(text, x, (y - (j * M.settings.COL_HEIGHT)));
  201.  
  202. // if ((j === codeLength - 1) && (y - ((j + 1) * M.settings.COL_HEIGHT) > M.HEIGHT)) {
  203. // columnIndex = M.codes[i][0].position.x / M.settings.COL_WIDTH;
  204. // M.codes[columnIndex][0].open = true;
  205. // M.codes[columnIndex][0].position.y = 0;
  206. // }
  207. // }
  208. // }
  209.  
  210. // },
  211.  
  212. draw: function() {
  213.  
  214. var velocity, height, x, y, c, ctx;
  215.  
  216. // slow fade BG colour
  217. M.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
  218. M.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
  219. M.ctx.fillRect(0, 0, M.WIDTH, M.HEIGHT);
  220.  
  221. M.ctx.globalCompositeOperation = 'source-over';
  222.  
  223. for (var i = 0; i < M.COLUMNS; i++) {
  224.  
  225. // check member of array isn't undefined at this point
  226. if (M.codes[i][0].canvas) {
  227. velocity = M.codes[i][0].velocity;
  228. height = M.codes[i][0].canvas.height;
  229. x = M.codes[i][0].position.x;
  230. y = M.codes[i][0].position.y - height;
  231. c = M.codes[i][0].canvas;
  232. ctx = c.getContext('2d');
  233.  
  234. M.ctx.drawImage(c, x, y, M.settings.COL_WIDTH, height);
  235.  
  236. if ((M.codes[i][0].position.y - height) < M.HEIGHT){
  237. M.codes[i][0].position.y += velocity;
  238. } else {
  239. M.codes[i][0].position.y = 0;
  240. }
  241.  
  242. }
  243. }
  244.  
  245. },
  246.  
  247. createCode: function() {
  248.  
  249. if (M.codesCounter > M.COLUMNS) {
  250. clearTimeout(M.createCodeLoop);
  251. return;
  252. }
  253.  
  254. var randomInterval = M.randomFromInterval(0, 100);
  255. var column = M.assignColumn();
  256.  
  257. if (column) {
  258.  
  259. var codeLength = M.randomFromInterval(M.settings.CODE_LENGTH_PARAMS.min, M.settings.CODE_LENGTH_PARAMS.max);
  260. var codeVelocity = (Math.random() * (M.settings.VELOCITY_PARAMS.max - M.settings.VELOCITY_PARAMS.min)) + M.settings.VELOCITY_PARAMS.min;
  261. var lettersLength = M.letters.length;
  262.  
  263. M.codes[column][0].position = {'x': (column * M.settings.COL_WIDTH), 'y': 0};
  264. M.codes[column][0].velocity = codeVelocity;
  265. M.codes[column][0].strength = M.codes[column][0].velocity / M.settings.VELOCITY_PARAMS.max;
  266.  
  267. for (var i = 1; i <= codeLength; i++) {
  268. var newLetter = M.randomFromInterval(0, (lettersLength - 1));
  269. M.codes[column][i] = M.letters[newLetter];
  270. }
  271.  
  272. M.createCanvii(column);
  273.  
  274. M.codesCounter++;
  275.  
  276. }
  277.  
  278. M.createCodeLoop = setTimeout(M.createCode, randomInterval);
  279.  
  280. },
  281.  
  282. createCanvii: function(i) {
  283.  
  284. var codeLen = M.codes[i].length - 1;
  285. var canvHeight = codeLen * M.settings.COL_HEIGHT;
  286. var velocity = M.codes[i][0].velocity;
  287. var strength = M.codes[i][0].strength;
  288. var text, fadeStrength;
  289.  
  290. var newCanv = document.createElement('canvas');
  291. var newCtx = newCanv.getContext('2d');
  292.  
  293. newCanv.width = M.settings.COL_WIDTH;
  294. newCanv.height = canvHeight;
  295.  
  296. for (var j = 1; j < codeLen; j++) {
  297. text = M.codes[i][j];
  298. newCtx.globalCompositeOperation = 'source-over';
  299. newCtx.font = '30px matrix-code';
  300.  
  301. if (j < 5) {
  302. newCtx.shadowColor = 'hsl(104, 79%, 74%)';
  303. newCtx.shadowOffsetX = 0;
  304. newCtx.shadowOffsetY = 0;
  305. newCtx.shadowBlur = 10;
  306. newCtx.fillStyle = 'hsla(104, 79%, ' + (100 - (j * 5)) + '%, ' + strength + ')';
  307. } else if (j > (codeLen - 4)) {
  308. fadeStrength = j / codeLen;
  309. fadeStrength = 1 - fadeStrength;
  310.  
  311. newCtx.shadowOffsetX = 0;
  312. newCtx.shadowOffsetY = 0;
  313. newCtx.shadowBlur = 0;
  314. newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + (fadeStrength + 0.3) + ')';
  315. } else {
  316. newCtx.shadowOffsetX = 0;
  317. newCtx.shadowOffsetY = 0;
  318. newCtx.shadowBlur = 0;
  319. newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + strength + ')';
  320. }
  321.  
  322. newCtx.fillText(text, 0, (canvHeight - (j * M.settings.COL_HEIGHT)));
  323. }
  324.  
  325. M.codes[i][0].canvas = newCanv;
  326.  
  327. },
  328.  
  329. swapCharacters: function() {
  330. var randomCodeIndex;
  331. var randomCode;
  332. var randomCodeLen;
  333. var randomCharIndex;
  334. var newRandomCharIndex;
  335. var newRandomChar;
  336.  
  337. for (var i = 0; i < 20; i++) {
  338. randomCodeIndex = M.randomFromInterval(0, (M.codes.length - 1));
  339. randomCode = M.codes[randomCodeIndex];
  340. randomCodeLen = randomCode.length;
  341. randomCharIndex = M.randomFromInterval(2, (randomCodeLen - 1));
  342. newRandomCharIndex = M.randomFromInterval(0, (M.letters.length - 1));
  343. newRandomChar = M.letters[newRandomCharIndex];
  344.  
  345. randomCode[randomCharIndex] = newRandomChar;
  346. }
  347.  
  348. M.swapCharacters();
  349. },
  350.  
  351. createLines: function() {
  352. M.linesC = document.createElement('canvas');
  353. M.linesC.width = M.WIDTH;
  354. M.linesC.height = M.HEIGHT;
  355. M.linesC.style.position = 'absolute';
  356. M.linesC.style.top = 0;
  357. M.linesC.style.left = 0;
  358. M.linesC.style.zIndex = 10;
  359. document.body.appendChild(M.linesC);
  360.  
  361. var linesYBlack = 0;
  362. var linesYWhite = 0;
  363. M.ctx2 = M.linesC.getContext('2d');
  364.  
  365. M.ctx2.beginPath();
  366.  
  367. M.ctx2.lineWidth = 1;
  368. M.ctx2.strokeStyle = 'rgba(0, 0, 0, 0.7)';
  369.  
  370. while (linesYBlack < M.HEIGHT) {
  371.  
  372. M.ctx2.moveTo(0, linesYBlack);
  373. M.ctx2.lineTo(M.WIDTH, linesYBlack);
  374.  
  375. linesYBlack += 5;
  376. }
  377.  
  378. M.ctx2.lineWidth = 0.15;
  379. M.ctx2.strokeStyle = 'rgba(255, 255, 255, 0.7)';
  380.  
  381. while (linesYWhite < M.HEIGHT) {
  382.  
  383. M.ctx2.moveTo(0, linesYWhite+1);
  384. M.ctx2.lineTo(M.WIDTH, linesYWhite+1);
  385.  
  386. linesYWhite += 5;
  387. }
  388.  
  389. M.ctx2.stroke();
  390. },
  391.  
  392. assignColumn: function() {
  393. var randomColumn = M.randomFromInterval(0, (M.COLUMNS - 1));
  394.  
  395. if (M.codes[randomColumn][0].open) {
  396. M.codes[randomColumn][0].open = false;
  397. } else {
  398. return false;
  399. }
  400.  
  401. return randomColumn;
  402. },
  403.  
  404. randomFromInterval: function(from, to) {
  405. return Math.floor(Math.random() * (to - from+ 1 ) + from);
  406. },
  407.  
  408. snapshot: function() {
  409. window.open(M.c.toDataURL());
  410. }
  411.  
  412. };
  413.  
  414. function eventListenerz() {
  415. var controlToggles = document.getElementsByClassName('toggle-info');
  416. var controls = document.getElementById('info');
  417. var snapshotBtn = document.getElementById('snapshot');
  418.  
  419. function toggleControls(e) {
  420. e.preventDefault();
  421. controls.className = controls.className === 'closed' ? '' : 'closed';
  422. }
  423.  
  424. for (var j = 0; j < 2; j++) {
  425. controlToggles[j].addEventListener('click', toggleControls, false);
  426. }
  427.  
  428. snapshotBtn.addEventListener('click', M.snapshot, false);
  429.  
  430. }
  431.  
  432. window.onload = function() {
  433.  
  434. M.init();
  435.  
  436. eventListenerz();
  437.  
  438. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement