• 小程序抽奖老虎.机实现原理


    运营:提个活动需求,拉新下用户嘛。
    产品:网上demo那么多随便拷拷就能用。
    开发:
    那么没做过的首先是google一下看看有没有好的demo拿来改改。
    做过的呢想想拷贝下就好了吧。

    进入正题:

    网上老.虎.机.的插件挺多的,实现原理也各不一样,
    这里先给个网上找的老.虎.机的效果demo: 点我,emmmm,基本就是这个操作了吧。

    然后这里主要提下自己当初做老.虎.机时想到的一个原理:

    划重点

    css的 background-position属性是设置背景图像的起始位置,那么我们控制背景图在0-3秒的时间内显示不同的位置,再加上过渡动画就可以达到老.虎.机旋转的效果
    第一个版本的在这里点我
    看下效果视频(第二个版本)
    这里只能上传图片 - -然后我视频转的gif有十多兆,放这里有点卡。就上传视频了。
    视频效果
    该版本定时3秒停,然后弹窗,未做到老.虎.机底部滚动停止后再显示弹窗。

    今天要说的是第三种方案(实现底部滚动停止后显示弹窗且跟后端返回的中奖码一致)


     
    image.png

     
    image.png

    先贴一段代码

    WXML
      <view class="box-container">
        <view class="box-tips">{{boxTips}}</view>
        <view class="wheel-boxs">
          <view class="box-list" wx:for="{{boxStatus}}" wx:key="index">
            <view class="box-text" wx:if="{{!isStart}}">{{item}}</view>
            <view class="box-image" style="background: url('https://qiniu-image.qtshe.com/20181113wheels.png'); background-position-y: {{isStart ? ((16 - item) * 100) + 1500 + 'rpx' : 0}}; background-size: 100% 100%; transition-property: {{isStart ? 'all' : 'none'}}; transition-delay: {{(index + 1) * 100 + 'ms'}}; transition-duration: 3.5s;">
            </view>
            {{item}}
          </view>
        </view>
        <view class="start-box">
         <form bindsubmit="startDraw" report-submit="true" wx:if="{{pageVo.remainCount !== 0}}">
             <button class="start-draw" formType="submit" />
         </form>
        </view>
        <view class="last-tips">当前剩余 <text>{{pageVo.remainCount || 0}}</text> 次攒码机会</view>
      </view>
    
    WXSS
    .box-container {
       680rpx;
      height: 380rpx;
      background: url(https://qiniu-image.qtshe.com/20190227goddess_02.png) no-repeat center center;
      background-size: 100% 100%;
      position: relative;
      z-index: 10;
      margin: auto;
      overflow: hidden;
    }
    
    .wheel-boxs {
       680rpx;
      padding: 0 80rpx;
      margin-top: 16rpx;
    }
    
    .box-list {
       90rpx;
      height: 100rpx;
      background: url(https://qiniu-image.qtshe.com/20190227goddess_11.png) no-repeat center center;
      background-size: 100% 100%;
      display: inline-block;
      margin-right: 16rpx;
      overflow: hidden;
    }
    
    .box-list:last-child {
      margin-right: 0;
    }
    
    .box-tips {
       500rpx;
      height: 54rpx;
      background: url(https://qiniu-image.qtshe.com/20190227goddess_10.png) no-repeat center center;
      overflow: hidden;
      background-size: 100% 100%;
      margin: 20rpx auto;
      color: #000;
      font-size: 24rpx;
      text-align: center;
      line-height: 54rpx;
      margin-top: 36rpx;
    }
    
    .box-text {
       100%;
      height: 100rpx;
      line-height: 100rpx;
      text-align: center;
      font-size: 44rpx;
      color: #f8294a;
      font-weight: 600;
    }
    
    .box-image {
      height: 1500%;
    }
    
    .start-box {
       100%;
      text-align: center;
      margin: 16rpx 0 8rpx;
    }
    
    .start-box button {
       290rpx;
      height: 76rpx;
      background: url(https://qiniu-image.qtshe.com/20190227startDraw.png) no-repeat center center;
      background-size: 290rpx 76rpx;
      margin: 0 auto;
    }
    
    .start-box .start-draw {
       290rpx;
      height: 76rpx;
      background: url(https://qiniu-image.qtshe.com/20190227startDraw.png) no-repeat center center;
      background-size: 290rpx 76rpx;
      margin: 0 auto;
    }
    
    JS
    const app = getApp()
    Page({
      data: {
        isStart: false, //是否开始抽奖
        isDialog: false, //是否显示中奖弹窗
        dialogId: 1, //显示第几个中奖弹窗
        boxTips: '本场女神码将在3月8日 19:00截止领取', //页面中部文案显示
        typeTips: '3月8日20点开奖哦!',
        boxStatus: ['码', '上', '有', '红', '包'], //五个抽奖默认文案
        results: [], //抽中的码
      },
      onLoad() {
          this.initData()
      },
      //显隐藏中奖弹窗或规则弹窗等
      handleModel() {
        this.setData({
          isDialog: !this.data.isDialog
        })
      },
      onShow() {},
      //初始化页面数据
      initData() {
        let postData = {
          url: 'xxx'
        }
        app.ajax(postData).then((res) => {
          if (res.success) {
            this.setData({
              pageVo: res.data,
            })
          } else {
            util.toast( res.msg || '团团开小差啦,请稍后再试')
          }
        }, () => {
          wx.hideLoading()
          util.toast( '团团开小差啦,请稍后再试')
        })
      },
      //收集FormId 发模版消息用
      addFormId(e) {
        if (e.detail.formId !== 'the formId is a mock one') { //开发者工具上显示这段文案,过滤掉
          let formData = {
            url: 'xxx',
            data: {
              formId: e.detail.formId,
              openId: wx.getStorageSync('openId') || ''
            }
          }
          app.ajax(formData)
        }
      },
      //开始抽奖
      startDraw(e) {
      //这里可以做下节流
        this.addFormId(e)  //收集formId
        let postData = {
          url: 'xxx'
        }
        app.ajax(postData).then((res) => {
          if (res.success) {
            this.setData({
              isStart: true,
              results: res.data.result.split(','), //假如后端返回[1,2,3,4,5]
              dialogId: res.data.special ? 3 : 2  //3为彩蛋状态,2为普通状态
            })
          } else {
            util.toast(res.msg || '团团开小差啦,请稍后再试')
          }
        }, () => {
          wx.hideLoading()
          util.toast( '团团开小差啦,请稍后再试')
        })
      },
     
      onShareAppMessage() {
        return {
          title: '码上有红包!点我瓜分10万女神节礼金!',
          path: '/activity/xxx/xxx',
          imageUrl: 'https://qiniu-image.qtshe.com/20190227goddess-share.png'
        }
      }
    })
    

    最后完整的实现效果在这里:
    点我查看完整的视频效果

    注意两个点:

    • 旋转的背景图是雪碧图。我这里用到的是这张(https://qiniu-image.qtshe.com/20181113wheels.png)可供参考
    • 控制好图的位移单位,需要计算下,这样才可以让后端返回的值与你的图想匹配。我这里是15个icon所以计算方式如下
    <view class="box-image" style="
         background: url('https://qiniu-image.qtshe.com/20181113wheels.png'); 
         background-position-y: {{isStart ? ((16 - item) * 100) + 1500 + 'rpx' : 0}}; 
         background-size: 100% 100%; 
         transition-property: {{isStart ? 'all' : 'none'}}; 
         transition-delay: {{(index + 1) * 100 + 'ms'}}; 
         transition-duration: 3.5s;">
    </view>
    

    这里可以封装成自定义组件,传入图片以及数量即可。后面如果有再用到 我会封装下再发出来。

    最后说下弹窗显示的图的匹配方法,根据图片大小计算,比较麻烦:
    wxml

    <view class="ci-wrapper">
      <view wx:if="{{icontype ==='nomal'}}" class="icon-default  icon-nomal" style=" background-position-y: {{(-24 -  117.86 * (typeId - 1)) + 'rpx'}};"></view>
      <view wx:else class="icon-default  icon-fade" style=" background-position-y: {{(-20 - 110.73 * (typeId - 1)) + 'rpx'}}; "></view>
    </view>
    

    wxss

    .ci-wrapper {
    }
    .icon-default {
       70rpx;
      height: 70rpx;
      background-repeat: no-repeat;
     
    }
    .icon-nomal {
      background-image: url(https://qiniu-image.qtshe.com/20181113wheels.png);
      background-position-x: -17rpx;
       background-size: 100rpx 1768rpx
    }
    .icon-fade {
      background-image: url(https://qiniu-image.qtshe.com/20181113wheels_fade.png);
      background-size: 110rpx 1661rpx;
      background-position-x: -18rpx;
    }
    
    

    Js

    Component({
      properties: {
        icontype: {
          type: String,
          value: "nomal"
        },
        iconid: {
          type: Number,
          value: 1,
          observer(newVal, oldVal) {
            this.setData({ typeId: newVal });
          }
        }
      },
      data: {
        nomalOrigin: {
          x: -17,
          y: -24
        },
        fadeOrigin: {
          x: -17,
          y: -24
        },
        typeId: 1
      }
    })
    

    以上就是一个完整小程序的tigerDraw实现方案,有什么优化点大家可以指出来,后续会整理一下出个文件拷贝就可使用。

    这里写了个代码片段 可以直接导入使用

    https://developers.weixin.qq.com/s/1k5eSnmh7z72

    青团社招聘:
    招聘岗位:资深前端开发工程师

    简历投递到:hr@qtshe.com || haochen@qtshe.com

    职位描述:

    1、建设工具、提炼组件、抽象框架,促进前端工程化、服务化,持续提升研发效率,保障线上产品质量

    2、构建H5/PC应用基础设施,主导建设前端各种发布/监控等平台,指导落实解决方案

    3、持续优化前端页面性能,维护前端代码规范,钻研各种前沿技术和创新交互,增强用户体验、开拓前端能力边界

     
  • 相关阅读:
    Web安全实践
    认证授权的设计与实现
    Elasticsearch 分页查询
    【算法】三色旗
    【转】互联网项目中mysql应该选什么事务隔离级别
    Elasticsearch 聚合
    Elasticsearch 结构化搜索、keyword、Term查询
    Elasticsearch 单字符串多字段查询
    Elasticsearch 复合查询——多字符串多字段查询
    JavaScript 原型与原型链
  • 原文地址:https://www.cnblogs.com/Mcy1358781719/p/10653224.html
Copyright © 2020-2023  润新知