成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

小程序如何生成海報(bào)分享朋友圈

lemon / 3095人閱讀

摘要:項(xiàng)目需求寫完有一段時(shí)間了,但是還是想回過來總結(jié)一下,一是對(duì)項(xiàng)目的回顧優(yōu)化等,二是對(duì)坑的地方做個(gè)記錄,避免以后遇到類似的問題。需求利用微信強(qiáng)大的社交能力通過小程序達(dá)到裂變的目的,拉取新用戶。

摘要: 小程序開發(fā)必備技能啊...

原文:小程序如何生成海報(bào)分享朋友圈

作者:小白

Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。

項(xiàng)目需求寫完有一段時(shí)間了,但是還是想回過來總結(jié)一下,一是對(duì)項(xiàng)目的回顧優(yōu)化等,二是對(duì)坑的地方做個(gè)記錄,避免以后遇到類似的問題。

需求

利用微信強(qiáng)大的社交能力通過小程序達(dá)到裂變的目的,拉取新用戶。

生成的海報(bào)如下:

需求分析

1、利用小程序官方提供的api可以直接分享轉(zhuǎn)發(fā)到微信群打開小程序 2、利用小程序生成海報(bào)保存圖片到相冊(cè)分享到朋友圈,用戶長(zhǎng)按識(shí)別二維碼關(guān)注公眾號(hào)或者打開小程序來達(dá)到裂變的目的

實(shí)現(xiàn)方案

一、分析如何實(shí)現(xiàn)

相信大家應(yīng)該都會(huì)有類似的迷惑,就是如何按照產(chǎn)品設(shè)計(jì)的那樣繪制成海報(bào),其實(shí)當(dāng)時(shí)我也是不知道如何下手,認(rèn)真想了下得通過canvas繪制成圖片,這樣用戶保存這個(gè)圖片到相冊(cè),就可以分享到朋友圈了。但是要繪制的圖片上面不僅有文字還有數(shù)字、圖片、二維碼等且都是活的,這個(gè)要怎么動(dòng)態(tài)生成呢。認(rèn)真想了下,需要一點(diǎn)一點(diǎn)的將文字和數(shù)字,背景圖繪制到畫布上去,這樣通過api最終合成一個(gè)圖片導(dǎo)出到手機(jī)相冊(cè)中。

二、需要解決的問題

二維碼的動(dòng)態(tài)獲取和繪制(包括如何生成小程序二維碼、公眾號(hào)二維碼、打開網(wǎng)頁(yè)二維碼)

背景圖如何繪制,獲取圖片信息

將繪制完成的圖片保存到本地相冊(cè)

處理用戶是否取消授權(quán)保存到相冊(cè)

三、實(shí)現(xiàn)步驟

這里我具體寫下圍繞上面所提出的問題,描述大概實(shí)現(xiàn)的過程

①首先創(chuàng)建canvas畫布,我把畫布定位設(shè)成負(fù)的,是為了不讓它顯示在頁(yè)面上,是因?yàn)槲覈L試把canvas通過判斷條件動(dòng)態(tài)的顯示和隱藏,在繪制的時(shí)候會(huì)出現(xiàn)問題,所以采用了這種方法,這里還有一定要設(shè)置畫布的大小。

<canvas canvas-id="myCanvas" style="width: 690px;height:1085px;position: fixed;top: -10000px;">canvas>

②創(chuàng)建好畫布之后,先繪制背景圖,因?yàn)楸尘皥D我是放在本地,所以獲取 組件 canvas-id 屬性,通過createCanvasContext創(chuàng)建canvas的繪圖上下文 CanvasContext 對(duì)象。使用drawImage繪制圖像到畫布,第一個(gè)參數(shù)是圖片的本地地址,后面兩個(gè)參數(shù)是圖像相對(duì)畫布左上角位置的x軸和y軸,最后兩個(gè)參數(shù)是設(shè)置圖像的寬高。

const ctx = wx.createCanvasContext("myCanvas")

ctx.drawImage("/img/study/shareimg.png", 0, 0, 690, 1085)

③創(chuàng)建好背景圖后,在背景圖上繪制頭像,文字和數(shù)字。通過getImageInfo獲取頭像的信息,這里需要注意下在獲取的網(wǎng)絡(luò)圖片要先配置download域名才能生效,具體在小程序后臺(tái)設(shè)置里配置。

