推拿小程序前端代码仓库
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.

203 lines
4.4 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <template>
  2. <view class="page">
  3. <navbar title="邀请好友" leftClick @leftClick="$utils.navigateBack" color="#fff" />
  4. <view class="flex flex-column content">
  5. <view style="width: 698rpx; height: 788rpx; border-radius: 16rpx; overflow: hidden;">
  6. <canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas>
  7. </view>
  8. <view class="tools">
  9. <button plain class="flex btn" @click="saveImg">
  10. 保存到本地
  11. </button>
  12. </view>
  13. </view>
  14. </view>
  15. </template>
  16. <script>
  17. import { mapState } from 'vuex'
  18. export default {
  19. name: 'Promotion',
  20. computed: {
  21. ...mapState(['userInfo']),
  22. },
  23. data() {
  24. return {
  25. wxCodeImage: '',
  26. baseUrl: 'https://image.hhlm1688.com/',
  27. canvas: {},
  28. }
  29. },
  30. onReady() {
  31. this.fetchQrCode()
  32. },
  33. methods: {
  34. async fetchQrCode() {
  35. try {
  36. this.wxCodeImage = (await this.$fetch('getInviteCode'))?.url
  37. this.draw()
  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 / 698
  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. ctx.fillStyle = '#000000';
  73. const fontSize = 32 * Ratio / dpr
  74. ctx.font = `${fontSize}px PingFangSC-regular`;
  75. const titleX = 285 * Ratio / dpr
  76. const titleY = 53 * Ratio / dpr
  77. ctx.fillText('邀请好友', titleX, titleY);
  78. const codeX = 216 * Ratio / dpr
  79. const codeY = 645 * Ratio / dpr
  80. // todo: fetch code
  81. ctx.fillText(`邀请码:${'YFY1688'}`, codeX, codeY);
  82. //二维码图片
  83. const coderImage = canvas.createImage()
  84. coderImage.src = this.wxCodeImage
  85. coderImage.onload = () => {
  86. const x = 158 * Ratio / dpr
  87. const y = 188 * Ratio / dpr
  88. const size = 382 * Ratio / dpr
  89. ctx.drawImage(coderImage, x, y, size, size)
  90. uni.hideLoading()
  91. }
  92. })
  93. },
  94. saveImg(){
  95. this.$authorize('scope.writePhotosAlbum').then((res) => {
  96. this.imgApi()
  97. })
  98. },
  99. imgApi() {
  100. wx.canvasToTempFilePath({
  101. x: 0,
  102. y: 0,
  103. width: this.canvas.width,
  104. height: this.canvas.height,
  105. canvas: this.canvas,
  106. success: (res) => {
  107. let tempFilePath = res.tempFilePath;
  108. this.saveImgToPhone(tempFilePath)
  109. },
  110. fail: (err) => {
  111. console.log('--canvasToTempFilePath--fail', err)
  112. }
  113. }, this);
  114. },
  115. saveImgToPhone(image) {
  116. /* 获取图片的信息 */
  117. uni.getImageInfo({
  118. src: image,
  119. success: function(image) {
  120. /* 保存图片到手机相册 */
  121. uni.saveImageToPhotosAlbum({
  122. filePath: image.path,
  123. success: function() {
  124. uni.showModal({
  125. title: '保存成功',
  126. content: '图片已成功保存到相册',
  127. showCancel: false
  128. });
  129. },
  130. complete(res) {
  131. console.log(res);
  132. }
  133. });
  134. }
  135. });
  136. }
  137. }
  138. }
  139. </script>
  140. <style lang="scss" scoped>
  141. .page {
  142. background-color: $uni-bg-color;
  143. min-height: 100vh;
  144. /deep/ .nav-bar__view {
  145. background-image: linear-gradient(#84A73F, #D8FF8F);
  146. }
  147. }
  148. .content {
  149. align-items: flex-start;
  150. padding: 48rpx 26rpx;
  151. }
  152. .image{
  153. width: 100%;
  154. height: 778rpx;
  155. }
  156. .tools {
  157. margin-top: 163rpx;
  158. width: 100%;
  159. padding: 0 56rpx;
  160. box-sizing: border-box;
  161. .btn {
  162. width: 100%;
  163. padding: 29rpx 0;
  164. color: $uni-text-color-inverse;
  165. font-size: 28rpx;
  166. line-height: 40rpx;
  167. border-radius: 49rpx;
  168. border: none;
  169. background-image: linear-gradient(to right, #84A73F, #D8FF8F);
  170. }
  171. }
  172. </style>