wm-posterorders.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <template>
  2. <view style="background: #FFFFFF;">
  3. <!-- <view v-if="loading"></view> -->
  4. <canvas v-if="!tempFilePath" :canvas-id="CanvasID" :style="{ width: canvasW + 'px', height: canvasH + 'px' }"></canvas>
  5. <image v-else lazy-load :src="tempFilePath" mode="widthFix" class="is-response" @longpress="toSave(tempFilePath)"></image>
  6. </view>
  7. </template>
  8. <script>
  9. var _this;
  10. export default {
  11. name: 'wm-poster',
  12. props: {
  13. CanvasID: {
  14. //CanvasID 等同于 canvas-id
  15. Type: String,
  16. default: 'PosterCanvas'
  17. },
  18. imgSrc: {
  19. //展示图
  20. Type: String,
  21. default: ''
  22. },
  23. QrSrc: {
  24. //二维码
  25. Type: String,
  26. default: ''
  27. },
  28. Title: {
  29. //文本内容
  30. Type: String,
  31. default: ''
  32. },
  33. TitleColor: {
  34. //标题颜色
  35. Type: String,
  36. default: '#000000'
  37. },
  38. LineType: {
  39. //标题显示行数 (注超出2行显示会导致画布布局絮乱)
  40. Type: [String, Boolean],
  41. default: true
  42. },
  43. PriceTxt: {
  44. //价格值
  45. Type: String,
  46. default: ''
  47. },
  48. PriceColor: {
  49. //价格颜色
  50. Type: String,
  51. default: '#e31d1a'
  52. },
  53. OriginalTxt: {
  54. //原价值
  55. Type: String,
  56. default: ''
  57. },
  58. OriginalColor: {
  59. //默认颜色(如原价与扫描二维码颜色)
  60. Type: String,
  61. default: '#b8b8b8'
  62. },
  63. Width: {
  64. //画布宽度 (高度根据图片比例计算 单位upx)
  65. Type: String,
  66. default: 700
  67. },
  68. CanvasBg: {
  69. //canvas画布背景色
  70. Type: String,
  71. default: '#ffffff'
  72. },
  73. Referrer: {
  74. //推荐人信息
  75. Type: String,
  76. default: ''
  77. },
  78. ViewDetails: {
  79. //描述提示文字
  80. Type: String,
  81. default: '长按或扫描识别二维码'
  82. }
  83. },
  84. data() {
  85. return {
  86. loading: false,
  87. tempFilePath: '',
  88. canvasW: 0,
  89. canvasH: 0,
  90. canvasImgSrc: '',
  91. ctx: null
  92. };
  93. },
  94. methods: {
  95. toSave(url) {
  96. //#ifndef H5
  97. uni.getImageInfo({
  98. src: url,
  99. success: function(image) {
  100. console.log('图片信息:', JSON.stringify(image));
  101. uni.saveImageToPhotosAlbum({
  102. filePath: image.path,
  103. success: function() {
  104. console.log('save success');
  105. uni.showToast({
  106. title: '海报已保存相册',
  107. icon: 'success',
  108. duration: 2000
  109. });
  110. }
  111. });
  112. }
  113. });
  114. //#endif
  115. },
  116. async OnCanvas() {
  117. this.loading = true;
  118. // this.$queue.showLoading('海报生成中...');
  119. _this.ctx = uni.createCanvasContext(_this.CanvasID, this);
  120. const C_W = uni.upx2px(_this.Width), //canvas宽度
  121. C_P = uni.upx2px(30), //canvas Paddng 间距
  122. C_Q = uni.upx2px(150); //二维码或太阳码宽高
  123. let _strlineW = 0; //文本宽度
  124. let _imgInfo = await _this.getImageInfo({
  125. imgSrc: _this.imgSrc
  126. }); //广告图
  127. let _QrCode = await _this.getImageInfo({
  128. imgSrc: _this.QrSrc
  129. }); //二维码或太阳码
  130. let r = [_imgInfo.width, _imgInfo.height];
  131. let q = [_QrCode.width, _QrCode.height];
  132. let imgW = C_W - C_P * 2-8;
  133. if (r[0] != imgW) {
  134. r[1] = Math.floor((imgW / r[0]) * r[1]);
  135. r[0] = imgW;
  136. }
  137. if (q[0] != C_Q) {
  138. q[1] = Math.floor((C_Q / q[0]) * q[1]);
  139. q[0] = C_Q;
  140. }
  141. _this.canvasW = C_W;
  142. _this.canvasH = r[1] + q[1] + 68;
  143. _this.ctx.setFillStyle(_this.CanvasBg); //canvas背景颜色
  144. _this.ctx.fillRect(0, 0, C_W, _this.canvasH); //canvas画布大小
  145. //添加图片展示
  146. _this.ctx.drawImage(_imgInfo.path, C_P, C_P, r[0], r[1]);
  147. //添加图片展示 end
  148. //设置文本
  149. //#ifdef H5
  150. _this.ctx.setFontSize(uni.upx2px(32)); //设置标题字体大小
  151. //#endif
  152. //#ifdef APP-PLUS
  153. _this.ctx.setFontSize(uni.upx2px(36)); //设置标题字体大小
  154. _this.Title=_this.Title.substring(0,20)
  155. //#endif
  156. _this.ctx.setFillStyle(_this.TitleColor); //设置标题文本颜色
  157. let _strLastIndex = 0; //每次开始截取的字符串的索引
  158. let _strHeight = r[1] + C_P * 2 + 10; //绘制字体距离canvas顶部的初始高度
  159. let _num = 1;
  160. for (let i = 0; i < _this.Title.length; i++) {
  161. _strlineW += _this.ctx.measureText(_this.Title[i]).width;
  162. if (_strlineW > r[0]) {
  163. if (_num == 2 && _this.LineType) {
  164. //文字换行数量大于二进行省略号处理
  165. _this.ctx.fillText(_this.Title.substring(_strLastIndex, i - 8) + '...', C_P, _strHeight);
  166. _strlineW = 0;
  167. _strLastIndex = i;
  168. _num++;
  169. break;
  170. } else {
  171. _this.ctx.fillText(_this.Title.substring(_strLastIndex, i), C_P, _strHeight);
  172. _strlineW = 0;
  173. _strHeight += 20;
  174. _strLastIndex = i;
  175. _num++;
  176. }
  177. } else if (i == _this.Title.length - 1) {
  178. _this.ctx.fillText(_this.Title.substring(_strLastIndex, i + 1), C_P, _strHeight);
  179. _strlineW = 0;
  180. }
  181. }
  182. //设置文本 end
  183. //添加二维码
  184. _strHeight += uni.upx2px(20);
  185. _this.ctx.drawImage(_QrCode.path, r[0] - q[0] + C_P, _strHeight, q[0], q[1]);
  186. //添加二维码 end
  187. //添加推荐人与描述
  188. _this.ctx.setFillStyle(_this.TitleColor);
  189. _this.ctx.setFontSize(uni.upx2px(30));
  190. _this.ctx.fillText(_this.Referrer, C_P, _strHeight + q[1] / 2);
  191. _this.ctx.setFillStyle(_this.OriginalColor);
  192. _this.ctx.setFontSize(uni.upx2px(24));
  193. _this.ctx.fillText(_this.ViewDetails, C_P, _strHeight + q[1] / 2 + 20);
  194. //添加推荐人与描述 end
  195. //延迟后渲染至canvas上
  196. setTimeout(function() {
  197. _this.ctx.draw(true, ret => {
  198. _this.getNewImage();
  199. });
  200. }, 600);
  201. },
  202. async getImageInfo({
  203. imgSrc
  204. }) {
  205. return new Promise((resolve, errs) => {
  206. uni.getImageInfo({
  207. src: imgSrc,
  208. success: function(image) {
  209. resolve(image);
  210. },
  211. fail(err) {
  212. errs(err);
  213. _this.$queue.showToast('海报生成失败');
  214. uni.hideLoading()
  215. }
  216. });
  217. });
  218. },
  219. getNewImage() {
  220. uni.canvasToTempFilePath({
  221. canvasId: _this.CanvasID,
  222. quality: 1,
  223. complete: res => {
  224. _this.tempFilePath = res.tempFilePath;
  225. _this.$emit('success', res);
  226. _this.loading = false;
  227. _this.$queue.showToast('长按图片保存海报');
  228. uni.hideLoading()
  229. }
  230. },
  231. this
  232. );
  233. }
  234. },
  235. mounted() {
  236. _this = this;
  237. this.OnCanvas();
  238. }
  239. };
  240. </script>
  241. <style></style>