index.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /**
  2. * FeHelper QR Code Tools
  3. */
  4. new Vue({
  5. el: '#pageContainer',
  6. data: {
  7. textContent: '',
  8. qrSize: 200,
  9. qrColor: '#000000',
  10. useIcon: 'no',
  11. previewSrc: '',
  12. resultContent: '',
  13. qrEncodeMode: true,
  14. showResult: false
  15. },
  16. mounted: function () {
  17. let mode = new URL(location.href).searchParams.get('mode');
  18. this.qrEncodeMode = mode !== 'decode';
  19. // 在tab创建或者更新时候,监听事件,看看是否有参数传递过来
  20. if (location.protocol === 'chrome-extension:') {
  21. chrome.runtime.onMessage.addListener((request, sender, callback) => {
  22. if (request.type === 'TAB_CREATED_OR_UPDATED' && request.event === location.pathname.split('/')[1]) {
  23. let text = request.content || (request.fromTab ? request.fromTab.url : '');
  24. if (text) {
  25. if (!this.qrEncodeMode) {
  26. // 解码模式
  27. this._qrDecode(text);
  28. } else {
  29. this.textContent = text;
  30. this.convert();
  31. }
  32. }
  33. callback && callback();
  34. return true;
  35. }
  36. });
  37. }
  38. this.$refs.codeSource && this.$refs.codeSource.focus();
  39. // 拖拽注册
  40. document.addEventListener('drop', (evt) => {
  41. evt.preventDefault();
  42. evt.stopPropagation();
  43. let files = evt.dataTransfer.files;
  44. if (files.length) {
  45. if (this.qrEncodeMode) {
  46. this._drawIcon(files[0]);
  47. } else {
  48. this._decodeLocal(files[0]);
  49. }
  50. }
  51. }, false);
  52. document.addEventListener('dragover', (e) => {
  53. e.preventDefault();
  54. e.stopPropagation();
  55. }, false);
  56. //监听paste事件
  57. document.addEventListener('paste', (event) => {
  58. if (this.qrEncodeMode) return;
  59. this.paste(event);
  60. }, false);
  61. // color picker绑定
  62. $("#opt_fc").colorpicker({
  63. fillcolor: true,
  64. success: (obj, color) => {
  65. this.qrColor = color;
  66. this.convert();
  67. }
  68. })
  69. },
  70. methods: {
  71. convert: function () {
  72. this.showResult = true;
  73. this.$nextTick(() => {
  74. if (this.textContent) {
  75. $('#preview').html('').qrcode(this._createOptions());
  76. } else {
  77. $('#preview').html('再在输入框里输入一些内容,就能生成二维码了哦~')
  78. }
  79. });
  80. },
  81. fileChanged: function (event) {
  82. if (event.target.files.length) {
  83. if (this.qrEncodeMode) {
  84. this._drawIcon(event.target.files[0]);
  85. } else {
  86. this._decodeLocal(event.target.files[0]);
  87. }
  88. event.target.value = '';
  89. }
  90. },
  91. _drawIcon: function (file) {
  92. if (/image\//.test(file.type)) {
  93. this.useIcon = 'custom';
  94. let reader = new FileReader();
  95. reader.onload = (evt) => {
  96. this.$refs.logoCustom.src = evt.target.result;
  97. this.convert();
  98. };
  99. reader.readAsDataURL(file);
  100. } else {
  101. alert('请选择图片文件!');
  102. }
  103. },
  104. _createOptions: function () {
  105. let defaultOptions = {
  106. render: 'canvas',
  107. minVersion: 1,
  108. maxVersion: 40,
  109. ecLevel: 'L',
  110. left: 0,
  111. top: 0,
  112. size: +this.qrSize || 200,
  113. fill: this.qrColor,
  114. background: '#fff',
  115. radius: 0,
  116. quiet: 0,
  117. text: this.textContent,
  118. mode: 0,
  119. mSize: 0.15,
  120. mPosX: 0.5,
  121. mPosY: 0.5,
  122. label: 'FH',
  123. fontname: 'sans',
  124. fontcolor: '#f00',
  125. image: false
  126. };
  127. // 判断是否需要设置icon
  128. switch (this.useIcon) {
  129. case 'default':
  130. defaultOptions.mode = 4;
  131. defaultOptions.image = this.$refs.logoDefault;
  132. break;
  133. case 'custom':
  134. defaultOptions.mode = 4;
  135. defaultOptions.image = this.$refs.logoCustom;
  136. break;
  137. }
  138. return defaultOptions;
  139. },
  140. trans: function () {
  141. this.qrEncodeMode = !this.qrEncodeMode;
  142. },
  143. select: function () {
  144. this.$refs.resultBox.select();
  145. },
  146. _decodeLocal: function (file) {
  147. let reader = new FileReader();
  148. reader.onload = (e) => {
  149. this._qrDecode(e.target.result);
  150. };
  151. reader.readAsDataURL(file);
  152. },
  153. paste: function (event) {
  154. let items = event.clipboardData.items || {};
  155. // 优先处理图片
  156. for (let index in items) {
  157. let item = items[index];
  158. if (/image\//.test(item.type)) {
  159. let file = item.getAsFile();
  160. return this._decodeLocal(file);
  161. }
  162. }
  163. // 然后处理url
  164. try {
  165. // 逐个遍历
  166. (async () => {
  167. for (let index in items) {
  168. let item = items[index];
  169. if (/text\/plain/.test(item.type)) {
  170. let url = await new Promise(resolve => {
  171. item.getAsString(url => resolve(url))
  172. });
  173. let flag = await new Promise(resolve => {
  174. this._qrDecode(url, flag => resolve(flag));
  175. });
  176. if (flag) break;
  177. }
  178. }
  179. })();
  180. } catch (ex) {
  181. // 只能处理一个了
  182. for (let index in items) {
  183. let item = items[index];
  184. if (/text\/plain/.test(item.type)) {
  185. return item.getAsString(url => {
  186. this._qrDecode(url);
  187. });
  188. }
  189. }
  190. }
  191. },
  192. /**
  193. * 二维码转码
  194. * @param imgSrc
  195. * @param callback
  196. */
  197. _qrDecode: function (imgSrc, callback) {
  198. let self = this;
  199. const codeReader = new ZXing.BrowserMultiFormatReader();
  200. let image = new Image();
  201. image.src = imgSrc;
  202. image.setAttribute('crossOrigin', 'Anonymous');
  203. image.onload = function () {
  204. codeReader.decodeFromImage(this).then((result) => {
  205. self._showDecodeResult(imgSrc, result.text);
  206. callback && callback(result.text);
  207. }).catch((err) => {
  208. self._showDecodeResult(imgSrc, err);
  209. callback && callback(err);
  210. });
  211. };
  212. image.onerror = function (e) {
  213. callback && callback(false);
  214. alert('抱歉,当前图片无法被解码,请保存图片再拖拽进来试试!')
  215. };
  216. },
  217. _showDecodeResult: function (src, txt) {
  218. this.previewSrc = src;
  219. this.$refs.panelBox.style.backgroundImage = 'none';
  220. this.resultContent = txt;
  221. }
  222. }
  223. });