qrcode-poster.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <view class="content" @touchmove.stop.prevent="moveHandle" v-if="isShow" @click.stop="isShow=false">
  3. <canvas @click.stop="" :style="{ width: canvasW + 'px', height: canvasH + 'px' }" :width="canvasWW + 'px'" :height="canvasHH + 'px'" canvas-id="my-canvas"></canvas>
  4. <view class="save-btn-wrap savepadding">
  5. <view class="save-btn" @click.stop="saveImage">保存图片</view>
  6. </view>
  7. </view>
  8. </template>
  9. <script>
  10. export default{
  11. props:{
  12. backImagUrl: {
  13. type: String,
  14. default: ''
  15. }, headerImgUrl:{
  16. type: String,
  17. default: ''
  18. },
  19. memberName:{
  20. type: String,
  21. default: '会员'
  22. },
  23. qdImageUrl:{
  24. type: String,
  25. default: ''
  26. },
  27. codeType:{
  28. type: Number,
  29. default: 0
  30. },
  31. goodsIamgeUrl:{
  32. type: String,
  33. default: ''
  34. },
  35. goodsName:{
  36. type: String,
  37. default: '精品'
  38. },
  39. goodsPrice:{
  40. type:Number,
  41. default: 0.00
  42. },
  43. goodsYPrice:{
  44. type: Number,
  45. default: 0.00
  46. }
  47. },
  48. data(){
  49. return {
  50. canvasW: 0,
  51. canvasH: 0,
  52. canvasWW: 0,
  53. canvasHH: 0,
  54. ctx: null,
  55. isShow: false,
  56. qrcode: ''
  57. }
  58. },
  59. methods:{
  60. //显示
  61. showCanvas(){
  62. this.isShow = true
  63. this.__init()
  64. },
  65. //初始化画布
  66. async __init(){
  67. uni.showLoading({
  68. title: '加载中...',
  69. mask: true
  70. })
  71. this.ctx = uni.createCanvasContext('my-canvas',this)
  72. this.canvasW = uni.upx2px(580);
  73. this.canvasH = uni.upx2px(1020);
  74. this.canvasWW = this.canvasW * 2;
  75. this.canvasHH = this.canvasH * 2;
  76. //设置画布背景透明
  77. this.ctx.setFillStyle('rgba(255, 255, 255, 1)')
  78. //设置画布大小
  79. this.ctx.fillRect(0,0,this.canvasW,this.canvasH)
  80. // 绘制背景图片
  81. let backImag = await this.getImageInfo(this.backImagUrl);
  82. this.ctx.drawImage(backImag.path,0,0, this.canvasW, this.canvasH);
  83. // 绘制会员名
  84. // this.ctx.setFontSize(15); //设置标题字体大小
  85. // this.ctx.setFillStyle('#333'); //设置标题文本颜色
  86. // this.ctx.fillText(this.memberName,uni.upx2px(140), uni.upx2px(160))
  87. // 绘制商品图片
  88. // let goodsIamge = await this.getImageInfo(this.goodsIamgeUrl);
  89. // this.roundedRectangle(this.ctx, uni.upx2px(17), uni.upx2px(55), uni.upx2px(549), uni.upx2px(549),10,goodsIamge.path);
  90. //绘制价格
  91. // this.ctx.setFontSize(12);
  92. // this.ctx.setFillStyle('#ff631d');
  93. // this.ctx.fillText('¥', uni.upx2px(395), uni.upx2px(740));
  94. // this.ctx.setFontSize(18);
  95. // this.ctx.setFillStyle('#ff631d');
  96. // this.ctx.fillText((this.goodsPrice).toFixed(2), uni.upx2px(420), uni.upx2px(740));
  97. // 绘制商品名称
  98. // let hW = uni.upx2px(500);
  99. // this.ctx.setFontSize(12);
  100. // this.ctx.setFillStyle('#757575');
  101. // let sWidth = this.ctx.measureText(this.goodsName).width
  102. // if (this.goodsName.length < 14) {
  103. // this.ctx.fillText(this.goodsName, uni.upx2px(40), uni.upx2px(730));
  104. // } else{
  105. // this.ctx.fillText(this.goodsName.slice(0, 14), uni.upx2px(40), uni.upx2px(730));
  106. // this.ctx.fillText(this.goodsName.slice(14,26) + '..', uni.upx2px(40), uni.upx2px(765));
  107. // }
  108. // 绘制头像
  109. //let headerImg = await this.getImageInfo(this.headerImgUrl);
  110. //this.drawCircular(this.ctx, headerImg.path, uni.upx2px(60), uni.upx2px(800), uni.upx2px(75), uni.upx2px(75));
  111. // 绘制小程序码 // 不发胖
  112. if (this.codeType == 1) {
  113. let qdImage = await this.getImageInfo(this.qdImageUrl);
  114. this.ctx.drawImage(qdImage.path, uni.upx2px(225), uni.upx2px(785), uni.upx2px(140), uni.upx2px(140));
  115. }
  116. if (this.codeType == 2 || this.codeType == 6){
  117. // 绘制小程序码 // 按时吃饭
  118. let qdImage = await this.getImageInfo(this.qdImageUrl);
  119. this.ctx.drawImage(qdImage.path, uni.upx2px(120), uni.upx2px(575), uni.upx2px(335), uni.upx2px(335));
  120. }
  121. if (this.codeType == 3) {
  122. // 绘制小程序码 // 科技质感
  123. let qdImage = await this.getImageInfo(this.qdImageUrl);
  124. this.ctx.drawImage(qdImage.path, uni.upx2px(140), uni.upx2px(370), uni.upx2px(300), uni.upx2px(300));
  125. }
  126. if (this.codeType == 4) {
  127. // 绘制小程序码 // 叮咚黄
  128. let qdImage = await this.getImageInfo(this.qdImageUrl);
  129. this.ctx.drawImage(qdImage.path, uni.upx2px(135), uni.upx2px(370), uni.upx2px(305), uni.upx2px(305));
  130. }
  131. if (this.codeType == 5) {
  132. // 绘制小程序码 // 美味点心
  133. let qdImage = await this.getImageInfo(this.qdImageUrl);
  134. this.ctx.drawImage(qdImage.path, uni.upx2px(160), uni.upx2px(475), uni.upx2px(265), uni.upx2px(265));
  135. }
  136. setTimeout(()=>{
  137. this.ctx.draw(true,()=>{
  138. uni.hideLoading()
  139. })
  140. },500)
  141. },
  142. //画圆形头像
  143. drawCircular(ctx, url, x, y, width, height) {
  144. ctx.save();
  145. ctx.beginPath();
  146. ctx.arc(width / 2 + x, height / 2 + y, width / 2, 0, Math.PI * 2, false);
  147. ctx.clip();
  148. ctx.drawImage(url, x, y, width, height);
  149. ctx.restore();
  150. ctx.closePath();
  151. },
  152. roundedRectangle(ctx, x, y, width, height, r,url){
  153. ctx.save();
  154. ctx.beginPath();
  155. ctx.moveTo(x + r, y);
  156. ctx.lineTo(x + width - r, y);
  157. ctx.arc(x + width - r, y + r, r, Math.PI*1.5, Math.PI*2);
  158. ctx.lineTo(x + width, y + height - r);
  159. ctx.arc(x + width - r, y + height - r, r, 0, Math.PI*0.5);
  160. ctx.lineTo(x + r, y + height);
  161. ctx.arc(x + r, y + height - r, r, Math.PI*0.5, Math.PI);
  162. ctx.lineTo(x, y + r);
  163. ctx.arc(x + r, y + r, r, Math.PI, Math.PI*1.5);
  164. ctx.clip();;
  165. ctx.drawImage(url, x, y, width, height);
  166. ctx.restore();
  167. ctx.closePath();
  168. },
  169. //获取图片
  170. getImageInfo(imgSrc){
  171. return new Promise((resolve, reject) => {
  172. uni.getImageInfo({
  173. src: imgSrc,
  174. success: (image) => {
  175. resolve(image);
  176. },
  177. fail: (err) => {
  178. reject(err);
  179. setTimeout(()=>{
  180. uni.hideLoading()
  181. },500)
  182. }
  183. });
  184. });
  185. },
  186. moveHandle(){},
  187. //保存图片到相册
  188. saveImage(){
  189. var that = this
  190. uni.canvasToTempFilePath({
  191. canvasId: 'my-canvas',
  192. quality: 1,
  193. complete: (res) => {
  194. uni.saveImageToPhotosAlbum({
  195. filePath: res.tempFilePath,
  196. success(res) {
  197. uni.showToast({
  198. title: '已保存到相册',
  199. icon: 'success',
  200. duration: 2000
  201. })
  202. setTimeout(()=>{
  203. that.isShow = false
  204. },2000)
  205. }
  206. })
  207. }
  208. },this);
  209. }
  210. }
  211. }
  212. </script>
  213. <style scoped lang="scss">
  214. .content{
  215. position: fixed;
  216. top: 0;
  217. left: 0;
  218. right: 0;
  219. bottom: 90upx;
  220. background: rgba(0,0,0,.4);
  221. display: flex;
  222. flex-direction: column;
  223. justify-content: center;
  224. align-items: center;
  225. z-index: 99;
  226. .save-btn-wrap{
  227. position: fixed;
  228. left: 0;
  229. bottom: 0;
  230. height: 100upx;
  231. background: #fff;
  232. display: flex;
  233. justify-content: center;
  234. align-items: center;
  235. width: 100%;
  236. }
  237. .save-btn{
  238. // color: #fff;
  239. // // background-image: linear-gradient(#fce799, #e7c389);
  240. // background-image: linear-gradient(#f2190c, #f2370c);
  241. // padding: 15rpx 40rpx;
  242. // border-radius: 50rpx;
  243. width: 80%;
  244. height: 80rpx;
  245. border-radius: 40rpx;
  246. position: fixed;
  247. left: 10%;
  248. bottom: calc(20rpx + env(safe-area-inset-bottom));
  249. bottom: calc(20rpx + constant(safe-area-inset-bottom));
  250. background-color: $light-color;
  251. color: #fff;
  252. font-size: 36rpx;
  253. @include flexCenter;
  254. padding: 15rpx 40rpx;
  255. }
  256. }
  257. /* ios底部安全距离-padding */
  258. .savepadding {
  259. padding-bottom: constant(safe-area-inset-bottom);
  260. padding-bottom: env(safe-area-inset-bottom);
  261. box-sizing: content-box;
  262. }
  263. /* ios底部安全距离-bottom */
  264. .savebottom {
  265. bottom: constant(safe-area-inset-bottom);
  266. bottom: env(safe-area-inset-bottom);
  267. }
  268. </style>