獲取頭像地址,首先量取頭像在畫布中的大小,和x軸Y軸的坐標(biāo),這里的result[0]是我用promise封裝返回的一個(gè)圖片地址

let headImg = new Promise(function (resolve) {
        wx.getImageInfo({
          src: `${app.globalData.baseUrl2}${that.data.currentChildren.headImg}`,
          success: function (res) {
            resolve(res.path)
          },
          fail: function (err) {
            console.log(err)
            wx.showToast({
              title: "網(wǎng)絡(luò)錯(cuò)誤請(qǐng)重試",
              icon: "loading"
            })
          }
        })
      })
      
let avatarurl_width = 60, //繪制的頭像寬度
    avatarurl_heigth = 60, //繪制的頭像高度
    avatarurl_x = 28, //繪制的頭像在畫布上的位置
    avatarurl_y = 36; //繪制的頭像在畫布上的位置
    
    ctx.save(); // 先保存狀態(tài) 已便于畫完圓再用
    ctx.beginPath(); //開始繪制
    //先畫個(gè)圓   前兩個(gè)參數(shù)確定了圓心 (x,y) 坐標(biāo)  第三個(gè)參數(shù)是圓的半徑  四參數(shù)是繪圖方向  默認(rèn)是false,即順時(shí)針
    ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
    ctx.clip(); //畫了圓 再剪切  原始畫布中剪切任意形狀和尺寸。一旦剪切了某個(gè)區(qū)域,則所有之后的繪圖都會(huì)被限制在被剪切的區(qū)域內(nèi)
    ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推進(jìn)去圖片 

這里舉個(gè)例子說下如何繪制文字,比如我要繪制如下這個(gè)“字”,需要?jiǎng)討B(tài)獲取前面字?jǐn)?shù)的總寬度,這樣才能設(shè)置“字”的x軸坐標(biāo),這里我本來是想通過measureText來測(cè)量字體的寬度,但是在iOS端第一次獲取的寬度值不對(duì),關(guān)于這個(gè)問題,我還在微信開發(fā)者社區(qū)提了bug,所以我想用另一個(gè)方法來實(shí)現(xiàn),就是先獲取正常情況下一個(gè)字的寬度值,然后乘以總字?jǐn)?shù)就獲得了總寬度,親試是可以的。

let allReading = 97 / 6 / app.globalData.ratio * wordNumber.toString().length + 325;
ctx.font = "normal normal 30px sans-serif";
ctx.setFillStyle("#ffffff")
ctx.fillText("字", allReading, 150);

④繪制公眾號(hào)二維碼,和獲取頭像是一樣的,也是先通過接口返回圖片網(wǎng)絡(luò)地址,然后再通過getImageInfo獲取公眾號(hào)二維碼圖片信息

⑤如何繪制小程序碼,具體官網(wǎng)文檔也給出生成無限小程序碼接口,通過生成的小程序可以打開任意一個(gè)小程序頁(yè)面,并且二維碼永久有效,具體調(diào)用哪個(gè)小程序二維碼接口有不同的應(yīng)用場(chǎng)景,具體可以看下官方文檔怎么說的,也就是說前端通過傳遞參數(shù)調(diào)取后端接口返回的小程序碼,然后繪制在畫布上(和上面寫的繪制頭像和公眾號(hào)二維碼一樣的)

ctx.drawImage("小程序碼的本地地址", x軸, Y軸, 寬, 高)

⑥最終繪制完把canvas畫布轉(zhuǎn)成圖片并返回圖片地址

        wx.canvasToTempFilePath({
            canvasId: "myCanvas",
            success: function (res) {
              canvasToTempFilePath = res.tempFilePath // 返回的圖片地址保存到一個(gè)全局變量里
              that.setData({
                showShareImg: true
              })
              wx.showToast({
                title: "繪制成功",
              })
            },
            fail: function () {
              wx.showToast({
                title: "繪制失敗",
              })
            },
            complete: function () {
              wx.hideLoading()
              wx.hideToast()
            }
          })

⑦保存到系統(tǒng)相冊(cè);先判斷用戶是否開啟用戶授權(quán)相冊(cè),處理不同情況下的結(jié)果。比如用戶如果按照正常邏輯授權(quán)是沒問題的,但是有的用戶如果點(diǎn)擊了取消授權(quán)該如何處理,如果不處理會(huì)出現(xiàn)一定的問題。所以當(dāng)用戶點(diǎn)擊取消授權(quán)之后,來個(gè)彈框提示,當(dāng)它再次點(diǎn)擊的時(shí)候,主動(dòng)跳到設(shè)置引導(dǎo)用戶去開啟授權(quán),從而達(dá)到保存到相冊(cè)分享朋友圈的目的。

