小程序canvas生成海報 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

小程序canvas生成海報

發表時(shí)間:2020-9-29

發布人(rén):融晨科技

浏覽次數:95

小程序canvas生成海報

  • 先看看效果圖 以(yǐ)下↓
    • 使用場景
    • 前提
    • wxml
    • js
      • drawCanvas.js
      • 在(zài)Canvas.js引入drawCanvas.js
    • 希望大(dà)家能夠用到(dào)!

如果文章中有出(chū)現纰漏、錯誤之(zhī)處,還請看到(dào)的(de)小夥伴多多指教,先行謝過

先看看效果圖 以(yǐ)下↓

在(zài)這(zhè)裏插入圖片描述

使用場景

  • 分享小程序的(de),繪制分享圖
  • 不(bù)同商品分享的(de)是(shì)後生成不(bù)同的(de)圖片,每個(gè)商品的(de)信息圖片不(bù)同,小程序默認分享的(de)是(shì)頁面默認截圖
  • 小程序分享朋友圈,生成海報

前提

  • 根據上(shàng)面圖片需要(yào / yāo)一個(gè)背景圖片(上(shàng)面是(shì)750*777),大(dà)家可根據實際情況進行改變
  • 本文用的(de)是(shì)小程序canvas最新api,大(dà)家可以(yǐ)閱讀小程序canvas文檔

wxml

<canvas style="width:750px;height:777px;position:absolute;top:0px;left:-2000px;" id="canvas" type="2d"></canvas>

js

drawCanvas.js

[單獨創建drawCanvas.js存放一些公共函數,裏面封裝了(le/liǎo)圖片渲染文字換行等一些方法(由于(yú)畫布無法直接使用網絡圖片,所以(yǐ)需要(yào / yāo) wx.downloadFile或者wx.getImageInfo把它下載回來(lái)才能使用,本文使用wx.downloadFile)]


export default {
  // 下載圖片函數
  downloadImg(img) {
    return new Promise((resolve, reject) => {
      //将網絡圖片轉成本地(dì / de)路徑     
      // wx.getImageInfo({
      //   src: img,
      //   success: function (res) {
      //     resolve(res.path)

      //   }
      // })
      //方法二
      wx.downloadFile({
        url: img,
        success: (res) => {
          let cover = res.tempFilePath;
          resolve(cover)
        },
        fail: (err) => {

          reject(err)
        },
      })
    })
  },
  //圖片渲染
  drawImage(canvas, ctx, imgUrl, x, y, w, h) {
    ctx.save();
    const img = canvas.createImage();
    img.src = imgUrl
    img.onload = () => ctx.drawImage(img, x, y, w, h);
    ctx.closePath();
  },

  //文字換行
  drawTxt: function (ctx, _str, _x, _y, _total, _lineh, _linenum) {
    if (_str == "" || _str == undefined) {
      return;
    }
    var total = _total ? _total : 15; //每行字數(數字算半個(gè))
    var lineH = _lineh ? _lineh : 20; //行間距
    var lineNum = _linenum ? _linenum : 4; //最大(dà)顯示行數

    /*
    拆解字符串到(dào)數組,按行,每行15個(gè)(判斷數字占半個(gè),其他(tā)占1個(gè))
    */
    var lineArray = [];
    var len = 0; //數字算半個(gè),中文算一個(gè)
    for (var i = 0; i < _str.length; i++) {
      var line = '';
      if (Math.ceil(len) % total == 0) {
        if (lineArray[lineArray.length - 1] != "") {
          lineArray.push("");
        }
      }
      var index = Math.floor(len / total); //
      lineArray[index] = lineArray[index] + _str[i];

      if (!isNaN(_str[i])) {
        //是(shì)數字
        len = len + 0.5;
      } else {
        len = len + 1;
      }
    }

    for (var i = 0; i < lineArray.length; i++) {
      var t_str = lineArray[i];
      if (lineArray.length > lineNum && i == (lineNum - 1)) {
        //如果總行數大(dà)于(yú)設定的(de)行數,則到(dào)最大(dà)設定行時(shí),加省略号,退出(chū)
        t_str = t_str + '...'
        ctx.fillText(t_str, _x, _y + lineH * i);
        break;
      } else {
        ctx.fillText(t_str, _x, _y + lineH * i);
      }
    }
  },

  //裁切圓角  
  drawRoundRect: function (cxt, x, y, width, height, radius) {
    cxt.save()
    cxt.beginPath();
    cxt.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
    cxt.lineTo(width - radius + x, y);
    cxt.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
    cxt.lineTo(width + x, height + y - radius);
    cxt.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
    cxt.lineTo(radius + x, height + y);
    cxt.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
    cxt.closePath();
  }
}

