吉光研途前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
4.2 KiB

  1. <template>
  2. <view class="page__view">
  3. <!-- 导航栏 -->
  4. <navbar leftClick @leftClick="$utils.navigateBack" />
  5. <view style="width: 750rpx; height: 1184rpx; overflow: hidden;">
  6. <canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas>
  7. </view>
  8. <view class="flex bottom">
  9. <view class="flex">
  10. <button class="btn" @click="saveImg">保存到手机</button>
  11. </view>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. data() {
  18. return {
  19. wxCodeImage: '',
  20. baseUrl: 'https://image.hhlm1688.com/',
  21. canvas: {},
  22. posterData: {},
  23. }
  24. },
  25. async onLoad() {
  26. uni.showLoading({
  27. title: '加载中...'
  28. });
  29. this.posterData = uni.getStorageSync('posterData')
  30. await this.fetchQrCode(this.posterData.path)
  31. uni.hideLoading();
  32. this.draw()
  33. },
  34. methods: {
  35. async fetchQrCode(path) {
  36. try {
  37. this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url
  38. } catch (err) {
  39. }
  40. },
  41. draw() {
  42. uni.showLoading({
  43. title: "拼命绘画中..."
  44. })
  45. wx.createSelectorQuery()
  46. .select('#myCanvas') // 绘制的canvas的id
  47. .fields({
  48. node: true,
  49. size: true
  50. })
  51. .exec(async (res) => {
  52. const canvas = res[0].node
  53. // 渲染上下文
  54. const ctx = canvas.getContext('2d')
  55. // Canvas 画布的实际绘制宽高
  56. const width = res[0].width
  57. const height = res[0].height
  58. // 初始化画布大小
  59. const dpr = wx.getWindowInfo().pixelRatio
  60. //根据dpr调整
  61. // dpr 2 4
  62. // 3 6
  63. console.log("--dpr", dpr)
  64. canvas.width = width * dpr
  65. canvas.height = height * dpr
  66. let Ratio = canvas.width / 750
  67. this.canvas = canvas
  68. ctx.scale(dpr, dpr)
  69. ctx.clearRect(0, 0, width, height)
  70. ctx.fillStyle = '#fff'
  71. ctx.fillRect(0, 0, canvas.width, canvas.height)
  72. // 海报图片
  73. const paperImage = canvas.createImage()
  74. paperImage.src = this.posterData.paperImage
  75. paperImage.onload = () => {
  76. const w = 750 * Ratio / dpr
  77. const h = 1184 * Ratio / dpr
  78. ctx.drawImage(paperImage, 0, 0, w, h)
  79. //二维码图片
  80. const coderImage = canvas.createImage()
  81. coderImage.src = this.wxCodeImage
  82. coderImage.onload = () => {
  83. const x = 539 * Ratio / dpr
  84. const y = 987 * Ratio / dpr
  85. const size = 162 * Ratio / dpr
  86. ctx.drawImage(coderImage, x, y, size, size)
  87. uni.hideLoading()
  88. }
  89. }
  90. })
  91. },
  92. saveImg() {
  93. this.$authorize('scope.writePhotosAlbum').then((res) => {
  94. this.imgApi()
  95. })
  96. },
  97. imgApi() {
  98. uni.showLoading({
  99. title: '保存中...'
  100. });
  101. wx.canvasToTempFilePath({
  102. x: 0,
  103. y: 0,
  104. width: this.canvas.width,
  105. height: this.canvas.height,
  106. canvas: this.canvas,
  107. success: (res) => {
  108. let tempFilePath = res.tempFilePath;
  109. this.saveImgToPhone(tempFilePath)
  110. },
  111. fail: (err) => {
  112. console.log('--canvasToTempFilePath--fail', err)
  113. uni.hideLoading();
  114. }
  115. }, this);
  116. },
  117. saveImgToPhone(image) {
  118. /* 获取图片的信息 */
  119. uni.getImageInfo({
  120. src: image,
  121. success: function(image) {
  122. /* 保存图片到手机相册 */
  123. uni.saveImageToPhotosAlbum({
  124. filePath: image.path,
  125. success: function() {
  126. uni.showModal({
  127. title: '保存成功',
  128. content: '图片已成功保存到相册',
  129. showCancel: false
  130. });
  131. },
  132. complete(res) {
  133. console.log(res);
  134. uni.hideLoading();
  135. }
  136. });
  137. }
  138. });
  139. }
  140. },
  141. }
  142. </script>
  143. <style scoped lang="scss">
  144. .page__view {
  145. background: $uni-bg-color-grey;
  146. }
  147. .bottom {
  148. position: fixed;
  149. left: 0;
  150. bottom: 0;
  151. width: 100vw;
  152. height: 154rpx;
  153. padding-bottom: env(safe-area-inset-bottom);
  154. background: #FFFFFF;
  155. .btn {
  156. padding: 20rpx 77rpx;
  157. font-size: 28rpx;
  158. color: #FFFFFF;
  159. background: #4883F9;
  160. border-radius: 14rpx;
  161. }
  162. }
  163. </style>