shareQrCode.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <template>
  2. <view class="content">
  3. <image src="../../static/img/sharebg.png" mode="" class="bg"></image>
  4. <!-- <view class="qrimg"> -->
  5. <!-- <tki-qrcode :key="'http://shop.zhengyjk1994.com/register?petent=' + userInfo.uid" cid="tki-qrcode-canvas"
  6. ref="qrcode"
  7. :val="'http://shop.zhengyjk1994.com/register?petent=' + userInfo.uid"
  8. :size="300" unit="upx" background="#ffffff" foreground="#333333" pdground="#333333" icon=""
  9. :iconSize="40" :lv="3" :onval="true" :loadMake="true" :usingComponents="true" /> -->
  10. <!-- </view> -->
  11. <view class="er">
  12. <tki-qrcode :key="baseURL + '/index?petent=' + userInfo.id" cid="tki-qrcode-canvas" ref="qrcode"
  13. :val="baseURL + '/index?petent=' + userInfo.id" :size="150" unit="upx" background="#ffffff"
  14. foreground="#333333" pdground="#333333" icon="" :iconSize="40" :lv="3" :onval="true" :loadMake="true"
  15. :usingComponents="true" />
  16. </view>
  17. <view class="title">
  18. ID:{{id}}
  19. </view>
  20. <!-- #ifndef MP-ALIPAY -->
  21. <!-- <canvas :class="{ qrimg: !loading }" @longtap="alertCanv" id="qrShareBox" canvas-id="qrShareBox" class="tki-qrcode-canvas" /> -->
  22. <!-- #endif -->
  23. <!-- #ifdef MP-ALIPAY -->
  24. <!-- <canvas :class="{ qrimg: !loading }" @longtap="alertCanv" id="qrShareBox" class="tki-qrcode-canvas" /> -->
  25. <!-- #endif -->
  26. <!-- <view :style="{ display: loading ? 'none' : 'block' }" class="tki-qrcode-canvas"><image :src="ctxSrc" mode="scaleToFill" class="tki-qrcode-canvas"></image></view>
  27. <view class="share-bottom flex" :class="{ 'action-share-bottom': !loading }" @click="loading ? showImg() : ''">
  28. <text>{{ loading ? '点击生成图片' : '长按二维码下载' }}</text>
  29. </view> -->
  30. </view>
  31. </template>
  32. <script>
  33. import tkiQrcode from '@/components/tki-qrcode/tki-qrcode.vue';
  34. import {
  35. spreadBanner
  36. } from '@/api/user.js';
  37. import {
  38. mapState,
  39. mapMutations
  40. } from 'vuex';
  41. export default {
  42. components: {
  43. tkiQrcode
  44. },
  45. computed: {
  46. ...mapState('user', ['userInfo', 'orderInfo', 'hasLogin']),
  47. ...mapState(['baseURL'])
  48. },
  49. data() {
  50. return {
  51. id:'',
  52. cid: 'tki-qrcode-canvas', //canvasId,页面存在多个二维码组件时需设置不同的ID
  53. size: 180, //生成的二维码大小
  54. unit: 'upx', //大小单位尺寸
  55. // show: true,//默认使用组件中的image标签显示二维码
  56. val: '', //要生成的内容
  57. background: '#ffffff', //二维码背景色
  58. foreground: '#333333', //二维码前景色
  59. pdground: '#333333', //二维码角标色
  60. icon: '', //二维码图标URL(必须是本地图片,网络图需要先下载至本地)
  61. iconSize: 40, //二维码图标大小
  62. lv: 3, //容错级别
  63. onval: true, //监听val值变化自动重新生成二维码
  64. loadMake: false, //组件初始化完成后自动生成二维码,val需要有值
  65. usingComponents: false, //是否使用了自定义组件模式(主要是为了修复非自定义组件模式时 v-if 无法生成二维码的问题)
  66. showLoading: true, //是否显示loading
  67. loadingText: '二维码生成中', //loading文字
  68. src: '', // 二维码生成后的图片地址或base64
  69. ratio: 1, //页面比例用于计算
  70. ctxSrc: '', //要显示的图片
  71. loading: true, //是否载入图片中
  72. canHeight: '', //画布高度
  73. canWeidth: '' //画布宽度
  74. };
  75. },
  76. onLoad() {
  77. this.id = this.userInfo.id + '';
  78. if (this.id.length < 8) {
  79. let k = '';
  80. for (let j = 0; j < 8 - this.id.length; j++) {
  81. k += '0';
  82. }
  83. this.id = k + this.id;
  84. }
  85. uni.setNavigationBarTitle({
  86. title:this.$t('foo.wdewm')
  87. })
  88. // this.loadCodeList()
  89. },
  90. // onReady() {
  91. // let obj = this;
  92. // let query = uni.createSelectorQuery();
  93. // // 获取页面比例
  94. // query
  95. // .select('.content')
  96. // .fields(
  97. // {
  98. // size: true
  99. // },
  100. // e => {
  101. // // 保存比例
  102. // this.ratio = e.width / 750;
  103. // }
  104. // )
  105. // .exec();
  106. // // 获取画布宽高信息
  107. // query
  108. // .select('#qrShareBox')
  109. // .fields(
  110. // {
  111. // size: true
  112. // },
  113. // e => {
  114. // // 保存画布宽高信息
  115. // obj.canHeight = e.height;
  116. // obj.canWeidth = e.width;
  117. // }
  118. // )
  119. // .exec();
  120. // },
  121. methods: {
  122. loadCodeList() {
  123. // 加载二维码信息
  124. spreadBanner({
  125. // #ifdef H5
  126. type: 2,
  127. // #endif
  128. // #ifdef MP
  129. type: 1
  130. // #endif
  131. }).then(e => {
  132. // #ifdef MP
  133. // 保存二维码图片
  134. uni.downloadFile({
  135. url: e.data[0].wap_posterQr,
  136. success(res) {
  137. if (res.errMsg == 'downloadFile:ok') {
  138. obj.src = res.tempFilePath;
  139. // 生成画布
  140. obj.loadImg(obj.src);
  141. uni.hideLoading();
  142. }
  143. console.log(res);
  144. },
  145. fail(e) {
  146. console.log(e);
  147. }
  148. })
  149. // #endif
  150. // #ifdef H5
  151. // 保存二维码图片
  152. this.src = e.data[0].wap_posterQr;
  153. // 生成画布
  154. this.loadImg(e.data[0].wap_posterQr);
  155. // #endif
  156. }).catch((e) => {
  157. uni.showModal({
  158. title: '生成失败请刷新页面',
  159. showCancel: false
  160. });
  161. uni.hideLoading();
  162. });;
  163. },
  164. // 长按画布事件
  165. alertCanv() {
  166. uni.showModal({
  167. title: '请先点击生成图片再下载',
  168. showCancel: false
  169. });
  170. },
  171. // 生成图片
  172. showImg() {
  173. uni.showLoading({
  174. title: '图片生成中',
  175. mask: true
  176. });
  177. let obj = this;
  178. //因为和uni.showLoading载入效果冲突需要延迟执行生成图片方法
  179. setTimeout(function() {
  180. uni.canvasToTempFilePath({
  181. x: 0,
  182. y: 0,
  183. width: obj.canWeidth,
  184. height: obj.canHeight,
  185. destWidth: obj.canWeidth,
  186. destHeight: obj.canHeight,
  187. fileType: 'jpg',
  188. quality: 1,
  189. canvasId: 'qrShareBox',
  190. success: res => {
  191. uni.hideLoading();
  192. uni.showModal({
  193. title: '创建成功,长按二维码下载图片',
  194. showCancel: false
  195. });
  196. // 显示生成的图片
  197. obj.loading = false;
  198. // 保存图片base64
  199. obj.ctxSrc = res.tempFilePath;
  200. },
  201. fail(e) {
  202. console.log(e);
  203. }
  204. });
  205. }, 50);
  206. },
  207. // 开始渲染画布
  208. loadImg(src) {
  209. const obj = this;
  210. const cavWidth = 523; //画布宽度
  211. const cavHeight = 700; //画布高度
  212. const ratio = obj.ratio; //获取页面比例
  213. const ctxBg = '/static/img/img14.jpg'; //画布背景
  214. let context = uni.createCanvasContext('qrShareBox');
  215. const codeSize = obj.size * ratio; //计算二维码大小
  216. const codeX = ((cavWidth - obj.size) * ratio) / 2; //二维码所在x轴位置
  217. const codeY = cavHeight * ratio; //二维码所在y轴位置
  218. const codeBoxColor = '#FFFFFF'; //包裹框颜色
  219. const codeBoxWidht = 0; //包裹边框宽度
  220. const codeBoxSize = (codeBoxWidht / 2) * ratio; //计算二维码白色包裹框大小
  221. const codeBoxX = codeX - codeBoxSize; //包裹框初始X轴
  222. const codeBoxY = codeY - codeBoxSize; //包裹框初始Y轴
  223. const codeBoxEnd = codeSize + codeBoxWidht * ratio; //计算包裹框大小
  224. const fontTop = codeY + codeBoxEnd + (codeBoxWidht + 20) * this.ratio; //文字距离上边距高度
  225. const fontSize = 24 * ratio; //文字大小
  226. const fontText = ''; //文字内容
  227. const fontLeft = (codeSize - fontSize * fontText.length) / 2 + codeX; //文字左侧距离
  228. // 插入背景图片
  229. context.drawImage(ctxBg, 0, 0, obj.canWeidth, obj.canHeight);
  230. // // 插入文字
  231. context.setFontSize(fontSize);
  232. context.fillText(fontText, fontLeft, fontTop);
  233. // 插入边框
  234. context.beginPath(); //开始画线
  235. context.setLineJoin('round'); //边框类型
  236. context.setLineWidth(codeBoxWidht * ratio);
  237. context.setStrokeStyle(codeBoxColor); //设置包裹框颜色
  238. context.strokeRect(codeBoxX, codeBoxY, codeBoxEnd, codeBoxEnd);
  239. context.stroke(); //渲染线条
  240. // 插入二维码
  241. context.drawImage(src, codeX, codeY, codeSize, codeSize);
  242. // 开始渲染
  243. context.draw();
  244. },
  245. // 創建二维码
  246. creatQrcode() {
  247. this.$refs.qrcode._makeCode();
  248. },
  249. // 保存二维码到图库
  250. saveQrcode() {
  251. this.$refs.qrcode._saveCode();
  252. },
  253. // 生成二维码后返回base64
  254. qrR(res) {
  255. this.src = res;
  256. },
  257. //清空二维码(清空二维码会触发result回调 返回值为空)
  258. clearQrcode(e) {
  259. this.$refs.qrcode._clearCode();
  260. this.val = '';
  261. }
  262. }
  263. };
  264. </script>
  265. <style lang="scss">
  266. .content {
  267. // padding-top: 30rpx;
  268. height: calc(100vh - 44px);
  269. position: relative;
  270. }
  271. .bg {
  272. position: relative;
  273. height: calc(100vh - 44px);
  274. width: 100%;
  275. }
  276. // #qrShareBox {
  277. // position: absolute;
  278. // left: -9999rpx;
  279. // top: -9999rpx;
  280. // }
  281. .qrimg {
  282. position: absolute;
  283. left: -9999rpx;
  284. top: -9999rpx;
  285. }
  286. .tki-qrcode-canvas {
  287. // width: 700rpx;
  288. // height: 1245rpx;
  289. width: 532rpx;
  290. height: 945rpx;
  291. margin: 0 auto;
  292. }
  293. .share-bottom {
  294. width: 560rpx;
  295. height: 80rpx;
  296. color: #ffffff;
  297. background-color: $base-color;
  298. margin: 0 auto;
  299. font-size: $font-lg - 2rpx;
  300. margin-top: 30rpx;
  301. border-radius: 99rpx;
  302. justify-content: center;
  303. &.action-share-bottom {
  304. background-color: $color-gray;
  305. }
  306. }
  307. .tki-qrcode {
  308. width: 300rpx;
  309. height: 300rpx;
  310. position: fixed;
  311. bottom: 10vh;
  312. right: 0;
  313. left: 0;
  314. margin: auto;
  315. }
  316. .er {
  317. position: absolute;
  318. top: 82%;
  319. left: 40%;
  320. }
  321. .title {
  322. position: absolute;
  323. top: 86%;
  324. left: 50%;
  325. margin-left: -100rpx;
  326. width: 200rpx;
  327. background: #ff3130;
  328. text-align: center;
  329. border-radius: 10rpx;
  330. color: #FFFFFF;
  331. }
  332. </style>