微信小程序利用canvas生成海報分享圖片

一 . 效果

 這是借用女神照生成的分享的海報歇万,圖片來自網(wǎng)絡。

新增了poster組件和更新圖片自適應

二 . 準備

 準備兩張圖片連接,最好是自己開發(fā)賬號驗證的https圖片鏈接。

三 . 實現(xiàn)思路

其實就是canvas實現(xiàn)方式燃观,首先要就是定義一個canvas容器,把容器放在中間便瑟,圖片也要動態(tài)計算大小居中缆毁,顯示下面的文字和二維碼也是要根據(jù)容器動態(tài)去改變,這就是大概的實現(xiàn)思路到涂。

四 . 實現(xiàn)代碼

利用微信小程序canvas生成海報分享圖片脊框,這個生成圖片排版和適配不同尺寸的手機是一個難點,特別是圖片適應問題践啄,我處理的方法是動態(tài)獲取容器的寬度進行適應就是利用微信API wx.createSelectorQuery(),不知道還有沒有更好的辦法可以請教浇雹。

1.下載頭像
為了確保圖片下載完成之后,再回調其它方法執(zhí)行下一步屿讽。

  getAvaterInfo: function (cardInfo) {//cardInfo是傳入的信息參數(shù)昭灵,按實際需要。
    wx.showLoading({ title: '生成中...',mask: true,});
    var that = this;
    if (cardInfo.CardInfo.Avater) {
      wx.downloadFile({
        url: '圖片路徑',
        success: function (res) {
          wx.hideLoading();
          if (res.statusCode === 200) {
            var avaterSrc = res.tempFilePath;
            that.getQrCode(avaterSrc, cardInfo);
          }else{
            wx.showToast({
              title: '頭像下載失敺ヌ浮烂完!',
              icon:'none',
              duration: 2000,
              success:function(){
                that.getQrCode(avaterSrc = "", cardInfo);//回調另一個圖片下載
              }
            })
          }
        }
      })
    } else {
      wx.hideLoading();
      that.getQrCode(avaterSrc = "", cardInfo);//回調另一個圖片下載
    }
  },

2.下載二維碼
二維碼下載一樣的道理,就是先下載完成诵棵,再進行繪圖抠蚣。

  getQrCode: function (avaterSrc, cardInfo) {
    wx.showLoading({ title: '生成中...', mask: true, });
    var that = this;
    if (cardInfo.CardInfo.QrCode) {
      wx.downloadFile({
        url: cardInfo.CardInfo.QrCode,
        success: function (res) {
          wx.hideLoading();
          if (res.statusCode === 200) {
            var codeSrc = res.tempFilePath;
            that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的繪圖方法
          } else {
            wx.showToast({
              title: '二維碼下載失敗履澳!',
              icon: 'none',
              duration: 2000,
              success: function () {
                var codeSrc  = "";
                that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的繪圖方法
              }
            })
          }
        }
      })
    } else {
      wx.hideLoading();
     var codeSrc  = "";
      that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的繪圖方法
    }
  },

3.繪制分享海報
這里才是canvas實現(xiàn)繪制的過程

  sharePosteCanvas: function (cardInfo, avaterSrc, codeSrc) {
    wx.showLoading({
      title: '生成中...',
      mask: true,
    })
    var that = this;
    const ctx = wx.createCanvasContext('myCanvas');
    var width = "";
    wx.createSelectorQuery().select('#canvas-container').boundingClientRect(function (rect) {
      var height = rect.height;
      var right = rect.right;
      width = rect.width * 0.8;
      var left = rect.left + 5;
      ctx.setFillStyle('#fff');
      ctx.fillRect(0, 0, rect.width, height);

      //頭像
      if (avaterSrc) {
        ctx.drawImage(avaterSrc, left, 20, width, width);
        ctx.setFontSize(14);
        ctx.setFillStyle('#fff');
        ctx.setTextAlign('left');
      }

      if (cardInfo.TagList.length > 0) {
        ctx.fillText(cardInfo.TagList[0].TagName, left + 20, width - 4); //標簽
        const metrics = ctx.measureText(cardInfo.TagList[0].TagName); //測量文本信息
        ctx.stroke();
        ctx.rect(left + 10, width - 20, metrics.width + 40, 25);
        ctx.setFillStyle('rgba(255,255,255,0.4)');
        ctx.fill();
      }

      if (cardInfo.CardInfo.Name) {
        ctx.setFontSize(14);
        ctx.setFillStyle('#000');
        ctx.setTextAlign('left');
        ctx.fillText(cardInfo.CardInfo.Name, left, width + 60); //姓名
      }

      if (cardInfo.CardInfo.Position) {
        ctx.setFontSize(12);
        ctx.setFillStyle('#666');
        ctx.setTextAlign('left');
        ctx.fillText(cardInfo.CardInfo.Position, left, width + 85); //職位
      }

      if (cardInfo.CardInfo.Mobile) {
        ctx.setFontSize(12);
        ctx.setFillStyle('#666');
        ctx.setTextAlign('left');
        ctx.fillText(cardInfo.CardInfo.Mobile, left, width + 105); //電話
      }

      if (cardInfo.CardInfo.Company) {
        // 公司名稱
        const CONTENT_ROW_LENGTH = 24; // 正文 單行顯示字符長度
        let [contentLeng, contentArray, contentRows] = that.textByteLength(cardInfo.CardInfo.Company, CONTENT_ROW_LENGTH);
        ctx.setTextAlign('left');
        ctx.setFillStyle('#000');
        ctx.setFontSize(10);
        let contentHh = 22 * 1;
        for (let m = 0; m < contentArray.length; m++) {
          ctx.fillText(contentArray[m], left, width + 150 + contentHh * m);
        }
      }

      //  繪制二維碼cardInfo.CardInfo.QrCode
      if (codeSrc) {
        ctx.drawImage(codeSrc, left + 150, width + 40, width / 3, width / 3)
        ctx.setFontSize(10);
        ctx.setFillStyle('#000');
        ctx.setTextAlign('right');
        ctx.fillText("微信掃碼或長按識別", left + 235, width + 150);
      }

    }).exec()

    setTimeout(function () {
      ctx.draw();  這里有個需要注意就是嘶窄,這個方法是在繪制完成之后在調用怀跛,不然容易其它被覆蓋。
      wx.hideLoading();
    }, 1000)

  },

