Sansnn-uQRCode.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <view>
  3. <canvas :id="cid" :canvas-id="cid" :style="{width: `${size}px`, height: `${size}px`}" />
  4. </view>
  5. </template>
  6. <script>
  7. import uQRCode from './uqrcode.js'
  8. export default {
  9. props: {
  10. cid: {
  11. type: String,
  12. default(){
  13. return Date.now()+Math.random()+'';
  14. }
  15. },
  16. text: {
  17. type: String,
  18. required: true
  19. },
  20. size: {
  21. type: Number,
  22. default: uni.upx2px(200)
  23. },
  24. margin: {
  25. type: Number,
  26. default: 0
  27. },
  28. backgroundColor: {
  29. type: String,
  30. default: '#ffffff'
  31. },
  32. foregroundColor: {
  33. type: String,
  34. default: '#000000'
  35. },
  36. backgroundImage: {
  37. type: String
  38. },
  39. logo: {
  40. type: String
  41. },
  42. makeOnLoad: {
  43. type: Boolean,
  44. default: false
  45. }
  46. },
  47. data() {
  48. return {
  49. }
  50. },
  51. mounted() {
  52. if (this.makeOnLoad) {
  53. this.make()
  54. }
  55. },
  56. methods: {
  57. async make() {
  58. var options = {
  59. canvasId: this.cid,
  60. componentInstance: this,
  61. text: this.text,
  62. size: this.size,
  63. margin: this.margin,
  64. backgroundColor: this.backgroundImage ? 'rgba(255,255,255,0)' : this.backgroundColor,
  65. foregroundColor: this.foregroundColor
  66. }
  67. var filePath = await this.makeSync(options)
  68. if (this.backgroundImage) {
  69. filePath = await this.drawBackgroundImageSync(filePath)
  70. }
  71. if (this.logo) {
  72. filePath = await this.drawLogoSync(filePath)
  73. }
  74. this.makeComplete(filePath)
  75. },
  76. makeComplete(filePath) {
  77. this.$emit('makeComplete', filePath)
  78. },
  79. drawBackgroundImage(options) {
  80. var ctx = uni.createCanvasContext(this.cid, this)
  81. ctx.drawImage(this.backgroundImage, 0, 0, this.size, this.size)
  82. ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
  83. ctx.draw(false, () => {
  84. uni.canvasToTempFilePath({
  85. canvasId: this.cid,
  86. success: res => {
  87. options.success && options.success(res.tempFilePath)
  88. },
  89. fail: error => {
  90. options.fail && options.fail(error)
  91. }
  92. }, this)
  93. })
  94. },
  95. async drawBackgroundImageSync(filePath) {
  96. return new Promise((resolve, reject) => {
  97. this.drawBackgroundImage({
  98. filePath: filePath,
  99. success: res => {
  100. resolve(res)
  101. },
  102. fail: error => {
  103. reject(error)
  104. }
  105. })
  106. })
  107. },
  108. fillRoundRect(ctx, r, x, y, w, h) {
  109. ctx.save()
  110. ctx.translate(x, y)
  111. ctx.beginPath()
  112. ctx.arc(w - r, h - r, r, 0, Math.PI / 2)
  113. ctx.lineTo(r, h)
  114. ctx.arc(r, h - r, r, Math.PI / 2, Math.PI)
  115. ctx.lineTo(0, r)
  116. ctx.arc(r, r, r, Math.PI, Math.PI * 3 / 2)
  117. ctx.lineTo(w - r, 0)
  118. ctx.arc(w - r, r, r, Math.PI * 3 / 2, Math.PI * 2)
  119. ctx.lineTo(w, h - r)
  120. ctx.closePath()
  121. ctx.setFillStyle('#ffffff')
  122. ctx.fill()
  123. ctx.restore()
  124. },
  125. drawLogo(options) {
  126. var ctx = uni.createCanvasContext(this.cid, this)
  127. ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
  128. var logoSize = this.size / 4
  129. var logoX = this.size / 2 - logoSize / 2
  130. var logoY = logoX
  131. var borderSize = logoSize + 10
  132. var borderX = this.size / 2 - borderSize / 2
  133. var borderY = borderX
  134. var borderRadius = 5
  135. this.fillRoundRect(ctx, borderRadius, borderX, borderY, borderSize, borderSize)
  136. ctx.drawImage(this.logo, logoX, logoY, logoSize, logoSize)
  137. ctx.draw(false, () => {
  138. uni.canvasToTempFilePath({
  139. canvasId: this.cid,
  140. success: res => {
  141. options.success && options.success(res.tempFilePath)
  142. },
  143. fail: error => {
  144. options.fail && options.fail(error)
  145. }
  146. }, this)
  147. })
  148. },
  149. async drawLogoSync(filePath) {
  150. return new Promise((resolve, reject) => {
  151. this.drawLogo({
  152. filePath: filePath,
  153. success: res => {
  154. resolve(res)
  155. },
  156. fail: error => {
  157. reject(error)
  158. }
  159. })
  160. })
  161. },
  162. async makeSync(options) {
  163. return new Promise((resolve, reject) => {
  164. uQRCode.make({
  165. canvasId: options.canvasId,
  166. componentInstance: options.componentInstance,
  167. text: options.text,
  168. size: options.size,
  169. margin: options.margin,
  170. backgroundColor: options.backgroundColor,
  171. foregroundColor: options.foregroundColor,
  172. success: res => {
  173. resolve(res)
  174. },
  175. fail: error => {
  176. reject(error)
  177. }
  178. })
  179. })
  180. }
  181. }
  182. }
  183. </script>