random.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. 'use strict';
  2. const opts = require('./option-manager').options;
  3. const randomInt = function (min, max) {
  4. return Math.round(min + (Math.random() * (max - min)));
  5. };
  6. const stripCharsFromString = function (string, chars) {
  7. return string.split('').filter(char => chars.indexOf(char) === -1);
  8. };
  9. exports.int = randomInt;
  10. exports.greyColor = function (min, max) {
  11. min = min || 1;
  12. max = max || 9;
  13. const int = randomInt(min, max).toString(16);
  14. return `#${int}${int}${int}`;
  15. };
  16. exports.captchaText = function (options) {
  17. if (typeof options === 'number') {
  18. options = {size: options};
  19. }
  20. options = options || {};
  21. const size = options.size || 4;
  22. const ignoreChars = options.ignoreChars || '';
  23. let i = -1;
  24. let out = '';
  25. let chars = options.charPreset || opts.charPreset;
  26. if (ignoreChars) {
  27. chars = stripCharsFromString(chars, ignoreChars);
  28. }
  29. const len = chars.length - 1;
  30. while (++i < size) {
  31. out += chars[randomInt(0, len)];
  32. }
  33. return out;
  34. };
  35. const mathExprPlus = function(leftNumber, rightNumber){
  36. const text = (leftNumber + rightNumber).toString();
  37. const equation = leftNumber + '+' + rightNumber;
  38. return {text, equation}
  39. }
  40. const mathExprMinus = function(leftNumber, rightNumber){
  41. const text = (leftNumber - rightNumber).toString();
  42. const equation = leftNumber + '-' + rightNumber;
  43. return {text, equation}
  44. }
  45. /**
  46. * Creates a simple math expression using either the + or - operator
  47. * @param {number} [min] - The min value of the math expression defaults to 1
  48. * @param {number} [max] - The max value of the math expression defaults to 9
  49. * @param {string} [operator] - The operator(s) to use
  50. * @returns {{equation: string, text: string}}
  51. */
  52. exports.mathExpr = function (min, max, operator) {
  53. min = min || 1;
  54. max = max || 9;
  55. operator = operator || '+';
  56. const left = randomInt(min, max);
  57. const right = randomInt(min, max);
  58. switch(operator){
  59. case '+':
  60. return mathExprPlus(left, right)
  61. case '-':
  62. return mathExprMinus(left, right)
  63. default:
  64. return (randomInt(1, 2) % 2) ? mathExprPlus(left, right) : mathExprMinus(left, right);
  65. }
  66. };
  67. // https://github.com/jquery/jquery-color/blob/master/jquery.color.js#L432
  68. // The idea here is generate color in hsl first and convert that to rgb color
  69. exports.color = function (bgColor) {
  70. // Random 24 colors
  71. // or based on step
  72. const hue = randomInt(0, 24) / 24;
  73. const saturation = randomInt(60, 80) / 100;
  74. const bgLightness = bgColor ? getLightness(bgColor) : 1.0;
  75. let minLightness;
  76. let maxLightness;
  77. if (bgLightness >= 0.5) {
  78. minLightness = Math.round(bgLightness * 100) - 45;
  79. maxLightness = Math.round(bgLightness * 100) - 25;
  80. } else {
  81. minLightness = Math.round(bgLightness * 100) + 25;
  82. maxLightness = Math.round(bgLightness * 100) + 45;
  83. }
  84. const lightness = randomInt(minLightness, maxLightness) / 100;
  85. const q = lightness < 0.5 ?
  86. lightness * (lightness + saturation) :
  87. lightness + saturation - (lightness * saturation);
  88. const p = (2 * lightness) - q;
  89. const r = Math.floor(hue2rgb(p, q, hue + (1 / 3)) * 255);
  90. const g = Math.floor(hue2rgb(p, q, hue) * 255);
  91. const b = Math.floor(hue2rgb(p, q, hue - (1 / 3)) * 255);
  92. /* eslint-disable no-mixed-operators */
  93. const c = ((b | g << 8 | r << 16) | 1 << 24).toString(16).slice(1);
  94. return '#' + c;
  95. };
  96. function getLightness(rgbColor) {
  97. if (rgbColor[0] !== '#') {
  98. return 1.0; // Invalid color ?
  99. }
  100. rgbColor = rgbColor.slice(1);
  101. if (rgbColor.length === 3) {
  102. rgbColor = rgbColor[0] + rgbColor[0] +
  103. rgbColor[1] + rgbColor[1] + rgbColor[2] + rgbColor[2];
  104. }
  105. const hexColor = parseInt(rgbColor, 16);
  106. const r = hexColor >> 16;
  107. const g = hexColor >> 8 & 255;
  108. const b = hexColor & 255;
  109. const max = Math.max(r, g, b);
  110. const min = Math.min(r, g, b);
  111. return (max + min) / (2 * 255);
  112. }
  113. function hue2rgb(p, q, h) {
  114. h = (h + 1) % 1;
  115. if (h * 6 < 1) {
  116. return p + (q - p) * h * 6;
  117. }
  118. if (h * 2 < 1) {
  119. return q;
  120. }
  121. if (h * 3 < 2) {
  122. return p + (q - p) * ((2 / 3) - h) * 6;
  123. }
  124. return p;
  125. }