如何實現一個小程序版本的老虎機

運營:我們最近須要拉新用戶,作個簡單點的活動,就老虎機形式吧。
產品:老虎機的話比較簡單,網上demo那麼多隨便拷貝拷貝就能用啦。
開發:來來來,你來作。

進入正題:

網上老虎機的插件挺多的,實現原理也各不同, 而後這裏主要提下本身當初作老虎機抽獎活動時想到的一個原理:javascript

劃重點啦:
css的 background-position屬性是設置背景圖像的起始位置,那麼咱們控制背景圖在0-3秒的時間內顯示不一樣的位置,再加上過渡動畫就能夠達到老虎機旋轉的效果

第一個版本的在 這裏 vue的版本 看下效果視頻(第二個版本) 視頻轉的gif有十多兆,放這裏有點卡。就上傳視頻了。 視頻效果 該版本定時4秒停再彈窗,比較突兀,未作到老虎機底部滾動中止後再顯示彈窗。css

今天要說的是第三種方案(實現底部滾動中止後顯示彈窗且跟後端返回的中獎碼一致) 直接上代碼html

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 {
  width: 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 {
  width: 680rpx;
  padding: 0 80rpx;
  margin-top: 16rpx;
}    
.box-list {
  width: 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 {
  width: 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 {
  width: 100%;
  height: 100rpx;
  line-height: 100rpx;
  text-align: center;
  font-size: 44rpx;
  color: #f8294a;
  font-weight: 600;
}    
.box-image {
  height: 1500%;
}    
.start-box {
  width: 100%;
  text-align: center;
  margin: 16rpx 0 8rpx;
}    
.start-box button {
  width: 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 {
  width: 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'
    }
  }
})
複製代碼

最後完整的實現效果在這裏: 點我查看完整的視頻效果前端

注意兩個點:vue

  • 旋轉的背景圖是雪碧圖。我這裏用到的是這張圖可供參考html5

  • 控制好圖的位移單位,須要計算下,這樣纔可讓後端返回的值與你的圖相匹配。我這裏是15個icon因此計算方式以下java

    <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>
    複製代碼

這裏能夠封裝成自定義組件,傳入圖片以及數量便可。後面若是有再用到 我會封裝下再發出來。node

最後說下彈窗顯示的圖的匹配方法,根據圖片大小計算,比較麻煩:react

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
.icon-default {
   width: 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
    }
  })
複製代碼

至於引用的的地方嘛,就這樣操做(resultList爲中獎數字的數組):webpack

<code-icon wx:for="{{resultList}}" icontype="nomal" iconid="{{item}}" wx:key="{{index}}"></code-icon>
複製代碼

以上就是一個完整小程序的老虎機實現方案,有什麼優化點你們能夠指出來。

最後寫了個代碼片斷:developers.weixin.qq.com/s/1k5eSnmh7…

最後

招聘走一波:

招聘崗位:前端架構師/技術leader 職位描述:

一、建設工具、提煉組件、抽象框架,促進前端工程化、服務化,持續提高研發效率,保障線上產品質量 二、構建H5/PC應用、小程序等基礎設施,主導構建效率工具平臺,指導落實解決方案 三、持續優化前端頁面性能,維護前端代碼規範,鑽研各類前沿技術和創新交互,加強用戶體驗、開拓前端能力邊界 四、對所負責的技術項目有至少1年的清晰規劃,並設定關鍵目標節點

職位要求: 一、至少3年的一線互聯網前端開發經驗 二、在前端性能優化方面有深刻研究 三、對前端組件化、模塊化、工程化有深刻的看法和實踐 四、有node.js產品研發經驗,熟悉服務器端開發技術 五、溝通能力強,責任心強,思惟邏輯性強 六、有github項目經驗者優先,請附上github或我的博客地址

招聘崗位: 資深前端開發工程師 職位描述:

一、負責前端模塊(PC、移動、小程序)的重要方案設計與研發 二、研究和探索創新的開發思路和前端技術,優化前端框架、設計方案,提升前端的開發交付效率。 三、理解產品業務的基礎上,提高產品用戶體驗,技術驅動業務發展。 四、按期組織主題分享,活躍技術氛圍,帶動組員提高技術能力

任職資格與條件要求描述 一、對 MVC/MVMM 有必定的理解,至少熟練掌握一個或多個前端框架(React、Vue等) 二、代碼結構清晰,javascript基礎紮實,精通任意一門前端MV*框架,如Vue、React等 三、熟悉 HTTP 協議,熟悉 Web 應用的性能優化,監控,分析方法 四、溝通能力強,責任心強,思惟邏輯性強

招聘崗位: 高級前端開發工程師 職位描述:

一、根據產品需求和設計完成前端頁面代碼,實現交互效果 二、與後臺工程師協做,完成數據交互、動態信息展示 三、維護及優化網站前端頁面執行性能和加載性能,優化前端代碼規範 四、可以有效地解決實際開發問題,與後臺技術開發保持良好溝通,快速理解、消化各方需求,並落實爲具體的開發工做

職位要求:

一、熟練運用html5/css3佈局,具有必定的審美能力和觀察能力,能快速精確的還原設計稿(PS/Sketch),有移動端項目開發經驗 二、代碼結構清晰,javascript基礎紮實,熟悉掌握任意一門前端MV*框架,如vueJS、reactJS等 三、對前端組件化、模塊化、工程化有深刻的看法和實踐 四、熟悉前端構建工具基本用法(webpack、gulp、grunt) 五、熟悉CSS預處理LESS/SASS等 六、有github項目經驗者優先,請附上github或我的博客地址

相關文章
相關標籤/搜索