// 獲取用戶是否開啟用戶授權(quán)相冊(cè)
    if (!openStatus) {
      wx.openSetting({
        success: (result) => {
          if (result) {
            if (result.authSetting["scope.writePhotosAlbum"] === true) {
              openStatus = true;
              wx.saveImageToPhotosAlbum({
                filePath: canvasToTempFilePath,
                success() {
                  that.setData({
                    showShareImg: false
                  })
                  wx.showToast({
                    title: "圖片保存成功,快去分享到朋友圈吧~",
                    icon: "none",
                    duration: 2000
                  })
                },
                fail() {
                  wx.showToast({
                    title: "保存失敗",
                    icon: "none"
                  })
                }
              })
            }
          }
        },
        fail: () => { },
        complete: () => { }
      });
    } else {
      wx.getSetting({
        success(res) {
          // 如果沒有則獲取授權(quán)
          if (!res.authSetting["scope.writePhotosAlbum"]) {
            wx.authorize({
              scope: "scope.writePhotosAlbum",
              success() {
                openStatus = true
                wx.saveImageToPhotosAlbum({
                  filePath: canvasToTempFilePath,
                  success() {
                    that.setData({
                      showShareImg: false
                    })
                    wx.showToast({
                      title: "圖片保存成功,快去分享到朋友圈吧~",
                      icon: "none",
                      duration: 2000
                    })
                  },
                  fail() {
                    wx.showToast({
                      title: "保存失敗",
                      icon: "none"
                    })
                  }
                })
              },
              fail() {
                // 如果用戶拒絕過或沒有授權(quán),則再次打開授權(quán)窗口
                openStatus = false
                console.log("請(qǐng)?jiān)O(shè)置允許訪問相冊(cè)")
                wx.showToast({
                  title: "請(qǐng)?jiān)O(shè)置允許訪問相冊(cè)",
                  icon: "none"
                })
              }
            })
          } else {
            // 有則直接保存
            openStatus = true
            wx.saveImageToPhotosAlbum({
              filePath: canvasToTempFilePath,
              success() {
                that.setData({
                  showShareImg: false
                })
                wx.showToast({
                  title: "圖片保存成功,快去分享到朋友圈吧~",
                  icon: "none",
                  duration: 2000
                })
              },
              fail() {
                wx.showToast({
                  title: "保存失敗",
                  icon: "none"
                })
              }
            })
          }
        },
        fail(err) {
          console.log(err)
        }
      })
    }
總結(jié)

至此所有的步驟都已實(shí)現(xiàn),在繪制的時(shí)候會(huì)遇到一些異步請(qǐng)求后臺(tái)返回的數(shù)據(jù),所以我用promise和async和await進(jìn)行了封裝,確保導(dǎo)出的圖片信息是完整的。在繪制的過程確實(shí)遇到一些坑的地方。比如初開始導(dǎo)出的圖片比例大小不對(duì),還有用measureText測(cè)量文字寬度不對(duì),多次繪制(可能受網(wǎng)絡(luò)原因)有時(shí)導(dǎo)出的圖片上的文字顏色會(huì)有誤差等。如果你也遇到一些比較坑的地方可以一起探討下做個(gè)記錄,下面附下完整的代碼

import regeneratorRuntime from "../../utils/runtime.js" // 引入模塊
const app = getApp(),
  api = require("../../service/http.js");
var ctx = null, // 創(chuàng)建canvas對(duì)象
    canvasToTempFilePath = null, // 保存最終生成的導(dǎo)出的圖片地址
    openStatus = true; // 聲明一個(gè)全局變量判斷是否授權(quán)保存到相冊(cè)

