index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <div class="index">
  3. <u-modal v-model="show" :show-title="false" :show-confirm-button="false" mask-close-able>
  4. <view class="slot-content">
  5. <image @click="downLoad()" class="img" :src="imgUrl" />
  6. <div class="canvas-hide">
  7. <!-- #ifdef MP-WEIXIN -->
  8. <canvas id="canvas" type="2d" style="width: 600px; height: 960px" />
  9. <!-- #endif -->
  10. <!-- #ifndef MP-WEIXIN -->
  11. <canvas canvas-id="canvas" id="canvas" style="width: 600px; height: 960px" />
  12. <!-- #endif -->
  13. </div>
  14. </view>
  15. </u-modal>
  16. </div>
  17. </template>
  18. <script>
  19. import DrawPoster from "@/js_sdk/u-draw-poster";
  20. export default {
  21. data: () => ({
  22. imgUrl: "",
  23. width: "",
  24. height: "",
  25. show: false,
  26. dp: {},
  27. logo: require("@/pages/passport/static/logo-title.png"),
  28. }),
  29. props: {
  30. /**
  31. * 封装组件
  32. */
  33. res: {
  34. type: null,
  35. default: "",
  36. },
  37. },
  38. onUnload() {},
  39. methods: {
  40. /**
  41. * 解决微信小程序中图片模糊问题
  42. */
  43. // #ifdef MP-WEIXIN
  44. st2: (size) => size * 2,
  45. // #endif
  46. // #ifndef MP-WEIXIN
  47. st2: (size) => size,
  48. // #endif
  49. downLoad() {
  50. uni.saveImageToPhotosAlbum({
  51. filePath: this.imgUrl,
  52. success: function () {
  53. uni.showToast({
  54. title: "保存成功!",
  55. icon: "none",
  56. });
  57. },
  58. fail: function () {
  59. uni.showToast({
  60. title: "保存失败,请稍后重试!",
  61. icon: "none",
  62. });
  63. },
  64. });
  65. },
  66. /**
  67. * 创建canvas
  68. */
  69. async init() {
  70. this.show = true;
  71. this.dp = await DrawPoster.build({
  72. selector: "canvas",
  73. componentThis: this,
  74. loading: true,
  75. debugging: true,
  76. });
  77. let dp = this.dp;
  78. // #ifdef MP-WEIXIN
  79. // 用于微信小程序中画布错乱问题
  80. dp.canvas.width = this.st2(600);
  81. dp.canvas.height = this.st2(960);
  82. // #endif
  83. this.draw(dp);
  84. },
  85. async draw(dp) {
  86. const { width, height, background, title } = this.res.container;
  87. const { code, img, price } = this.res.bottom;
  88. // /** 绘制背景 */
  89. await dp.draw((ctx) => {
  90. ctx.fillStyle = background;
  91. ctx.fillRoundRect(
  92. this.st2(0),
  93. this.st2(0),
  94. this.st2(width),
  95. this.st2(height),
  96. this.st2(12)
  97. );
  98. ctx.clip();
  99. });
  100. /** 绘制图片 */
  101. dp.draw(async (ctx) => {
  102. await Promise.all([
  103. // 绘制Logo
  104. ctx.drawImage(
  105. this.logo,
  106. this.st2(175),
  107. this.st2(0),
  108. this.st2(256),
  109. this.st2(144)
  110. ),
  111. // 中间图片
  112. ctx.drawImage(
  113. img,
  114. this.st2(100),
  115. this.st2(150),
  116. this.st2(400),
  117. this.st2(400)
  118. ),
  119. // 二维码
  120. ctx.drawImage(
  121. code,
  122. this.st2(39),
  123. this.st2(750),
  124. this.st2(150),
  125. this.st2(150)
  126. ),
  127. ]);
  128. });
  129. /** 绘制中间文字*/
  130. await dp.draw((ctx) => {
  131. ctx.fillStyle = "#333";
  132. ctx.font = `bold ${this.st2(24)}px PingFang SC`;
  133. ctx.textAlign = "center";
  134. ctx.fillWarpText({
  135. text: title,
  136. maxWidth: this.st2(500),
  137. x: this.st2(300),
  138. y: this.st2(600),
  139. layer: 1,
  140. });
  141. ctx.fillStyle = "#ff3c2a";
  142. ctx.font = `${this.st2(38)}px PingFang SC`;
  143. ctx.textAlign = "center";
  144. ctx.fillText(price, this.st2(300), this.st2(680));
  145. });
  146. // /** 绘制底部文字 */
  147. await dp.draw((ctx) => {
  148. ctx.fillStyle = "#666";
  149. ctx.font = `${this.st2(24)}px PingFang SC`;
  150. ctx.fillText("长按图片,识别二维码", this.st2(200), this.st2(866));
  151. ctx.fillStyle = "#666";
  152. ctx.font = `${this.st2(24)}px PingFang SC`;
  153. ctx.fillText("查看商品详情", this.st2(200), this.st2(900));
  154. });
  155. this.imgUrl = await dp.createImagePath();
  156. // console.log(posterImgUrl)
  157. },
  158. },
  159. async mounted() {
  160. this.init();
  161. },
  162. };
  163. </script>
  164. <style lang="scss" scoped>
  165. page,
  166. .index {
  167. height: 100%;
  168. }
  169. .canvas-hide {
  170. /* 1 */
  171. position: fixed;
  172. right: 100vw;
  173. bottom: 100vh;
  174. /* 2 */
  175. z-index: -9999;
  176. /* 3 */
  177. opacity: 0;
  178. }
  179. .index {
  180. position: relative;
  181. text-align: center;
  182. background: rgba($color: grey, $alpha: 0.2);
  183. }
  184. image {
  185. display: block;
  186. }
  187. .img {
  188. width: 600rpx;
  189. height: 960rpx;
  190. }
  191. </style>