{"version":3,"file":"matrix.mjs","sources":["../src/matrix.js"],"sourcesContent":["/**\n * Matrix effect on a Canvas https://jcubic.github.io/cmatrix/\n *\n * Copyright (c) 2021-2023 Jakub T. Jankiewicz <https://jcubic.pl/me>\n * Released under MIT license\n *\n * The code was started at this Codepen https://codepen.io/jcubic/pen/rNeNwgB\n * And was based on code by Michael Goodman https://codepen.io/goodmanmr1/pen/jpPeRR\n *\n */\nvar katagana = gen_unicode(0x30A1, 0x30F6);\nvar hiragana = gen_unicode(0x3041, 0x3096);\n\n// ---------------------------------------------------------------\nclass Matrix {\n  constructor(canvas, {\n    chars = null,\n    font_size = 14,\n    width,\n    height,\n    font = 'monospace',\n    color,\n    background\n  } = {}) {\n    this._canvas = canvas;\n    if (this._canvas._matrix) {\n      this._canvas._matrix.stop();\n      this._canvas._matrix.clear();\n    }\n    this._canvas._matrix = this;\n    this._ctx = canvas.getContext('2d');\n    this._font_size = font_size;\n    this._drops = [];\n    this._color = color;\n    this._background = background;\n    this._font = font;\n    this._chars = chars ? chars : katagana.concat(hiragana);\n    this.resize(width, height);\n  }\n  random_char() {\n    return rnd(this._chars);\n  }\n  render_char(char, x, y) {\n    this._ctx.fillText(char, x, y);\n  }\n  start() {\n    if (this._run) {\n      return;\n    }\n    let frames = 0;\n    this._run = true;\n    const self = this;\n    (function loop() {\n      if (self._run) {\n        if (frames++ % 2 === 0) {\n          self.render(); // slower render\n        }\n        requestAnimationFrame(loop);\n      }\n    })();\n  }\n  stop() {\n    this._run = false;\n  }\n  reset() {\n    for (let x = 0; x < this._columns; x++) {\n      this._drops[x] = 255;\n    }\n  }\n  resize(width, height) {\n    this._width = width;\n    this._height = height;\n    this.clear();\n    this._canvas.width = width;\n    setTimeout(() => {\n      this._canvas.height = height;\n      this.reset();\n    }, 0);\n    this._columns = Math.round(width / this._font_size);\n  }\n  clear() {\n    this._ctx.fillStyle = this._background;\n    this._ctx.fillRect(0, 0, this._width, this._height);\n    this._ctx.fillStyle = this._color;\n    this._ctx.font = this._font_size + \"px \" + this._font;\n  }\n  fullscreen() {\n    if (!document.fullscreenElement) {\n      document.documentElement.requestFullscreen();\n    } else if (document.exitFullscreen) {\n      document.exitFullscreen();\n    }\n  }\n  render() {\n    this.clear();\n    for (let col = 0; col < this._drops.length; col++) {\n      const char = this.random_char();\n      const x = col * this._font_size;\n      const y = this._drops[col] * this._font_size;\n      this.render_char(char, x, y);\n      if (y > this._height && Math.random() > .975) {\n        this._drops[col] = 0;\n      }\n      this._drops[col]++;\n    }\n  }\n}\n\n// ---------------------------------------------------------------\n// :: Init code\n// ---------------------------------------------------------------\nfunction matrix(canvas, { chars = null,\n                          font_size = 14,\n                          exit = true,\n                          font = 'monospace',\n                          width = null,\n                          height = null,\n                          resize = true,\n                          color = '#0F0',\n                          mount = () => {},\n                          unmount = () => {},\n                          background = 'rgba(0, 0,0,0.05)'} = {}) {\n\n  const matrix = new Matrix(canvas, {\n    font_size: font_size,\n    chars,\n    font,\n    color,\n    background,\n    width: width ?? default_width(),\n    height: height ?? default_height()\n  });\n\n  let resize_handler;\n\n  if (resize) {\n    resize_handler = () => matrix.resize(default_width(), default_height());\n\n    window.addEventListener('resize', resize_handler);\n\n    if (screen?.orientation) {\n      screen.orientation.addEventListener('change', resize_handler);\n    }\n  }\n\n  canvas.classList.add('running');\n\n  matrix.start();\n  mount(matrix);\n\n  if (exit) {\n    return new Promise(function(resolve) {\n      window.addEventListener('keydown', function(e) {\n        var key = e.key.toLowerCase();\n        if (key === 'q' || key === 'escape') {\n          matrix.stop();\n          canvas.classList.remove('running');\n          if (resize_handler) {\n            window.removeEventListener('resize', resize_handler);\n            if (screen?.orientation) {\n              screen.orientation.removeEventListener('change', resize_handler);\n            }\n          }\n          setTimeout(() => {\n            unmount(matrix);\n            resolve();\n          }, 0);\n        }\n      });\n    });\n  }\n};\n\n\nexport default matrix;\n\n// ---------------------------------------------------------------\n// :: Utils\n// ---------------------------------------------------------------\nfunction gen_unicode(start, end) {\n  var chars = [];\n  for (var i = start; i <= end; ++i) {\n    chars.push(String.fromCharCode(i));\n  }\n  return chars;\n}\n\nmatrix.range = gen_unicode;\n\nmatrix.custom_chars = make_custom_chars();\n\n// ---------------------------------------------------------------\nfunction rnd(array) {\n  return array[Math.floor(Math.random() * array.length)];\n}\n\n// ---------------------------------------------------------------\nfunction default_width() {\n  return document.documentElement.clientWidth;\n}\n\n// ---------------------------------------------------------------\nfunction default_height() {\n  return window.innerHeight;\n}\n\n// ---------------------------------------------------------------\nfunction make_chars(...nums) {\n  return nums.map(num => String.fromCharCode(num));\n}\n\n// ---------------------------------------------------------------\nfunction make_custom_chars() {\n  const nums = [0x25AA, 0x254C, 0x00A9, 0x00A6, 0x007C, 0x007A, 0x003E, 0x003C, 0x003A, 0x0022, 0x002A, 0x002B,0x30A2,0x30A6,0x30A8,0x30AA,0x30AB,0x30AD,0x30B1,0x30B3,0x30B5,0x30B7,0x30B9,0x30BB,0x30BD,0x30BF,0x30C4,0x30C6,0x30CA,0x30CB,0x30CC,0x30CD,0x30CF,0x30D2,0x30DB,0x30DE,0x30DF,0x30E0,0x30E1,0x30E2,0x30E4,0x30E8,0x30E9,0x30EA,0x30EF,0x30FC, 0xA78A, 0xE937];\n\n  // '6' don't have its glyph\n  const digits = matrix.range(0x0030, 0x0035).concat(matrix.range(0x0037, 0x0039));\n\n  return digits.concat(make_chars(...nums));\n}\n"],"names":["katagana","gen_unicode","hiragana","Matrix","constructor","canvas","chars","font_size","width","height","font","color","background","this","_canvas","_matrix","stop","clear","_ctx","getContext","_font_size","_drops","_color","_background","_font","_chars","concat","resize","random_char","array","Math","floor","random","length","render_char","char","x","y","fillText","start","_run","frames","self","loop","render","requestAnimationFrame","reset","_columns","_width","_height","setTimeout","round","fillStyle","fillRect","fullscreen","document","fullscreenElement","exitFullscreen","documentElement","requestFullscreen","col","matrix","exit","mount","unmount","default_width","default_height","resize_handler","window","addEventListener","screen","orientation","classList","add","Promise","resolve","e","key","toLowerCase","remove","removeEventListener","end","i","push","String","fromCharCode","clientWidth","innerHeight","range","custom_chars","nums","map","num","make_chars"],"mappings":"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"}