微信小程序分享朋友圈 長海報 canvas 動態高度計算


業務場景

在微信中 小程序無法分享到朋友圈,目前大部分的解決方案都是,canvas動態繪制 生成圖片后,保存到用戶相冊,用戶進行分享照片到朋友圈,朋友圈打開圖片后識別二維碼進入小程序,達到分享目的

github源碼鏈接

https://github.com/richard1015/canvas

微信IDE代碼預覽

https://developers.weixin.qq.com/s/DBZhf8mB7qaD

海報需求設計圖分析

圖1分析: 可以看到海報 要求寬750 高1218(當然了數據是動態的,高度肯定不會固定值,需要我們動態去計算)

 

 

圖2分析:矩形框 寬高為固定值 320 背景顏色#fff 圓角10

 

 

圖3分析:矩形框 上半部分 寬320 高125 背景顏色#f7f7f7

 

 

代碼邏輯實現

1.模板邏輯 wxml添加canvas公用組件
<!--pages/index/index.wxml-->
<view class='index'>

  <!-- 公用canvas share -->
  <import src="../common/canvasShare.wxml" />
  <template data="{{shareCanvasItem}}" is="canvas-share" />

  <!-- content 內容預顯示 begin -->
  <view class='content'>
    <view class='content_header'>
      <view class='left' bindtap='toChoiceBank'>
        <text>中國銀行(測試數據)</text>
      </view>
    </view>
    <view class='content_item'>
      ...此處省略
    </view>
  </view>
  <!-- content end -->
  <import src="../common/footerShare.wxml" />
  <template is="footer-share" />
</view>
復制代碼
2.canvas公用模板設計
<template name="canvas-share">
  <!-- <view style='width:0px;height:0px;overflow:hidden;opacity: 0;'> -->
    <canvas style="height:{{shareCanvasItem.Height}}px !important;" class='shareCanvas' canvas-id="shareCanvas" binderror="canvasIdErrorCallback"></canvas>
  <!-- </view> -->
</template>
復制代碼

3.js 邏輯實現

