请选择 进入手机版 | 继续访问电脑版

乐趣微盟

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 264|回复: 0

微信小程序生成海报及源代码

[复制链接]

298

主题

314

帖子

1206

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1206
发表于 2018-8-23 21:16:01 | 显示全部楼层 |阅读模式
微信小程序生成海报的代码如下:

promisify文件:
  1. module.exports = {  
  2.   promisify: api => {  
  3.     return (options, ...params) => {  
  4.       return new Promise((resolve, reject) => {  
  5.         const extras = {  
  6.           success: resolve,  
  7.           fail: reject  
  8.         }  
  9.         api({ ...options, ...extras }, ...params)  
  10.       })  
  11.     }  
  12.   }   
  13. }
复制代码
开始:
  1. import {promisify} from './promisify'

  2. const wxGetImageInfo = promisify(wx.getImageInfo)
  3. // 图标路径
  4. const [localtionIconUrl, timeIconUrl, assemblyPointIconUrl] = ['/img/icons/localtion.png', '/img/icons/time.png', '/img/icons/assembly-point .png']
  5. // 是否是大屏幕
  6. const isLargeScreen = wx.getSystemInfoSync().windowHeight > 516
  7. // canvas 宽、高、内边距
  8. const [cvsW, cvsH, cvsPL, cvsPT, cvsPB] = [300, 516, 16, 22, 70]
  9. // 封面图片宽高
  10. const [coverImgW, coverImgH, qrImgH, qrImgW] = [300, isLargeScreen ? 180 : 150, 90, 90]
  11. // 字体内边距、字体大小、字体颜色
  12. const [fontPL, fontPT, fontSize18, fontSize14, colorBlack, colorGray, colorRed] = [55, 45, 18, 14, '#141414', '#666', 'red']
  13. // 字体分割显示缩略
  14. function helpFontSplit (str, lineNum = 1) {
  15.     const maxChar = 12
  16.     const len = str.length
  17.     let res
  18.     if (len <= maxChar) {// 小于一行
  19.       res = [str]
  20.     } else if (len <= maxChar * lineNum) {// 小于指定行数
  21.       res = [str.slice(0, maxChar), str.slice(maxChar, 37)]
  22.     } else {//大于指定行数
  23.       let temp = []
  24.       for (let i = 0; i < lineNum; i++) {
  25.         if (i === lineNum - 1) {
  26.           temp.push(str.slice(maxChar * i, (i + 1) * maxChar - 3) + '...')
  27.         } else {
  28.           temp.push(str.slice(maxChar * i, (i + 1) * maxChar))
  29.         }
  30.       }
  31.       res = temp
  32.     }
  33.     return lineNum > 1 ? res :[res][0]
  34. }
  35. // 日期格式化
  36. function helpFormatDate (dateArr) {
  37.         if (!Array.isArray(dateArr)) {
  38.                 return
  39.         }
  40.         return dateArr.map(item => {
  41.                 const week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  42.                 let startArr = item.activity_start.split('-')
  43.                 let endArr = item.activity_end.split('-')
  44.                 let start = new Date(startArr.join('/'))
  45.                 let end = new Date(endArr.join('/'))
  46.                 return startArr.splice(1, 2).join('.') + week[start.getDay()] + '~' + endArr.splice(1, 2).join('.') + week[end.getDay()]
  47.         })
  48. }
  49. // canvas转换成图片
  50. export class Canvas2Image {
  51.   constructor(param, qrUrl) {
  52.     this.param = param
  53.     this.qrUrl = qrUrl
  54.     this.isSingle = param.price_date.length == '1'
  55.   }


  56.   getImg (callback) {
  57.           const qrUrl = this.qrUrl
  58.           const coverUrl = this.param.thumb_img
  59.           Promise.all([ // url是服务器地址
  60.             // icon - 1
  61.             wxGetImageInfo({
  62.               src: url+ localtionIconUrl
  63.             }),
  64.             // icon - 2
  65.             wxGetImageInfo({
  66.               src: url + timeIconUrl
  67.             }),
  68.             // icon - 3
  69.             wxGetImageInfo({
  70.               src: url+ assemblyPointIconUrl
  71.             }),
  72.             // 封面图
  73.             wxGetImageInfo({
  74.               src: coverUrl
  75.             }),
  76.             // 小程序码图
  77.             wxGetImageInfo({
  78.               src: url+ qrUrl
  79.             })
  80.           ]).then(res => {
  81.                   callback && callback(res)
  82.           })
  83.   }

  84.   render (canvasId, callback) {
  85.     this.getImg(res => {
  86.             console.log('---图片就绪---')
  87.             console.log(res)
  88.             // 图片路径
  89.             const [{path: localtionIconPath}, {path: timeIconPath}, {path: assemblyPointIconPath}, {path: coverImgPath}, {path: qrImgPath}] = res
  90.             const {activity_name: title, resort: resort, price_list: prices, price_date: times} = this.param
  91.             const ctx = wx.createCanvasContext(canvasId)
  92.             console.log('---绘图开始---')
  93.             this.drawCover(ctx, coverImgPath)
  94.             this.drawIcon(ctx, localtionIconPath, timeIconPath, assemblyPointIconPath)
  95.             this.drawTitle(ctx, helpFontSplit(title, 2))
  96.             this.drawLocaltion(ctx, resort)
  97.             this.drawTime(ctx, helpFormatDate(times))
  98.             this.drawResort (ctx, resort)
  99.             this.drawQrImage (ctx, qrImgPath)
  100.             this.drawPrices (ctx, prices)
  101.             ctx.draw(false, function () {
  102.                       console.log('---canvas绘图完成---')
  103.                       callback && callback()
  104.             })
  105.     })
  106.   }
  107.   // 绘制封面
  108.   drawCover (ctx, coverImgPath) {
  109.           ctx.drawImage(coverImgPath, 0, 0, coverImgW, coverImgH)
  110.   }
  111.   // 绘制图标
  112.   drawIcon (ctx, localtionIconPath, timeIconPath, assemblyPointIconPath) {
  113.           ctx.drawImage(localtionIconPath, fontPL - 20, coverImgH + fontPT * 2.28, 15, 15)
  114.     ctx.drawImage(timeIconPath, fontPL - 20, coverImgH + fontPT * 2.88, 15, 15)
  115.     if (this.isSingle) {
  116.             ctx.drawImage(assemblyPointIconPath, fontPL - 20, coverImgH + fontPT * 3.54, 15, 15)
  117.     } else {
  118.             ctx.drawImage(assemblyPointIconPath, fontPL - 20, coverImgH + fontPT * 4.45, 15, 15)
  119.     }
  120.   }
  121.   // 绘制标题
  122.   drawTitle (ctx, title) {
  123.     ctx.setTextAlign('left')    // 文字居中
  124.     ctx.setFillStyle(colorBlack)  // 文字颜色
  125.     ctx.setFontSize(fontSize18)       // 文字字号:18px
  126.     ctx.fillText(title[0], fontPL - 20, coverImgH + fontPT)
  127.     title[1] && ctx.fillText(title[1], fontPL - 20, coverImgH + fontPT * 1.6)
  128.   }
  129.   // 绘制地点
  130.   drawLocaltion (ctx, adress) {
  131.           // 活动时间、地点
  132.     ctx.setFillStyle(colorGray)  // 文字颜色
  133.     ctx.setFontSize(fontSize14)       // 文字字号:14px
  134.     ctx.fillText('集合地点: ' + helpFontSplit(adress), fontPL, coverImgH + fontPT * 2.55)
  135.   }
  136.   // 绘制班期
  137.   drawTime (ctx, times) {
  138.           ctx.fillText('活动时间 :  ' + times[0], fontPL, coverImgH + fontPT * 3.15)
  139.           if (!this.isSingle) {
  140.                   times[1] && ctx.fillText(times[1], fontPL + 70, coverImgH + fontPT * 3.6)
  141.               times[2] && ctx.fillText(times[2], fontPL + 70, coverImgH + fontPT * 4)
  142.           }
  143.   }
  144.   // 绘制集合地点
  145.   drawResort (ctx, resort) {
  146.           if (this.isSingle) {
  147.                   ctx.fillText('集合地点: ' + helpFontSplit(resort), fontPL, coverImgH + fontPT * 3.8)
  148.           } else {
  149.                   ctx.fillText('集合地点: ' + helpFontSplit(resort), fontPL, coverImgH + fontPT * 4.7)
  150.           }
  151.   }
  152.   // 绘制小程序二维码
  153.   drawQrImage (ctx, qrImgPath) {
  154.           if (isLargeScreen) {
  155.       ctx.drawImage(qrImgPath, cvsW - qrImgW - cvsPL - 16, cvsH - qrImgH - cvsPB + 50, qrImgW, qrImgH)
  156.     } else {
  157.       ctx.drawImage(qrImgPath, cvsW - qrImgW - cvsPL + 10, cvsH - qrImgH - cvsPB + 10, qrImgW - 10, qrImgH - 10)
  158.     }
  159.   }
  160.   // 绘制价格
  161.   drawPrices (ctx, prices) {
  162.           const priceLabel = ['', '成人价: ', '儿童价: ', '老人价: ']
  163.           const baseNum = 5.3
  164.           const increment = 0.6
  165.           if (Array.isArray(prices)) {
  166.                   prices.forEach((item, index) => {
  167.                           ctx.setFillStyle(colorGray)
  168.                           ctx.fillText(priceLabel[item.type], fontPL - 20, coverImgH + fontPT * (baseNum + index * increment))
  169.                           ctx.setFillStyle(colorRed)
  170.                           ctx.fillText('¥' + item.price, fontPL + 35, coverImgH + fontPT * (baseNum + index * increment))
  171.                   })
  172.           }
  173.     ctx.stroke()
  174.   }
  175. }
  176. // 保存至本地
  177. export function saveCanvasImage2Local(canvasId, callback) {
  178.   console.log('---准备保存到本地---')
  179.   const wxCanvasToTempFilePath = promisify(wx.canvasToTempFilePath)
  180.   const wxSaveImageToPhotosAlbum = promisify(wx.saveImageToPhotosAlbum)
  181.   wxCanvasToTempFilePath({
  182.      canvasId: canvasId
  183.   }, this).then(res => {
  184.     console.log('---保存到本地就绪---')
  185.       callback && callback()
  186.       return wxSaveImageToPhotosAlbum({
  187.           filePath: res.tempFilePath
  188.       })
  189.   }).then(res => {
  190.     wx.showModal({...{
  191.         title: '',
  192.         content: '这是一个模态弹窗',
  193.         cancelText: '取消',
  194.         cancelColor: '#505050',
  195.         confirmText: '确定',
  196.         confirmColor: '#ff4558',
  197.         showCancel: true,
  198.         success: function(res) {
  199.           if (res.confirm) {
  200.             console.log('用户点击确定')
  201.           } else if (res.cancel) {
  202.             console.log('用户点击取消')
  203.           }
  204.         }
  205.       }, ...config})
  206.       // wx.showToast({
  207.       //     title: '已保存到相册'
  208.       // })
  209.   })
  210. }
复制代码


回复

使用道具 举报


QQ|Archiver|手机版|小黑屋|乐趣微盟 ( 青ICP备11000010号-2 )

GMT+8, 2018-11-22 02:45 , Processed in 0.130585 second(s), 24 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表