// 獲取微信公眾號(hào)二維碼
  getCode: function () {
    return new Promise(function (resolve, reject) {
      api.fetch("/wechat/open/getQRCodeNormal", "GET").then(res => {
        console.log(res, "獲取微信公眾號(hào)二維碼")
        if (res.code == 200) {
          console.log(res.content, "codeUrl")
          resolve(res.content)
        }
      }).catch(err => {
        console.log(err)
      })
    })
  },

  // 生成海報(bào)
  async createCanvasImage() {
    let that = this;
    // 點(diǎn)擊生成海報(bào)數(shù)據(jù)埋點(diǎn)
    that.setData({
      generateId: "點(diǎn)擊生成海報(bào)"
    })
    if (!ctx) {
      let codeUrl = await that.getCode()
      wx.showLoading({
        title: "繪制中..."
      })
      let code = new Promise(function (resolve) {
        wx.getImageInfo({
          src: codeUrl,
          success: function (res) {
            resolve(res.path)
          },
          fail: function (err) {
            console.log(err)
            wx.showToast({
              title: "網(wǎng)絡(luò)錯(cuò)誤請(qǐng)重試",
              icon: "loading"
            })
          }
        })
      })
      let headImg = new Promise(function (resolve) {
        wx.getImageInfo({
          src: `${app.globalData.baseUrl2}${that.data.currentChildren.headImg}`,
          success: function (res) {
            resolve(res.path)
          },
          fail: function (err) {
            console.log(err)
            wx.showToast({
              title: "網(wǎng)絡(luò)錯(cuò)誤請(qǐng)重試",
              icon: "loading"
            })
          }
        })
      })

      Promise.all([headImg, code]).then(function (result) {
        const ctx = wx.createCanvasContext("myCanvas")
        console.log(ctx, app.globalData.ratio, "ctx")
        let canvasWidthPx = 690 * app.globalData.ratio,
          canvasHeightPx = 1085 * app.globalData.ratio,
          avatarurl_width = 60, //繪制的頭像寬度
          avatarurl_heigth = 60, //繪制的頭像高度
          avatarurl_x = 28, //繪制的頭像在畫布上的位置
          avatarurl_y = 36, //繪制的頭像在畫布上的位置
          codeurl_width = 80, //繪制的二維碼寬度
          codeurl_heigth = 80, //繪制的二維碼高度
          codeurl_x = 588, //繪制的二維碼在畫布上的位置
          codeurl_y = 984, //繪制的二維碼在畫布上的位置
          wordNumber = that.data.wordNumber, // 獲取總閱讀字?jǐn)?shù)
          // nameWidth = ctx.measureText(that.data.wordNumber).width, // 獲取總閱讀字?jǐn)?shù)的寬度
          // allReading = ((nameWidth + 375) - 325) * 2 + 380;
          // allReading = nameWidth / app.globalData.ratio + 325;
          allReading = 97 / 6 / app.globalData.ratio * wordNumber.toString().length + 325;
        console.log(wordNumber, wordNumber.toString().length, allReading, "獲取總閱讀字?jǐn)?shù)的寬度")
        ctx.drawImage("/img/study/shareimg.png", 0, 0, 690, 1085)
        ctx.save(); // 先保存狀態(tài) 已便于畫完圓再用
        ctx.beginPath(); //開始繪制
        //先畫個(gè)圓   前兩個(gè)參數(shù)確定了圓心 (x,y) 坐標(biāo)  第三個(gè)參數(shù)是圓的半徑  四參數(shù)是繪圖方向  默認(rèn)是false,即順時(shí)針
        ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
        ctx.clip(); //畫了圓 再剪切  原始畫布中剪切任意形狀和尺寸。一旦剪切了某個(gè)區(qū)域,則所有之后的繪圖都會(huì)被限制在被剪切的區(qū)域內(nèi)
        ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推進(jìn)去圖片

        ctx.restore(); //恢復(fù)之前保存的繪圖上下文狀態(tài) 可以繼續(xù)繪制
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.setFontSize(28); // 文字字號(hào)
        ctx.fillText(that.data.currentChildren.name, 103, 78); // 繪制文字

        ctx.font = "normal bold 44px sans-serif";
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.fillText(wordNumber, 325, 153); // 繪制文字

        ctx.font = "normal normal 30px sans-serif";
        ctx.setFillStyle("#ffffff")
        ctx.fillText("字", allReading, 150);

        ctx.font = "normal normal 24px sans-serif";
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.fillText("打敗了全國(guó)", 26, 190); // 繪制文字

        ctx.font = "normal normal 24px sans-serif";
        ctx.setFillStyle("#faed15"); // 文字顏色
        ctx.fillText(that.data.percent, 154, 190); // 繪制孩子百分比

        ctx.font = "normal normal 24px sans-serif";
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.fillText("的小朋友", 205, 190); // 繪制孩子百分比

        ctx.font = "normal bold 32px sans-serif";
        ctx.setFillStyle("#333333"); // 文字顏色
        ctx.fillText(that.data.singIn, 50, 290); // 簽到天數(shù)

        ctx.fillText(that.data.reading, 280, 290); // 閱讀時(shí)長(zhǎng)
        ctx.fillText(that.data.reading, 508, 290); // 聽書時(shí)長(zhǎng)

        // 書籍閱讀結(jié)構(gòu)
        ctx.font = "normal normal 28px sans-serif";
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.fillText(that.data.bookInfo[0].count, 260, 510); 
        ctx.fillText(that.data.bookInfo[1].count, 420, 532); 
        ctx.fillText(that.data.bookInfo[2].count, 520, 594); 
        ctx.fillText(that.data.bookInfo[3].count, 515, 710); 
        ctx.fillText(that.data.bookInfo[4].count, 492, 828); 
        ctx.fillText(that.data.bookInfo[5].count, 348, 858); 
        ctx.fillText(that.data.bookInfo[6].count, 212, 828); 
        ctx.fillText(that.data.bookInfo[7].count, 148, 726); 
        ctx.fillText(that.data.bookInfo[8].count, 158, 600); 

        ctx.font = "normal normal 18px sans-serif";
        ctx.setFillStyle("#ffffff"); // 文字顏色
        ctx.fillText(that.data.bookInfo[0].name, 232, 530); 
        ctx.fillText(that.data.bookInfo[1].name, 394, 552); 
        ctx.fillText(that.data.bookInfo[2].name, 496, 614); 
        ctx.fillText(that.data.bookInfo[3].name, 490, 730); 
        ctx.fillText(that.data.bookInfo[4].name, 466, 850); 
        ctx.fillText(that.data.bookInfo[5].name, 323, 878); 
        ctx.fillText(that.data.bookInfo[6].name, 184, 850); 
        ctx.fillText(that.data.bookInfo[7].name, 117, 746); 
        ctx.fillText(that.data.bookInfo[8].name, 130, 621); 

        ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth); // 繪制頭像
        ctx.draw(false, function () {
          // canvas畫布轉(zhuǎn)成圖片并返回圖片地址
          wx.canvasToTempFilePath({
            canvasId: "myCanvas",
            success: function (res) {
              canvasToTempFilePath = res.tempFilePath
              that.setData({
                showShareImg: true
              })
              console.log(res.tempFilePath, "canvasToTempFilePath")
              wx.showToast({
                title: "繪制成功",
              })
            },
            fail: function () {
              wx.showToast({
                title: "繪制失敗",
              })
            },
            complete: function () {
              wx.hideLoading()
              wx.hideToast()
            }
          })
        })
      })
    }
  },

  // 保存到系統(tǒng)相冊(cè)
  saveShareImg: function () {
    let that = this;
    // 數(shù)據(jù)埋點(diǎn)點(diǎn)擊保存學(xué)情海報(bào)
    that.setData({
      saveId: "保存學(xué)情海報(bào)"
    })
    // 獲取用戶是否開啟用戶授權(quán)相冊(cè)
    if (!openStatus) {
      wx.openSetting({
        success: (result) => {
          if (result) {
            if (result.authSetting["scope.writePhotosAlbum"] === true) {
              openStatus = true;
              wx.saveImageToPhotosAlbum({
                filePath: canvasToTempFilePath,
                success() {
                  that.setData({
                    showShareImg: false
                  })
                  wx.showToast({
                    title: "圖片保存成功,快去分享到朋友圈吧~",
                    icon: "none",
                    duration: 2000
                  })
                },
                fail() {
                  wx.showToast({
                    title: "保存失敗",
                    icon: "none"
                  })
                }
              })
            }
          }
        },
        fail: () => { },
        complete: () => { }
      });
    } else {
      wx.getSetting({
        success(res) {
          // 如果沒有則獲取授權(quán)
          if (!res.authSetting["scope.writePhotosAlbum"]) {
            wx.authorize({
              scope: "scope.writePhotosAlbum",
              success() {
                openStatus = true
                wx.saveImageToPhotosAlbum({
                  filePath: canvasToTempFilePath,
                  success() {
                    that.setData({
                      showShareImg: false
                    })
                    wx.showToast({
                      title: "圖片保存成功,快去分享到朋友圈吧~",
                      icon: "none",
                      duration: 2000
                    })
                  },
                  fail() {
                    wx.showToast({
                      title: "保存失敗",
                      icon: "none"
                    })
                  }
                })
              },
              fail() {
                // 如果用戶拒絕過或沒有授權(quán),則再次打開授權(quán)窗口
                openStatus = false
                console.log("請(qǐng)?jiān)O(shè)置允許訪問相冊(cè)")
                wx.showToast({
                  title: "請(qǐng)?jiān)O(shè)置允許訪問相冊(cè)",
                  icon: "none"
                })
              }
            })
          } else {
            // 有則直接保存
            openStatus = true
            wx.saveImageToPhotosAlbum({
              filePath: canvasToTempFilePath,
              success() {
                that.setData({
                  showShareImg: false
                })
                wx.showToast({
                  title: "圖片保存成功,快去分享到朋友圈吧~",
                  icon: "none",
                  duration: 2000
                })
              },
              fail() {
                wx.showToast({
                  title: "保存失敗",
                  icon: "none"
                })
              }
            })
          }
        },
        fail(err) {
          console.log(err)
        }
      })
    }
  },

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/7286.html

相關(guān)文章

  • 程序如何生成海報(bào)分享朋友

    摘要:項(xiàng)目需求寫完有一段時(shí)間了,但是還是想回過來總結(jié)一下,一是對(duì)項(xiàng)目的回顧優(yōu)化等,二是對(duì)坑的地方做個(gè)記錄,避免以后遇到類似的問題。需求利用微信強(qiáng)大的社交能力通過小程序達(dá)到裂變的目的,拉取新用戶。 項(xiàng)目需求寫完有一段時(shí)間了,但是還是想回過來總結(jié)一下,一是對(duì)項(xiàng)目的回顧優(yōu)化等,二是對(duì)坑的地方做個(gè)記錄,避免以后遇到類似的問題。 需求 利用微信強(qiáng)大的社交能力通過小程序達(dá)到裂變的目的,拉取新用戶。生成的...

    Lemon_95 評(píng)論0 收藏0
  • Canvas繪圖在微信程序中的應(yīng)用:生成個(gè)性化海報(bào)

    摘要:解析進(jìn)到首頁(yè)其實(shí)關(guān)鍵字在本地就隨機(jī)取完了,在首頁(yè)中的方法中就通過緩存了要畫的元素,比如關(guān)鍵字這里是圖片關(guān)鍵字解析語(yǔ)也是圖片畢竟微信小程序的不支持字體等等。 一、Canvas應(yīng)用的背景(個(gè)人理解)及基礎(chǔ)語(yǔ)法 背景 從2012年開始,微信那個(gè)時(shí)候用戶的積累的量已經(jīng)非常大了,推出公眾號(hào),當(dāng)然大屏智能手機(jī)在那個(gè)時(shí)候也流行,傳統(tǒng)的大眾媒體逐步消亡,像微信公眾號(hào)這樣的新媒體盛行。企業(yè)的廣告投入開始...

    vpants 評(píng)論0 收藏0
  • Laravel 生成程序圖文海報(bào)最佳方案之一

    摘要:微信小程序官方并未提供分享到朋友圈的方法,所以目前基本整個(gè)行業(yè)都是使用生成圖文海報(bào)發(fā)到朋友圈,然后識(shí)別太陽(yáng)碼進(jìn)入到小程序。背景圖片和微信頭像合成后清晰度不夠。 微信小程序官方并未提供分享到朋友圈的方法,所以目前基本整個(gè)行業(yè)都是使用生成圖文海報(bào)發(fā)到朋友圈,然后識(shí)別太陽(yáng)碼進(jìn)入到小程序。 通過谷歌或者百度有很多同學(xué)已經(jīng)提供了一些解決方案,但是在我們使用后效果并不是很理想,主要體現(xiàn)在以下方面:...

    piglei 評(píng)論0 收藏0
  • 教你如何在低成本、有限的時(shí)間里策劃裂變100社群_怎么做微信防封群

    摘要:如何在低成本有限的時(shí)間里策劃一場(chǎng)合格的裂變活動(dòng)呢常做裂變的朋友可能回到個(gè)詞裂變系數(shù)投入與產(chǎn)出比。存在成本的裂變活動(dòng)嗎答案存在。在這條新規(guī)則宣布后,裂變分享率增加到了。優(yōu)點(diǎn)進(jìn)一步驗(yàn)證用戶的朋友圈,防止渾水摸魚。 ...

    BLUE 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<