index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { defineComponent } from 'vue';
  2. import { AwesomeQR } from 'vue-qr/src/lib/awesome-qr';
  3. import { px2vw } from '@/utils/index'
  4. function toBoolean(val: any): boolean {
  5. if (val === '') return val;
  6. return val === 'true' || val == '1';
  7. }
  8. function readAsArrayBuffer(url: any) {
  9. return new Promise(resolve => {
  10. const xhr = new XMLHttpRequest();
  11. xhr.responseType = 'blob'; //设定返回数据类型为Blob
  12. xhr.onload = function () {
  13. const reader = new FileReader();
  14. reader.onloadend = function () {
  15. resolve(reader.result);
  16. };
  17. reader.readAsArrayBuffer(xhr.response); //xhr.response就是一个Blob,用FileReader读取
  18. };
  19. xhr.open('GET', url);
  20. xhr.send();
  21. });
  22. }
  23. export default defineComponent({
  24. name: 'TheQrCode',
  25. props: {
  26. text: {
  27. type: String,
  28. required: true
  29. },
  30. qid: {
  31. type: String
  32. },
  33. correctLevel: {
  34. type: Number,
  35. default: 0
  36. },
  37. size: {
  38. type: Number,
  39. default: 220
  40. },
  41. margin: {
  42. type: Number,
  43. default: 20
  44. },
  45. colorDark: {
  46. type: String,
  47. default: '#000000'
  48. },
  49. colorLight: {
  50. type: String,
  51. default: '#FFFFFF'
  52. },
  53. bgSrc: {
  54. type: String,
  55. default: undefined
  56. },
  57. background: {
  58. type: String,
  59. default: 'rgba(0,0,0,0)'
  60. },
  61. backgroundDimming: {
  62. type: String,
  63. default: 'rgba(0,0,0,0)'
  64. },
  65. logoSrc: {
  66. type: String,
  67. default: undefined
  68. },
  69. logoBackgroundColor: {
  70. type: String,
  71. default: 'rgba(255,255,255,1)'
  72. },
  73. gifBgSrc: {
  74. type: String,
  75. default: undefined
  76. },
  77. logoScale: {
  78. type: Number,
  79. default: 0.2
  80. },
  81. logoMargin: {
  82. type: Number,
  83. default: 0
  84. },
  85. logoCornerRadius: {
  86. type: Number,
  87. default: 8
  88. },
  89. whiteMargin: {
  90. type: [Boolean, String],
  91. default: true
  92. },
  93. dotScale: {
  94. type: Number,
  95. default: 1
  96. },
  97. autoColor: {
  98. type: [Boolean, String],
  99. default: true
  100. },
  101. binarize: {
  102. type: [Boolean, String],
  103. default: false
  104. },
  105. binarizeThreshold: {
  106. type: Number,
  107. default: 128
  108. },
  109. callback: {
  110. type: Function,
  111. default: function () {
  112. return undefined;
  113. }
  114. },
  115. bindElement: {
  116. type: Boolean,
  117. default: true
  118. },
  119. backgroundColor: {
  120. type: String,
  121. default: '#FFFFFF'
  122. },
  123. components: {
  124. default: function () {
  125. return {
  126. data: {
  127. scale: 1
  128. },
  129. timing: {
  130. scale: 1,
  131. protectors: false
  132. },
  133. alignment: {
  134. scale: 1,
  135. protectors: false
  136. },
  137. cornerAlignment: {
  138. scale: 1,
  139. protectors: true
  140. }
  141. };
  142. }
  143. }
  144. },
  145. data() {
  146. return {
  147. imgUrl: '' as any
  148. };
  149. },
  150. watch: {
  151. $props: {
  152. deep: true,
  153. handler() {
  154. this.main();
  155. }
  156. }
  157. },
  158. mounted() {
  159. this.main();
  160. },
  161. methods: {
  162. async main() {
  163. // const that = this;
  164. if (this.gifBgSrc) {
  165. const gifImg = await readAsArrayBuffer(this.gifBgSrc);
  166. const logoImg = this.logoSrc;
  167. this.render(undefined, logoImg, gifImg);
  168. return;
  169. }
  170. const bgImg = this.bgSrc;
  171. const logoImg = this.logoSrc;
  172. this.render(bgImg, logoImg);
  173. },
  174. async render(img: any, logoImg: any, gifBgSrc?: any) {
  175. console.log(img, logoImg, gifBgSrc);
  176. new AwesomeQR({
  177. gifBackground: gifBgSrc,
  178. text: this.text,
  179. size: this.size,
  180. margin: this.margin,
  181. colorDark: this.colorDark,
  182. colorLight: this.colorLight,
  183. backgroundColor: this.backgroundColor,
  184. backgroundImage: img,
  185. backgroundDimming: this.backgroundDimming,
  186. logoImage: logoImg + '?' + new Date().getTime(),
  187. logoScale: this.logoScale,
  188. logoBackgroundColor: this.logoBackgroundColor,
  189. correctLevel: this.correctLevel,
  190. logoMargin: this.logoMargin,
  191. logoCornerRadius: this.logoCornerRadius,
  192. whiteMargin: toBoolean(this.whiteMargin),
  193. dotScale: this.dotScale,
  194. autoColor: toBoolean(this.autoColor),
  195. components: this.components
  196. })
  197. .draw()
  198. .then((dataUri: any) => {
  199. console.log('🚀 ~ dataUri:', dataUri);
  200. this.imgUrl = dataUri;
  201. this.callback && this.callback(dataUri, this.qid);
  202. });
  203. }
  204. },
  205. render() {
  206. return (
  207. < >
  208. {this.bindElement && this.imgUrl && (
  209. <img style={{ width: px2vw(this.size), height: px2vw(this.size), display: 'inline-block', zIndex: 1000 }} src={this.imgUrl} />
  210. )}
  211. </>
  212. );
  213. }
  214. });