趣味测试类微信小程序

先说说项目需求吧,

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内容还是很全的,大家可以尝试各种项目。

原文地址:https://www.cnblogs.com/xuniannian/p/10145210.html

时间: 2024-10-18 18:07:02

趣味测试类微信小程序的相关文章

全球首个实战类微信小程序开发教程

小木学堂专注于企业实战开发和经验传授,所以微信小程序诞生这么大的事怎么能不带着大家一起学习学习呢,所以小木学堂讲师连夜赶工学习并实战开发了微信小应用的第一个程序,并录制了课程现免费分享给大家.这个速度绝对是国内领先哦,来看看尝鲜开发,闲话少说,上地址.                在线免费观看地址 百度云下载:http://pan.baidu.com/s/1jIIzIKI 腾讯视频:http://v.qq.com/x/page/o03315osn5v.html csdn课程地址:http://

为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务

昨天测试开发微信小程序,才发现微信也要求用HTTPS加密数据,想来是由于之前苹果的ATS审核政策的缘故吧,微信想在苹果上开放小程序必然也只能要求开发者必须使用HTTPS了,于是在服务器上测试安装Nginx+HTTPS服务. 安装 HTTPS 最麻烦的问题应该就是获取证书了,证书感觉种类也挺复杂的,有好几种,单域.泛域.多域...还有个种标准乱七八糟的感觉,而且收费很高,还是每年买的. 现在各个云服务商也都有提供各种基础功能的免费证书,但似乎很多只对单域免费,这里的单域是指每个二级域名都算是一个域

微信小程序测试总结

概述 由于项目中,微信前端和后端对接出现错误.所以Alpha测试分为微信小程序前端,管理员web测试. 测试工具选择 微信小程序的前端使用微信小程序开发工具测试. 管理员web使用web测试. 测试工具使用 打开微信小程序,填写AppID,项目地址和项目名字开始调试. 管理员web登陆账号密码均为:admin . 测试用例文档 编号 发布者 标题 类别 信息说明 图片名称 发布时间 03 孙敏铭 自行车 找回 黄色自行车.知道的请联系我.电话:136552 自行车.jpg 2017-12-04

微信小程序最新开发资源汇总,对学习微信小程序的新手有一定帮助

微信小程序最新开发资源汇总,希望给想学习或正在学习微信小程序开发的同学们带来一定帮助,汇总的小程序资源有点繁杂,各种类型的小程序demo都有,大家可以选择自己想要的demo进行下载学习.这些微信小程序资源大多是整理自github,如果可以,希望大家能够给github上的原作者一颗star,感谢原作者的无私奉献. 这里整理的是资源的原帖子,下载链接也在帖子里,当然本人也只体验了部分demo,有兴趣的同学可以都下载试试. 下载地址: 仿微信聊天,朋友圈小程序源码wepy框架开发的小程序商城源码,功能

微信小程序商店 | 即速商店_团购类小程序

即速应用商店-分类最齐全的小程序商店,收录当前最新最热门小程序,汇集各行业小程序案例及评测,在这里可以轻松找到各种实用好玩的小程序,也可 免费发布 自己的小程序获取 巨大流量 . PS:关于微信小程序商店_即速商店?   如何免费发布微信小程序,获取流量? 微信小程序商店|即速商店_团购小程序 要求:该类目下提交的微信小程序须具备购物.团购相关属性.如小程序内发布虚假违法信息,由小程序主体承担.点击 > 即刻提交 < 本期团购小程序推荐: ? 网易一起拼lite 测评:网易一起拼小程序只做优质

微信小程序个人/企业开放服务类目一览表

之前写了个牙科小程序,结果服务类目没写对,审核没过,在网上搜了小程序官方的服务类目表,还有一些审核标准. 微信小程序个人开放服务类目表 服务类目 类目分类一 类目分类二 引导描述 出行与交通 代驾 / / 生活服务 家政.丽人.摄影/扩印.婚庆服务.环保回收/废物回收 / / 餐饮 点评与推荐.菜谱.餐厅排队 / / 旅游 出境WiFi.旅游攻略 / / 商业服务 会展服务.律师 / [律师]类目需上传<律师执业资格证>, 上传原件或复印件, 复印件务必加盖公司公章 文件格式为jpg.jpeg

微信小程序实现给循环列表点击添加类(单项和多项)

在微信小程序里面没有DOM对象, 不能操作DOM. 所有的操作通过数据来实现,下面主要实现了给循环列表点击添加类的操作 一.单项 目标需求:实现下图,给点击的view增加类,每次只能选择一个. 主要思路:给点击的view增加类,依靠点击的index对state进行赋值.如果相同时,给该view增加类. 实现代码: .wxml文件 1 <view> 2 <view class='appointent-date'> 3 <view class="appointent-d

微信小程序商店 | 即速商店_二手类小程序

即速应用商店_分类最齐全的小程序商店,收录当前最新最热门小程序,汇集各行业小程序案例及评测,在这里可以轻松找到各种实用好玩的小程序,也可免费发布 自己的小程序获取巨大流量 . PS:关于微信小程序商店_即速商店?   如何免费发布微信小程序,获取流量? 微信小程序商店|即速商店_二手小程序 要求:本次安利的可是二手类福利小程序,专业回收/出售各种闲置商品!注意,想在该类目下提交的微信小程序须具备购物.二手相关属性.如小程序内发布虚假违法信息,由小程序主体承担.点击 > 即刻提交 < 本期二手小

微信小程序商店 | 即速商店_福利类小程序

即速应用商店_分类最齐全的小程序商店,收录当前最新最热门小程序,汇集各行业小程序案例及评测,在这里可以轻松找到各种实用好玩的小程序,也可免费发布 自己的小程序获取 巨大流量 . PS:关于微信小程序商店_即速商店?   如何免费发布微信小程序,获取流量? 微信小程序商店|即速商店_福利小程序 要求:本次安利的可是一堆堆福利小程序,各大电商自有平台优惠券代金券随便领!注意,想在该类目下提交的微信小程序须具备购物.福利相关属性.如小程序内发布虚假违法信息,由小程序主体承担.点击 > 即刻提交 <