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