4.多行顯示文字
這個函數(shù)就是需要多行顯示文字的時候進行折行柄冲,就是切分為數(shù)組吻谋。

  textByteLength(text, num) { // text為傳入的文本  num為單行顯示的字節(jié)長度
    let strLength = 0; // text byte length
    let rows = 1;
    let str = 0;
    let arr = [];
    for (let j = 0; j < text.length; j++) {
      if (text.charCodeAt(j) > 255) {
        strLength += 2;
        if (strLength > rows * num) {
          strLength++;
          arr.push(text.slice(str, j));
          str = j;
          rows++;
        }
      } else {
        strLength++;
        if (strLength > rows * num) {
          arr.push(text.slice(str, j));
          str = j;
          rows++;
        }
      }
    }
    arr.push(text.slice(str, text.length));
    return [strLength, arr, rows] //  [處理文字的總字節(jié)長度,每行顯示內容的數(shù)組羊初,行數(shù)]
  },

5.保存繪制生成圖片
這一步就是最后把canvas生成圖片了滨溉,大功告成什湘。

  //點擊保存到相冊
  saveShareImg: function () {
    var that = this;
    wx.showLoading({
      title: '正在保存',
      mask: true,
    })
    setTimeout(function () {
      wx.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success: function (res) {
          wx.hideLoading();
          var tempFilePath = res.tempFilePath;
          wx.saveImageToPhotosAlbum({
            filePath: tempFilePath,
            success(res) {
              wx.showModal({
                content: '圖片已保存到相冊长赞,趕緊曬一下吧~',
                showCancel: false,
                confirmText: '好的',
                confirmColor: '#333',
                success: function (res) {
                  if (res.confirm) { }
                },
                fail: function (res) { }
              })
            },
            fail: function (res) {
              wx.showToast({
                title: res.errMsg,
                icon: 'none',
                duration: 2000
              })
            }
          })
        }
        });
          }, 1000);
       },

五 . 填坑

1.圖片要提前下載
這里面還有一個問題就是,圖片要提前下載完之后再繪圖闽撤,不然圖片顯示不出來得哆,可以把下載圖片的方法單獨拎出來,然后下載圖片后回調繪圖方法哟旗。

  1. ctx.draw()
    這個方法是在繪制完成之后在調用贩据,不然容易其它被覆蓋。

這樣就大功告成了闸餐,有問題可以和聯(lián)系作者饱亮,一起進步。
喜歡就點點喜歡鼓勵
DEMO路徑:https://github.com/kingbuwu/poster
demo上封裝了poster組件和顯示頭圖圖片自適應

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末舍沙,一起剝皮案震驚了整個濱河市近上,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拂铡,老刑警劉巖壹无,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異感帅,居然都是意外死亡斗锭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門失球,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岖是,“玉大人,你說我怎么就攤上這事实苞〔虺牛” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵硬梁,是天一觀的道長前硫。 經常有香客問我,道長荧止,這世上最難降的妖魔是什么屹电? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任阶剑,我火速辦了婚禮,結果婚禮上危号,老公的妹妹穿的比我還像新娘牧愁。我一直安慰自己,他們只是感情好外莲,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布猪半。 她就那樣靜靜地躺著,像睡著了一般偷线。 火紅的嫁衣襯著肌膚如雪磨确。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天声邦,我揣著相機與錄音乏奥,去河邊找鬼。 笑死亥曹,一個胖子當著我的面吹牛邓了,可吹牛的內容都是我干的。 我是一名探鬼主播媳瞪,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼骗炉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蛇受?” 一聲冷哼從身側響起句葵,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎龙巨,沒想到半個月后笼呆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡旨别,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年诗赌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秸弛。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡铭若,死狀恐怖,靈堂內的尸體忽然破棺而出递览,到底是詐尸還是另有隱情叼屠,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布绞铃,位于F島的核電站镜雨,受9級特大地震影響,放射性物質發(fā)生泄漏儿捧。R本人自食惡果不足惜荚坞,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一挑宠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颓影,春花似錦各淀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至璃俗,卻和暖如春奴璃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旧找。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工溺健, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留麦牺,地道東北人钮蛛。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像剖膳,于是被迫代替她去往敵國和親魏颓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容