在(zài)Canvas.js引入drawCanvas.js

import drawCanvas from 'drawCanvas.js';
Page(Object.assign({},drawCanvas, {
 /**
   * 頁面的(de)初始數據
   */
  data: {
    canvasImg: 'https://dss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2635355882,2630309952&fm=218&app=2&f=JPEG?w=121&h=75&s=FF7204C5C0615D0773AD7CD103003098' // 實例
  },
 /**
   * 生命周期函數--監聽頁面加載
   */
 >: function (options) {
    this.shareCreate()
  },
  //分享微信朋友圈
  async shareCreate() {
    var self = this;
    //self.downloadImg是(shì)drawCanvas.js裏面方法
    let imgUrl = await self.downloadImg(self.data.canvasImg);
    wx.nextTick(() => { self.drawAll(imgUrl) })
  },
    drawAll(imgUrl) {
    const query = wx.createSelectorQuery()
    const node = query.select('#canvas').node();
    var self = this;
    node.exec(async res => {
      const canvas = res[0].node;
      //設置寬高
      canvas.width = canvas._width
      canvas.height = canvas._height
      const ctx = canvas.getContext('2d');
      //背景圖
      await self.drawImage(canvas, ctx, "/images/shareImg.png", 0, 0, 750, 777);

      //cover
      await self.drawImage(canvas, ctx, imgUrl, 0, 0, 750, 460);

      //logo
      await self.drawImage(canvas, ctx, imgUrl, 50, 525, 363, 45);


      setTimeout(async () => {
        //背景透明
        ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
        ctx.fillRect(0, 0, 750, 460);
        //繪制空心矩形
        ctx.strokeStyle = 'rgba(0, 0, 0, 0.6)';
        ctx.strokeRect(0, 0, 750, 460);
        ctx.save();
        //title
        ctx.textAlign = 'left';
        ctx.fillStyle = 'rgba(255, 255, 255, 1)';
        ctx.font = "normal bold 41px PingFangSC-Regular";
        self.drawTxt(ctx, "測試卡片", 50, 390, 30, 50, 1);

        //desc
        ctx.textAlign = 'left';
        ctx.fillStyle = "#1e1e1e";
        ctx.font = "normal normal 28px PingFangSC-Regular";
        self.drawTxt(ctx, "測試卡片測試卡片測試卡測試卡片片測試卡片測試卡片測試卡片測試卡片測試卡片測試卡片片測試卡片測試卡片", 159, 661, 18, 43, 2);
        //裁切圓角 
        self.drawRoundRect(ctx, 50, 625, 92, 92, 46);
        ctx.clip();
        ctx.stroke();
        //頭像
        await self.drawImage(canvas, ctx, imgUrl, 50, 625, 92, 92);
        ctx.restore();
        ctx.closePath();
        //canvas轉成圖片
        self.previewHB(canvas)
      }, 500)


    })
  },
   //圖片預覽
  previewHB(canvas) {
    var self = this;
    wx.nextTick(() => {
      //轉換圖片
      wx.canvasToTempFilePath({
        canvas: canvas,
        success:async (res)=> {
          let img=res.tempFilePath
          //預覽
          wx.previewImage({
            urls: [img]
          })
        }
      })
    })
  },
}})

希望大(dà)家能夠用到(dào)!

相關案例查看更多