// 調用公用組件
let {
  CanvasUtil,
  util
} = getApp();
// 測試數據引入
const testData= require('../../test.js');
Page({
  /** * 頁面的初始數據 */
  data: {
    shareCanvasItem: {
      Height: 5000
    },//初始canvas高度,設置背景黑,此高度必須大於 動態生成內容高度,否則 無法全面覆蓋背景
    items: [],
  },
  onLoad: function() {
    this.getList();
  },
  //獲取列表數據
  getList() {
    var self = this;

    // purchasePrice 匯買價
    // cashPrice 鈔買價
    // sellingPrice 匯賣價
    // banknotePrice 鈔賣價
    //賦值過濾健全item
    self.setData({
      items: testData
    });
  },

  /* 分享事件 */
  share: function() {
    console.log('分享');
    var self = this;

    let titleTemp = `今日中行外匯牌價`;

    let tips = '*以上為保存時間的牌價,成交價格以實際交易為准';
    // 獲取設備寬高
    var res = wx.getSystemInfoSync();
    var canvasWidth = res.windowWidth;
    var canvasHeight = self.data.shareCanvasItem.Height;
    // 獲取canvas的的寬 自適應寬(設備寬/750) px
    var Rpx = (canvasWidth / 750).toFixed(2);
    //上邊距
    var paddingTop = Rpx * 20;
    //左邊距
    var paddingLeft = Rpx * 20;
    //右邊距
    var paddingRight = Rpx * 20;
    //當前編寫高
    var currentLineHeight = Rpx * 33;

    var context = wx.createCanvasContext('shareCanvas');

    //全局背景顏色默認填充
    context.setFillStyle('#333333');
    context.fillRect(0, 0, canvasWidth, canvasHeight);

    //字體顏色
    context.setFillStyle('#999999');
    context.setTextAlign('center');
    context.font = `${(Rpx * 36).toFixed(0)}px PingFangSC-Regular`;
    //內容行邊距計算
    currentLineHeight += Rpx * 36;

    //標題文本 繪制
    context.fillText(titleTemp, canvasWidth / 2, currentLineHeight);
    context.setTextAlign('left');

    //內容行邊距計算
    currentLineHeight += Rpx * 34;

    //item白色背景 矩形左右邊距
    let padingLeftRightRect = Rpx * 40,
      rectRadius = Rpx * 10, //圓角10
      rectWidth = Rpx * 320, //寬
      rectHeight = Rpx * 320, //高
      topRectHeight = Rpx * 125; //美元上部分


    self.data.items.forEach((item, index) => {
      //保存上次繪制圖,進行本次操作
      // context.save();
      //每兩次進行換行邏輯
      if (index > 1 && index % 2 === 0) {
        //行高換行
        currentLineHeight += rectHeight + Rpx * 40;
        //邊距重置
        padingLeftRightRect = Rpx * 40;
      }
      //局部 y currentLineHeight
      //局部 x padingLeftRightRect

      // 偶數為 left 處理邏輯 奇數為right 處理邏輯
      //left
      if (index % 2 === 0) {

      } else {
        //right 坐標 = 加矩形寬 + 中間距30
        padingLeftRightRect += rectWidth + Rpx * 30;
      }
      //矩形顏色設置
      context.setFillStyle('#ffffff');
      //調用繪制圓角矩形
      CanvasUtil.drawRoundedRect(context, padingLeftRightRect, currentLineHeight, rectWidth, rectHeight, rectRadius, true);
      //矩形上變背景顏色生成
      context.setFillStyle('#f7f7f7');
      //調用繪制圓角矩形
      CanvasUtil.drawRoundedRect(context, padingLeftRightRect, currentLineHeight, rectWidth, topRectHeight, rectRadius, true);

      //幣種字體顏色
      context.setFillStyle('#333333');
      context.font = `${(Rpx * 34).toFixed(0)}px PingFangSC-Regular`;
      //幣種文本繪制
      context.fillText(item.chName, padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34);
      //幣種英文繪制
      context.fillText(item.abridge, padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
      //繪制幣種圖案
      context.drawImage(`/currencyImg/${item.iconName}`, padingLeftRightRect + Rpx * 226, currentLineHeight + Rpx * 35, Rpx * 64, Rpx * 64);

      //價格字體顏色
      context.setFillStyle('#666666');
      context.font = `${(Rpx * 26).toFixed(0)}px PingFangSC-Regular`;
      context.fillText('鈔買價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 70, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);

      context.fillText('匯買價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 110, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);

      context.fillText('鈔賣價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 150, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);

      context.fillText('匯賣價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 190, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
      //價格值字體顏色
      context.setFillStyle('#333333');
      //鈔買價
      context.fillText(item.cashPrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 70, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
      // 匯買價
      context.fillText(item.purchasePrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 110, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
      //鈔賣價
      context.fillText(item.banknotePrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 150, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
      //匯賣價
      context.fillText(item.sellingPrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 190, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);

      //操作完成后恢復上次值
      // context.restore();
    });
    //行高換行
    currentLineHeight += rectHeight + Rpx * 40;



    //字體顏色
    context.setFillStyle('#999999');
    context.setTextAlign('center');
    context.font = `${(Rpx * 28).toFixed(0)}px PingFangSC-Regular`;
    //領取提示文本 繪制
    context.fillText(tips, canvasWidth / 2, currentLineHeight);

    //行高換行
    currentLineHeight += Rpx * 30;

    //qrcode生成圖片
    context.drawImage('/imgs/qrcode.png', paddingLeft, currentLineHeight, canvasWidth - paddingLeft - paddingRight, Rpx * 200);

    context.setTextAlign('left');
    //字體顏色
    context.setFillStyle('#EEC62E');
    context.font = `${(Rpx * 32).toFixed(0)}px PingFangSC-Regular`;
    //領取提示文本 繪制
    context.fillText('測試canvas', paddingLeft + Rpx * 43, currentLineHeight + Rpx * 90);

    //字體顏色
    context.setFillStyle('#999999');
    context.font = `${(Rpx * 28).toFixed(0)}px PingFangSC-Regular`;
    //領取提示文本 繪制
    context.fillText('出境游、炒匯必備神器', paddingLeft + Rpx * 43, currentLineHeight + Rpx * 130);

    //內容行高控制
    currentLineHeight += Rpx * 220;


    //設置最終canvas高度
    self.setData({
      shareCanvasItem: {
        Height: currentLineHeight
      }
    });
    //繪制完成
    context.draw();
    //調用公共組件保存圖片
    util.saveImg();
  },
  /** * 生命周期函數--監聽頁面初次渲染完成 */
  onReady: function() {},

  /** * 生命周期函數--監聽頁面顯示 */
  onShow: function() {},

  /** * 生命周期函數--監聽頁面隱藏 */
  onHide: function() {},

  /** * 生命周期函數--監聽頁面卸載 */
  onUnload: function() {},

  /** * 頁面上拉觸底事件的處理函數 */
  onReachBottom: function() {},

  /** * 用戶點擊右上角分享 */
  onShareAppMessage: function(res) {}
})
復制代碼

CanvasUtil testData 數據代碼省略... 請查看頂部源碼鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM