趣味測試類微信小程序


先說說項目需求吧,

 

 

l  點擊【再測一次】,重新開始測試流程,主持人回復第一個題目,流程同上;答完全部題目后,底部不顯示【立即開始分析】按鈕,而是直接展示結果,且上一次測試內容不清空;如退出再進來,則清空全部歷史記錄。

圖片說明:

l 圖片上面顯示微信頭像和昵稱

l 名稱:左右腦人才鑒定,下面顯示2019權威測試標記;

l 分數、簡述文案與詳述文案

l 二維碼:H5聚合頁的二維碼

l 二維碼文案為:長按識別二維碼|快來領取你的左右腦成績單

l 點擊【點擊保存結果】,將圖片保存到手機相冊,且按鈕隱藏,顯示為文字:圖片已保存到相冊,可分享至朋友圈。

l 點擊【查看大圖】,將圖片發送給朋友。

至於分數就是每一題左腦得分xx分,右腦得分XX分 ,最后左腦總分XX分,右腦總分XX分,根據分數得出左腦優勢詳述右腦分數,詳述。

拿到這個小程序的時候,我覺得沒什么內容應該能很快搞定,初始預期想的是用戶信息這一塊服務端返回字段給我即可,數據結果這一段我可以在前端自己處理。

我當時想的唯一的難點就是最后html生成圖片這部分,因為之前在移動端其實做過這個需求,使用的是html2canvas,里面的坑多兼容性不好,所以心里有陰影。

最后做了才知道困住我的不是這一步,而是在不能操作dom的情況下,如何實現無線循環的再測一次。

那就從頭梳理一下這個小程序吧:

1.用戶信息授權

這個是直接使用微信的getUserInfo

<a class="supend" wx:if="{{!hasUserInfo && canIUse && item==2}}"><button open-type="getUserInfo" bindgetuserinfo="getUserInfo" class="supend-bth"> 立即分析結果 </button></a>
<view wx:if="{{hasUserInfo}}">
  <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
  <text class="userinfo-nickname">{{userInfo.nickName}}</text>
</view>
這個微信規定必須使用button按鈕授權,
對應js
getUserInfo: function(e) {
  var _this = this;
  console.log(e)
  if (!e.detail.userInfo){
    return false;
  }
  app.globalData.userInfo = e.detail.userInfo
  console.log(e.detail.userInfo)
  _this.setData({
    userInfo: e.detail.userInfo,
    hasUserInfo: true
  })
  console.log("已有用戶信息");
  _this.resultShow();
},
if (app.globalData.userInfo) {
  this.setData({
    userInfo: app.globalData.userInfo,
    hasUserInfo: true
  })
} else if (this.data.canIUse) {
  // 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
  // 所以此處加入 callback 以防止這種情況
  app.userInfoReadyCallback = res => {
    this.setData({
    userInfo: res.userInfo,
    hasUserInfo: true
    })
  }
  console.log("支持button標簽獲取信息");
  } else {
  // 在沒有 open-type=getUserInfo 版本的兼容處理
  wx.getUserInfo({
    success: res => {
      app.globalData.userInfo = res.userInfo
      this.setData({
      userInfo: res.userInfo,
      hasUserInfo: true
    })
  },
  fail:function(){
    return false;
  }
})
  console.log("不支持button標簽的兼容寫法");
}
這樣直接可以獲取到用戶的昵稱和頭像,沒有進行服務端交互。
 
2.計算結果分數
直接將結果存成一個對象,最后找出每個答案對應的值相加,返回總結果
optRst: function (ansArr) {
var rst = {
 "0": {
    '0': [xx, xx],
    '1': [xx, xx],
    '2': [xx, xx],
    '3': [xx, xx],
    '4': [xx, xx]
  },
  "1": {
    '0': [xx, xx],
    '1': [xx, xx]
   },
  "2": {
    '0': [xx, xx],
    '1': [xx, xx]
    },
  "3": {
    '0': [xx, xx],
    '1': [xx, xx],
    '2': [xx, xx]
    },
   "4": {
    '0': [xx, xx],
    '1': [xx, xx]
    }
 };
for (var i = 0; i < ansArr.length; i++) {
  var j =ansArr[i];
  this.globalData.leftScore = this.globalData.leftScore + rst[i][j][0]
  this.globalData.rightScore = this.globalData.rightScore + rst[i][j][1]
}
}
將計算得來的總數據存放在全局data里即可
3.繪制生成圖片
想要繪制用戶的微信頭像怎么辦?
將微信的域名配置到自己公眾平台的服務器域名下(https://wx.qlogo.cn)
先將微信頭像下載下來
wx.downloadFile({
  url: _this.data.avatarUrl,
  success: function (res) {
    //console.log(res.tempFilePath);
    _this.setData({
      avatarUrl: res.tempFilePath,
    })
    //繪圖方法
    //that.drawImage();
  },
  fail: function (res) {
    //console.log("繪圖失敗")
    _this.setData({ nonet: false })
  }
})
然后獲取圖片
let promise1 = new Promise(function (resolve, reject) {
  wx.getImageInfo({
  src: '../../images/result-pic.png',
  success: function (res) {
    //console.log('背景圖獲取成功')
    resolve(res);
  }
  })
});
let promise2 = new Promise(function (resolve, reject) {
  wx.getImageInfo({
    src: app.globalData.userInfo.avatarUrl,//服務器返回的圖片地址
    success: function (res) {
      //console.log('頭像獲取成功')
      resolve(res);
     }
  })
});
獲取圖片成功后去繪制圖片
Promise.all([
  //promise1, promise2
  promise2, promise3, promise4
]).then(res => {
  //console.log("進入promise")
  const ctx = wx.createCanvasContext('shareImg')
  ctx.drawImage('../../' + res[0].path, 0, 0, 545, 771)
  ctx.drawImage('../../' + res[2].path, 14, 658, 90, 90)
  //ctx.drawImage(_this.data.avatarUrl, 0, 0, 70, 70)
  //主要就是計算好各個圖文的位置
  //繪制圓角頭像
  ctx.save(); // 先保存狀態 已便於畫完圓再用
  ctx.beginPath(); //開始繪制
  ctx.arc(272, 257, 50, 0, Math.PI * 2, false);
  ctx.clip();//畫了圓 再剪切 原始畫布中剪切任意形狀和尺寸。一旦剪切了某個區域,則所有之后的繪圖都會被限制在被剪切的區域內
  ctx.drawImage(res[1].path, 220, 208, 100, 100); // 推進去圖片
  ctx.restore(); //恢復之前保存的繪圖上下文 恢復之前保存的繪圖上下午即狀態 可以繼續繪制
  //console.log("頭像繪制成功")
  //ctx.draw();
  //繪制名字
  ctx.setTextAlign('left')
  ctx.setFillStyle('#ffffff')
  ctx.font = 'normal bold 32px sans-serif';
  ctx.fillText(app.globalData.userInfo.nickName, (540 - ctx.measureText(app.globalData.userInfo.nickName).width) / 2, 118)
  //ctx.fillText('可愛的小公舉', (540 - ctx.measureText('可愛的小工具').width) / 2, 118)
  var chr = _this.data.leftDesc.split("");//將一個字符串分割成字符串數組
  var temp = "";
  var row = [];
  ctx.setFillStyle('#211f18')
  ctx.setTextAlign('left')
  ctx.font = 'normal normal 20px sans-serif';
  for (var a = 0; a < chr.length; a++) {
    if (ctx.measureText(temp).width < 220) {
      temp += chr[a];
    }
    else {
      a--; //這里添加了a-- 是為了防止字符丟失,效果圖中有對比
      row.push(temp);
      temp = "";
    }
  }
  row.push(temp);
  ctx.draw(true,setTimeout(() => {//在draw回調里調用該方法才能保證圖片導出成功。
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 'xxx',
      height: 'xxx',
      destWidth: 'xxx',
      destHeight: 'xxx',
      canvasId: 'shareImg',
      success: function (res) {
        _this.setData({
          prurl: res.tempFilePath,
          hidden: false
      })
      wx.hideLoading()
     },
    fail: function (res) {
      //console.log("最后繪制失敗");
    }
   })
  }, 200))
})
4.保存圖片到相冊(獲取用戶保存到相冊授權)
wx.getSetting({
  success(res) {
    if (!res.authSetting['scope.writePhotosAlbum']) {
      wx.authorize({
        scope: 'scope.writePhotosAlbum',
        success() {
          //console.log('用戶已經同意小程序使用保存到相冊功能')
          // 用戶已經同意小程序使用保存到相冊功能,后續調用 wx.startRecord 接口不會彈窗詢問
          //wx.startWritePhotosAlbum()
        },
        fail(){
         //console.log('用戶不同意小程序使用保存到相冊功能')
          wx.showModal({
            title: '警告',
            content: '你點擊了拒絕授權將無法保存圖片,點擊確定重新獲取授權。',
            showCancel: false,
            confirmText: '返回授權',
            success: function (res) {
              if (res.confirm) {
                wx.openSetting({
                  success: (res) => {
                    if (res.authSetting["scope.writePhotosAlbum"]) {
                      wx.authorize({
                          scope: 'scope.writePhotosAlbum',
                          success() {
                            //console.log('用戶已經同意小程序使用保存到相冊功能')
                            // 用戶已經同意小程序使用保存到相冊功能,后續調用 wx.startRecord 接口不會彈窗詢問
                            //wx.startWritePhotosAlbum()
                         },
                       })
                       }
                     }
                  })
                }
                 }
             })
           }
          })
      }else{
        //console.log('用戶之前同意過小程序使用保存到相冊功能')
         wx.saveImageToPhotosAlbum({
           filePath: that.data.prurl,
           success(res) {
              wx.showToast({
                 title: '已保存到相冊',
                 icon: '',
                 duration: 1000,
                 mask: true
                })
             }
         })
       }
    }
})
5.長按分享圖片
sharepic:function(e){
  var current = e.target.dataset.src;
  wx.previewImage({
    current: current,
    urls: [current]
  })
}
6.//獲取頁面的高度,從而實現滾動
pageScrollToBottom: function () {
  var _this = this;
  wx.createSelectorQuery().select('#wrap').boundingClientRect(function (rect) {
  // 使頁面滾動到底部
    _this.setData({
      scrollTop: rect.height
    })
  }).exec()
},
剛開始我是直接在里面設置wx.pageScrollTo來實現,每次將頁面滑到最底部,后來發現這種情況頁面抖動十分厲害,故只用上述方法獲取高度,
然后使用

<scroll-view scroll-y class="container" enable-back-to-top="true" style="height: {{windowHeight}}rpx;" bindscroll="touchclose" scroll-with-animation="true" scroll-top="{{scrollTop}}">
<!-- 內容 -->
<view>-----略------</view>
</scroll-view>

設置scrollTop的值即可
7.最后說說基於存在再測一次頁面實現的整體結構
因為頁面可以無限次循環,每次又是從第一次循環,所以這邊根據數據渲染得出,
當第一題有答案時顯示第二題,當第二題顯示時出現第三題,依次執行,五題執行完又可以實現再測一次從第一次實現
我想到了用wx:for,用wx:for一下循環五項,判斷是否展示的條件不變,用二維數組保存,剛開始測試的第一組存放在arr[0]一維數組索引為0的
第一個二維數組里,每點擊再測一次,數組的length加一,添加到下一個arr[1]數組里,這樣即可實現無限循環。
如果有用到上述api出現問題的,可以共同探討下原因,最后說一下,小程序官方api內容還是很全的,大家可以嘗試各種項目。
 
 


免責聲明!

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



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